装饰模式
动态的给一个对象添加一些而外的职责,就增加功能来说,装饰模式比生成子类更灵活。
下面为装饰模式结构图:
设计要灵活,如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent类的一个子类。同样,如果只有一个ConcreteDecorator类,那么就没有必要单独再建立一个Decorator类,而可以把Decorator和ConcreteComponent的责任合成一个类。
自我理解:装饰与继承的差异
继承:继承的子类需要重写父类的方法,然后才能扩展自己的一些方法。当业务需求变化,要增加其他功能或者调整原有逻辑,原来的子类存量功能又要保存,这时只能新增子类来完成需求。最终得到的结果是增加了一大堆重写父类方法的子类,很繁琐。
装饰:增加新的需求时,只需要在装饰类里面新增逻辑,然后在加载父类对象(用多态),提供外部调用即可,不用重写父类重写所有方法
代码示例:
public abstract class Strategy { /** * 算法策略 * @return * */ public abstract void calculate(); }
//具体实现者 public class ConcreteStrategy extends Strategy{ @Override public void calculate() { // TODO Auto-generated method stub System.out.println("具体的策略实现"); } }
//装饰者 public abstract class Decorate extends Strategy{ private Strategy st; public void setSt(Strategy st) { this.st = st; } @Override public void calculate() { // TODO Auto-generated method stub st.calculate(); } }//具体装饰者A public class ConcreteDecorateA extends Decorate{ @Override public void calculate() { // TODO Auto-generated method stub super.calculate(); addCalculateA(); } public void addCalculateA(){ System.out.println("增加的装饰方法A"); } }//具体装饰者B public class ConcreteDecorateB extends Decorate{ @Override public void calculate() { // TODO Auto-generated method stub super.calculate(); addCalculateB(); } public void addCalculateB(){ System.out.println("增加的装饰方法B"); } }
//在原有类的基础上增加装饰方法扩展,比起继承一个子类来说简单些(继承需要重写每一个方法) public class test { public static void main(String[] args) { ConcreteStrategy cs = new ConcreteStrategy(); ConcreteDecorateA cda = new ConcreteDecorateA(); ConcreteDecorateB cdb = new ConcreteDecorateB(); cs.calculate(); System.out.println("--------------------"); cda.setSt(cs); cda.calculate(); System.out.println("--------------------"); cdb.setSt(cda); cdb.calculate(); System.out.println("--------------------"); } }