一、定义
定义:在不改变原有对象的基础上,将功能附加到对象上
提供了比继承更有弹性的替代方案(扩展原有对象功能)
类型: 结构型
二、使用场景
扩展一个类的功能或者给一个类添加附件职责
动态给一个对象添加功能,这些功能可以再动态的撤销
三、优点
继承的有力补充,比继承灵活,不改变原有对象的情况下给对象一个扩展功能
通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同的效果
符合开闭原则
四、缺点
会出现更多的代码,更多的类,增加程序的复杂性
动态装饰时,多层装饰时会更复杂
五、相关设计模式
1. 装饰者模式和代理模式
装饰者模式关注一个对象动态添加方法
代理模式关注控制对对象的访问
六、Coding
1. 创建BatterCake 类
/** * 煎饼 */ public class BatterCake { protected String getDesc(){ return "煎饼"; } protected int cost(){ return 8; } }
2. 创建BatterCakeWithEgg
public class BatterCakeWithEgg extends BatterCake{ @Override public String getDesc() { return super.getDesc() + " 加一个鸡蛋"; } @Override public int cost() { return super.cost() + 1; } }
3. 创建BatterCakeWithEggSausage类
public class BatterCakeWithEggSausage extends BatterCakeWithEgg{ @Override public String getDesc() { return super.getDesc() + " 加一根香肠"; } @Override public int cost() { return super.cost() + 2; } }
4. 测试类
public class Test { public static void main(String[] args) { BatterCake batterCake = new BatterCake(); System.out.println(batterCake.getDesc() + " 销售价格:" + batterCake.cost()); BatterCakeWithEgg batterCakeWithEgg = new BatterCakeWithEgg(); System.out.println(batterCakeWithEgg.getDesc() + " 销售价格:" + batterCakeWithEgg.cost()); BatterCakeWithEggSausage batterCakeWithEggSausage = new BatterCakeWithEggSausage(); System.out.println(batterCakeWithEggSausage.getDesc() + " 销售价格:" + batterCakeWithEggSausage.cost()); } }
缺点:不能增加个数,如需要两个鸡蛋和两个火腿肠
七、Coding(改进版本)
1. 创建ABatterCake抽象类
public abstract class ABatterCake { protected abstract String getDesc(); protected abstract int cost(); }
2. 创建BatterCake类
public class BatterCake extends ABatterCake{ @Override protected String getDesc() { return "煎饼"; } @Override protected int cost() { return 8; } }
3. 创建AbstractDecorator。 这里可以不用抽象类
public abstract class AbstractDecorator extends ABatterCake { private ABatterCake aBatterCake; public AbstractDecorator(ABatterCake aBatterCake){ this.aBatterCake = aBatterCake; } protected abstract void doSomething(); @Override protected String getDesc() { return this.aBatterCake.getDesc(); } @Override protected int cost() { return this.aBatterCake.cost(); } }
4. 创建装饰类 EggDecorator
public class EggDecorator extends AbstractDecorator{ public EggDecorator(ABatterCake aBatterCake) { super(aBatterCake); } @Override protected void doSomething() { } @Override protected String getDesc() { return super.getDesc() + " 加一个鸡蛋"; } @Override protected int cost() { return super.cost() + 1; } }
5. 创建装饰类
public class SausageDecorator extends AbstractDecorator{ public SausageDecorator(ABatterCake aBatterCake) { super(aBatterCake); } @Override protected void doSomething() { } @Override protected String getDesc() { return super.getDesc() + "加一根香肠"; } @Override protected int cost() { return super.cost() + 2; } }
6. 创建测试类
public class Test { public static void main(String[] args) { ABatterCake aBatterCake = new BatterCake(); aBatterCake = new EggDecorator(aBatterCake); aBatterCake = new EggDecorator(aBatterCake); aBatterCake = new EggDecorator(aBatterCake); System.out.println(aBatterCake.getDesc() + " 销售价格:" + aBatterCake.cost()); } }
7. UML图
八、装饰者模式在源码中的应用
1.java.io包下的BufferedReader类
继承于Reader抽象类。BufferedReader的构造器如下
public BufferedReader(Reader var1, int var2) { super(var1); this.markedChar = -1; this.readAheadLimit = 0; this.skipLF = false; this.markedSkipLF = false; if(var2 <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } else { this.in = var1; this.cb = new char[var2]; this.nextChar = this.nChars = 0; } }
2. BufferedOutputStream和BufferedInputStream
BufferedOutputStream继承自FilterOutputStream, FilterOutputStream继承自OutputStream
BufferedOutputStream的构造器
public BufferedOutputStream(OutputStream var1, int var2) { super(var1); if(var2 <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } else { this.buf = new byte[var2]; } }
3. FilterInputStream是一个装饰者,LineInputStream,BufferedInputStream,DataInputStream是实际的装饰者。
4. 在spring中的TransactionAwareCacheDecorator类
public class TransactionAwareCacheDecorator implements Cache { private final Cache targetCache; public TransactionAwareCacheDecorator(Cache targetCache) { Assert.notNull(targetCache, "Target Cache must not be null"); this.targetCache = targetCache; } }
5. Mybatis中的org.apache.ibatis.cache.Cache类
例如FifoCache 类
public class FifoCache implements Cache { private final Cache delegate; private Deque<Object> keyList; private int size; public FifoCache(Cache delegate) { this.delegate = delegate; this.keyList = new LinkedList(); this.size = 1024; } }
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!