《Head First 设计模式》之装饰者模式——饮料加工

装饰者模式(Decorator)

  ——动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

  • 特点:建立拥有共同超类的装饰者与被装饰者来实现功能的动态扩展
  • 原则:对扩展开放,对修改关闭。(开放-关闭原则)
  • 示例:(装饰饮料类图)包括 抽象组件(Beverage),具体组件(HouseBlend),抽象装饰者(CondimentDecorator)和具体装饰者(Mocha)

Beverage.java

 1 public abstract class Beverage {
 2     String description = "Unknown Beverage";//定义饮料相关描述信息
 3     float cost;//定义饮料的价格
 4      
 5     public abstract double getCost();//定义cost方法返回该饮料的价格,子类必须实现此方法
 6      
 7     public String getDescription(){
 8         return description;
 9     }
10 }

CondimentDecorator.java

1 public abstract class CondimentDecorator extends Beverage{
2     public abstract String getDescription();
3 }

HouseBlend.java

1 public class HouseBlend extends Beverage{
2     public HouseBlend(){
3         description = "House Blend Coffee";
4     }
5     public double cost(){
6         return 1.99;
7     }
8 }

Mocha.java

 1 public class Mocha extends CondimentDecorator{
 2     Beverage beverage;//被装饰者
 3     public Mocha(Beverage beverage)
 4     {
 5         this.beverage = beverage;
 6     }
 7     public String getDescription(){
 8         return beverage.getDescription()+", Mocha";//利用委托(delegate),得到一个description。
 9     }
10     public double cost(){
11         return .20 + beverage.cost();
12     }
13 }

Test.java

 1 public class Test{
 2     public static void main(String args[]){
 3         Beverage beverage = new HouseBlend();//调料为豆浆、双摩卡、奶泡的HouseBlend咖啡
 4         beverage = new Soy(beverage);
 5         beverage = new Mocha(beverage);
 6         beverage = new Mocha(beverage);
 7         beverage = new Whip(beverage);
 8         System.out.println(beverage.getDescription() + " $" + beverage.cost());
 9     }
10 }

 

notice:

  1. 装饰者和被装饰者必须是一样的类型,也就是有共同的超类,用继承达到“类型匹配”。
  2. 通常装饰者模式是采用抽象类,但在Java中可以使用接口。
  3. 可以用无数个装饰者包装一个组件。

缺点:

装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。


 

附:装饰 java.io 类

 

InputStream in = new BufferedInputStream(new FileInputStream("test.txt"));

 

posted @ 2017-02-23 21:10  D-Dong  阅读(306)  评论(0编辑  收藏  举报