装饰器设计模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构,作为现有类的包装。
角色
-
Component:组件对象接口,可给对象动态的添加职责;
-
ConcreteComponent:具体组件对象,实现组件接口,该对象通常就是被装饰器装饰的原始对象,可给这个对象添加职责;
-
Decorator:所有装饰器父类,需定义1个与组件接口一致的接口,主要是为了实现装饰器功能复用,即具体的装饰器A可装饰另外一个具体的装饰器B,因装饰器类也是一个Component),并持有一个Component对象,该对象其实也是被装饰的对象。如果不继承组件接口类,则只能为某个组件添加单一的功能,即装饰器对象不能在装饰其他的装饰器对象。
-
ConcreteDecorator:具体装饰器类,实现具体要向被装饰对象添加的功能,用来装饰具体的组件对象或者另外1个具体的装饰器对象。
Component角色:被装饰对象
public interface Phone { public void call();}
ConcreteComponent角色:
public class PhoneImp implements Phone { @Override public void call() { System.out.println("手机正在通话......."); }}
Decorator 角色:装饰器:通过接口持有被装饰对象的引用,作为装饰器的基类
public abstract class PhoneDecorate implements Phone { private Phone phone; public PhoneDecorate(Phone phone) { this.phone = phone; } @Override public void call() { this.phone.call(); }}
ConcreteDecorator角色:
public class ColorPhoneDecorate extends PhoneDecorate{ //Phone可是其他的Phone接口的子类,也可是特殊功能 public ColorPhoneDecorate(Phone phone) { super(phone); } @Override public void call(){ System.out.println("手机正在播放彩铃....."); super.call(); }}
public class GuangGaoPhoneDecorate extends PhoneDecorate{ public GuangGaoPhoneDecorate(Phone phone) { super(phone); } @Override public void call(){ super.call(); //调用被包装对象的方法 System.out.println("手机语音正在播放广告......"); }}
测试代码:
//手机彩铃功能:1层装饰Phone phone = new PhoneImp(); //基础接口实现类PhoneDecorate phoneDecorate = new ColorPhoneDecorate(phone); //抽象装饰类phoneDecorate.call();System.out.println("-----------------------");//手机的彩铃和广告功能:2层装饰phoneDecorate = new GuangGaoPhoneDecorate(new ColorPhoneDecorate(phone));phoneDecorate.call();
手机功能演变:基础通话功能 --> 基础通话+彩铃 -->基础通话+彩铃+广告语音
装饰器模式分析:
装饰器和组件类都实现相同的接口,可将他们理解为一组和接口关联的对象,装饰器持有组件对象的引用,可保证各种实现基础组件接口的装饰器可以互相组合,从而实现不同的功能。
经典应用:JDK的IO流