装饰者模式
(装饰模式)
定义==装饰模式==动态地将责任附加到对象上。为了扩展功能,装饰提供了比继承更灵活的替代方案。
主要角色- 抽象组件(Component):定义一个对象的界面可以动态地增加这些对象的责任。
- 具体组件(ConcreteComponent):抽象组件的接口代表装饰的原始对象。
- 抽象装饰者(Decorator):继承或实现抽象组件,持有抽象组件引用,可调用装饰对象的方法,并在其前后增加新的功能。
- 具体装饰者(ConcreteDecorator):实现抽象装饰者的方法,增加装饰对象的具体职责。
- 继承是扩展形式之一,但不一定是实现弹性设计的最佳方式
- 在我们的设计中,不需要修改现有代码,就应该允许行为扩展
- 组合和委托可以在运行过程中动态添加新的行为
- 除了继承,装饰模式还可以扩大我们的行为
- 装饰模式意味着一群用于包装特定组件的装饰者
- 装饰者反映了装饰部件的类型(事实上,它们有相同的类型,通过接口或继承实现)
- ==装饰者可以在被装饰者的行为之前和/或之后添加自己的行为,甚至取代被装饰者的整个行为,达到特定的目的==
- 你可以用无数的装饰者包装一个组件
- 除非客户程序依赖于组件的具体类型,否则装饰者通常对组件的客户是透明的
- 装饰会导致设计中的许多小物体,如果过度使用,会使程序变得非常复杂
- 定义抽象组件表示饮料
public abstract class Beverage { public String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract double cost();}
- 定义抽象组件表示调味品
public abstract class CondimentDecorator extends Beverage { public abstract String getDescription();}
- 定义一个特定的组件表示浓缩咖啡
public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } @Override public double cost() { return 1.99; }}
- 定义一个特定的组件表示摩卡
public class Mocha extends CondimentDecorator { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } @Override public double cost() { return .20 + beverage.cost(); } @Override public String getDescription() { return beverage.getDescription() + ", Mocha"; }}
- 测试代码
public class StarbuzzCoffee { public static void main(String[] args) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); Beverage beverage1 = new HouseBlend(); beverage1 = new Mocha(beverage1); beverage1 = new Mocha(beverage1); System.out.println(beverage1.getDescription() + " $" + beverage1.cost()); }}
- 输出结果
Espresso $1.99House Blend Coffee, Mocha, Mocha $1.29
Java可以利用抽象和接口来实现装饰模式,并通过继承和组合为对象增加新的功能。
