目录
动机(Motivation)
*在某些情况下我们可能会“过度使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使这种扩展方式缺乏灵活性;并且随着子类的过度增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多的子类膨胀。
*如何使“对象功能的扩展“能够根据需要动态地实现?同时避免”扩展功能的增多“带来的子类膨胀问题?从而使得任何”功能扩展变化“所导致的影响降为最低?
模式定义
动态地给一个对象增加一些额外的职责。就增加的功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)。
实例
以饮品的形式描述Decorator模式,饮品是最基础的类,饮品可以有coffee,milk,tea等等,饮品中又可以添加sugar,jumby bean等等。
Drink类(最基础抽象的类Component)
package com.decorator;
public abstract class Drink {
public abstract void getDrink();
}
Coffee类(最基础的实现类1)
package com.decorator;
public class Coffee extends Drink{
@Override
public void getDrink() {
System.out.println("Give you a cup of coffee.");
}
}
Milk(最基础的实现类2)
package com.decorator;
public class Milk extends Drink {
@Override
public void getDrink() {
System.out.println("Give you a cup of milk.");
}
}
Decorator类(装饰类)
package com.decorator;
public abstract class DecoratorDrink extends Drink{
protected Drink drink;
}
CombinationA(Decorator类的实现类1------加糖)
package com.decorator;
public class CombinationA extends DecoratorDrink{
public CombinationA() {
}
public CombinationA(Drink drink) {
this.drink = drink;
}
public void getDrink() {
this.drink.getDrink();
System.out.println("Add suger.");
}
}
CombinationB(Decorator类的实现类2-------加红豆)
package com.decorator;
public class CombinationB extends DecoratorDrink{
public CombinationB() {
}
public CombinationB(Drink drink) {
this.drink = drink;
}
@Override
public void getDrink() {
this.drink.getDrink();
System.out.println("Add jumby bean.");
}
}
GetADrink(最终测试类)
package com.decorator;
public class GetADrink{
public static void main(String args[]) {
Coffee coffee = new Coffee();
CombinationA addsuger = new CombinationA(coffee);
CombinationB addjumbybean = new CombinationB(addsuger);
addjumbybean.getDrink();
Milk teamilk = new Milk();
CombinationA milksuger = new CombinationA(teamilk);
Drink drink = new CombinationB(milksuger);
drink.getDrink();
}
}
测试结果:
Give you a cup of coffee.
Add suger.
Add jumby bean.
Give you a cup of milk.
Add suger.
Add jumby bean.
Decorator模式的结构
要点总结
通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了使用继承带来的”灵活性差“和”多子类的衍生“。
Decorator类在接口上表现了is - a Component的继承关系,即Decorator类继承了Component类所具有的接口,但在实现上又表现为has - a Component的组合关系,即Decorator类又使用了另外一个Component类。
Decorator模式的目的并非解决”多子类衍生的多继承问题“,而是主要应用于解决”主体类在多个方向的扩展功能“——即”装饰“。