装饰者模式(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:
- 装饰者和被装饰者必须是一样的类型,也就是有共同的超类,用继承达到“类型匹配”。
- 通常装饰者模式是采用抽象类,但在Java中可以使用接口。
- 可以用无数个装饰者包装一个组件。
缺点:
装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。
附:装饰 java.io 类
InputStream in = new BufferedInputStream(new FileInputStream("test.txt"));