装饰模式

参考http://www.cnblogs.com/xinye/p/3910149.html

http://www.2cto.com/kf/201512/455764.html

 

假如有个食物类,不同的做法蒸炒煎炸要生成不同的基类。就是四个子类:蒸食物、炒食物,煎食物,炸食物。如果还要有两种做法的子类呢,还要写蒸炒食物,蒸煎食物……三种做法的更夸张,子类多到爆炸。并且为了应对不同情况,要把所有可能用到的子类都提前写出来,而不是到使用时再随时写。

处理办法:

食物类增加四个属性来标记做法:是否蒸,是否炒,是否煎,是否炸……

那要是有蒸两遍的呢?看来这个属性不能用bool类型,还要用int类型。

当然这样做,对应不同的做法组合,处理方法里要写很多if判断上述的四个属性组合,去做对应的逻辑。食物类也因此变得庞大,逻辑超多。如果需要40个属性,甚至400个属性呢……这种直接在基类中处理所有逻辑也违反了开放封闭原则,即基类是可扩展的,但不能修改。可以预见到,随着食物的做法增多,必然要不停地修改基类,以及基类的if判断。

 

有没有办法做到,生成一个食物的子类,即满足子类要求,又可以处理不同的做法呢。答案就是组合,即设计模式中的装饰模式。

 

1.abstract class Food食物类

   function todo()

2.Chicken extends Food鸡肉类

3.Duck extends Food鸭肉类

 

4.FoodDecoration extends Food

 

5.SteameFood extends FoodDecoration//子类蒸食物,仍然是Food的子类

   private Food food;//使用构造方法传入的变量进行组合

   public SteameFood(Food f){

      this.food = f;

   }

   override function todo(){

      //food.todo()

      //蒸

   }

6.RoastFood extends FoodDecoration//子类烤食物,仍然是Food的子类

   private Food food;//使用构造方法传入的变量进行组合

   public RoastFood(Food f){

      this.food = f;

   }

   override function todo(){

      //food.todo()

      //烤

   }

 

运行时就可以自由组合了:

 

// 测试单纯的食物

Food f1 = new Chicken();

System.out.println(f1.getDesc());

System.out.println("----------------------");

 

// 测试单重修饰的食物

RoastFood rf = new RoastFood(f1);

System.out.println(rf.getDesc());

System.out.println("----------------------");

 

// 测试多重修饰的食物

SteamedFood sf = new SteamedFood(rf);

System.out.println(sf.getDesc());

 

执行结果:

鸡肉

----------------------

烤鸡肉

----------------------

蒸烤鸡肉

 

可以看出,N种做法只要N个子类。使用的时候多重装饰即可,自己安排好装饰顺序。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值