定义:动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
类型:对象结构型模式
别名:包装模式(Wrapper)
类图:
Decorator装饰模式是一种结构型模式,它主要是解决:“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。继承为类型引入的静态特质的意思是说以继承的方式使某一类型要获得功能是在编译时。所谓静态,是指在编译时;动态,是指在运行时。
装饰设计模式的结构
协作关系:Decorator把来自客户端的请求发送给所装饰的ConcreteComponent,在发送请求的前后执行一些附加的动作。
实现代码
用Decorator模式实现一下对某个手机的GSP和蓝牙功能扩展
首先,定义一个手机的接口或者是抽象类,这里就用抽象类来实现,代码如下:
//抽象接口 --> Component abstract class AbstractCellPhone{ public abstract String callNumber(); public abstract String sendMessage(); }
然后,再来实现Android和IPhone的手机类,这类要继承CellPhone,也就是图中ConcreteComponent类要继承Component,实现代码如下:
// Android厂商的手机 -->ConcreteComponent class AndroidCellPhone extends AbstractCellPhone{ @Override public String callNumber() { return "callNumber from Android terminal"; } @Override public String sendMessage() { return "sendMessage from Android terminal"; } } class IPhoneCellPhone extends AbstractCellPhone{ @Override public String callNumber() { return "callNumber from IPhone terminal"; } @Override public String sendMessage() { return "sendMessage from IPhone terminal"; } }
//抽象接口 --> Decorator abstract class Decorator extends AbstractCellPhone{ protected AbstractCellPhone mCellPhone; public Decorator(AbstractCellPhone mCellPhone) { this.mCellPhone = mCellPhone; } @Override public String callNumber() { return mCellPhone.callNumber(); } @Override public String sendMessage() { return mCellPhone.sendMessage(); } }
紧接着,实现GSP和蓝牙的功能扩展,它们继承自Decorator,代码如下:
//具体装饰类 GPS功能扩展 --> ConcreteDecorator class DecoratorGPS extends Decorator{ public DecoratorGPS(AbstractCellPhone mCellPhone) { super(mCellPhone); } @Override public String callNumber() { return super.callNumber() +" GPS"; } @Override public String sendMessage() { return super.sendMessage() +" GPS"; } } class DecoratorBlueTooth extends Decorator{ public DecoratorBlueTooth (AbstractCellPhone mCellPhone) { super(mCellPhone); } @Override public String callNumber() { return super.callNumber() +" BlueTooth"; } @Override public String sendMessage() { return super.sendMessage() +" BlueTooth"; } }
//客户 Client public class DecoratorClient { /** * @param args */ public static void main(String[] args) { AbstractCellPhone mCellPhone = new AndroidCellPhone(); System.out.println(mCellPhone.callNumber() +"\n" +mCellPhone.sendMessage()); System.out.println("-------------------------------------------"); Decorator gps = new DecoratorGPS(mCellPhone); System.out.println(gps.callNumber() +"\n" +gps.sendMessage()); System.out.println("-------------------------------------------"); Decorator bluetooth = new DecoratorBlueTooth(mCellPhone); System.out.println(bluetooth.callNumber() +"\n" +bluetooth.sendMessage()); } }
Decorator模式的优缺点
适用场景
最后,自己有一点点费解,Decorator完全可以不用继承自Component类 实现相同的功能,但是最终还是继承自 Component,不大明白