概念
在面向对象的编程中,装饰器模式是一种设计模式,它允许动态地将行为添加到单个对象,而不会影响来自同一类的其他对象的行为。
举例
当我们在需要扩展一个类的方法的时候,我们需要不断地继承原始方法或上一级方法的类,加上新的方法结构,这样就实现了对于原始方法的增强。当继承关系复杂的情景下,当我们要修改其中一个类方法,会导致其他增强方法的重写,这样使代码的耦合性太强,维护成本很高。对于这种情况,我们可以试试使用装饰者模式去解决这个问题。
就以我们最经常看到的IO操作中,构造一个InputStreamReader,File读取path封装成FileInputStream,接着被装饰成InputStreamReader
1
| InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(path)));
|
组成
Component接口:抽象组件,即最原始的方法,底层方法。
ConcreteComponent类:实现了Component接口,具体的被装饰组件。
Decorator类:抽象继承类,是所有装饰者的父类。内部有一个私有的Component类型的属性,在构造方法中初始化属性,对底层的方法做了封装。
ConcreteDecorator类:具体的装饰者类,继承Decorator类。每一个ConcreteDecorator类都会有自己的私有方法(方法增强),接着通过在重写父类方法,在重写方法中添加自身方法,从而达到了新的功能的效果。
举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| /** * Created by Heiku on 2018/8/31 * * Decorator pattern */
// 抽象手机功能 interface PhoneFunc{
void shoot(); void play(); }
// 手机的具体实现 class SimplePhone implements PhoneFunc{
@Override public void shoot() { System.out.println("我可以拍摄"); }
@Override public void play() { System.out.println("我可以播放音乐"); } }
// 抽象装饰者 abstract class Decorator implements PhoneFunc{
// 被装饰的PhoneFunc private PhoneFunc phoneFunc;
// 通过构造器注入装饰的phoneFunc public Decorator(PhoneFunc phoneFunc){ this.phoneFunc = phoneFunc; }
@Override public void shoot() { this.phoneFunc.shoot(); }
@Override public void play() { this.phoneFunc.play(); } }
// 继承抽象装饰者 class ShootPhone extends Decorator{
public ShootPhone(PhoneFunc phoneFunc){ super(phoneFunc); }
// 自己新加的功能 private void exposure(){ System.out.println("拍摄曝光处理"); }
@Override public void shoot() { super.shoot(); exposure(); } }
class BeautyPhone extends Decorator{
public BeautyPhone(PhoneFunc phoneFunc){ super(phoneFunc); }
// 自己新加的功能 private void Beauty(){ System.out.println("拍摄美颜处理"); }
@Override public void shoot() { super.shoot(); Beauty(); } }
public class Phone { public static void main(String[] args) {
BeautyPhone beautyPhone = new BeautyPhone(new ShootPhone(new SimplePhone())); beautyPhone.shoot(); } }
Reuslt: 我可以拍摄 拍摄曝光处理 拍摄美颜处理
|