装饰者模式
装饰者模式:动态将责任添加到对象上。如果需要扩展功能,装饰者提供了比继承更有弹性的解决方案。装饰者模式类图如下:
装饰者模式类图(来源Head First).png
举个栗子:
情景如下:去饭店点菜的例子,饭店(Component),中国饭店(ConcreteComponent),菜品(Decorate),鱼(FishDecorate装饰者),牛排(SteakDecorate装饰者)
- 被装饰者
1,创建基类
/**
* 饭店
* @author cuishuxiang
*/
public abstract class Restaurant {
//点菜
String orderFood="Order Nothing";
public String getOrderFoods() {
return orderFood;
}
//根据点的菜,计算价格
abstract int cost();
}
2,创建饭店的具体实现类
/**
* 中国餐馆
* @author cuishuxiang
*/
public class ChinaRestaurant extends Restaurant{
public ChinaRestaurant() {
// TODO Auto-generated constructor stub
}
@Override
public String getOrderFoods() {
// TODO Auto-generated method stub
return super.getOrderFoods();
}
@Override
int cost() {
// 此时没点菜,价格为 0
return 0;
}
}
- 装饰者(继承基类拥有同一个父类
Restaurant
)
1,创建装饰者基类
/**
* 抽象装饰者
* @author cuishuxiang
*
*/
public abstract class Decorate extends Restaurant{
public abstract String getOrderFoods();//点了什么菜
}
2,鱼(具体的装饰者)
/**
* 点了鱼
* @author cuishuxiang
*
*/
public class FishDecorate extends Decorate{
private Restaurant restaurant;
public FishDecorate(Restaurant restaurant) {
// 这里持有 Restaurant 的引用
this.restaurant=restaurant;
}
@Override
int cost() {
// 此时应先计算上个的价格 再加上 鱼的价格
return restaurant.cost()+10;
}
@Override
public String getOrderFoods() {
// TODO Auto-generated method stub
return " 点了China饭店的 鱼!";
}
}
3,牛排(具体的装饰者)
/**
* 牛排
*
* @author cuishuxiang
*
*/
public class SteakDecorate extends Restaurant{
Restaurant restaurant;
public SteakDecorate(Restaurant restaurant) {
this.restaurant=restaurant;
}
@Override
public String getOrderFoods() {
return restaurant.getOrderFoods()+",点了饭店的牛排。";
}
@Override
int cost() {
return restaurant.cost()+20;
}
}
- 测试
/**
* 测试类
* @author cuishuxiang
*/
public class RestaurantTest {
public static void main(String[] args) {
Restaurant restaurant=new ChinaRestaurant();
//装饰者,点了鱼(将引用传入)
restaurant=new FishDecorate(restaurant);
//装饰者,点了牛排
restaurant=new SteakDecorate(restaurant);
System.out.println("点的菜:"+restaurant.getOrderFoods());
System.out.println("总价为: "+restaurant.cost());
}
}
结果为:
装饰者测试结果.png 调用逻辑如上图.png
总结
- 装饰者模式特点
1,装饰者与被装饰者拥有相同的父类(如上例中的Restaurant
)。
2,装饰者中都持有一个被装饰者的引用(如上例中构造器需要传入一个Restaurant
引用)。
3,装饰者执行完自己的逻辑之后,会将最终的结果传递给被装饰者(在装饰者类当中调用被装饰者类的方法,封装成新的功能方法。)。
4,扩展性比较好,灵活性高。但是响应的会出现比较多的类。
5,java中最常见的就是I/O,使用的就是装饰者模式。
网友评论