1 基础知识
定义:在不改变原有对象的基础上,将功能附加到对象上。特征:提供了比继承更有弹性的替代方案。
使用场景:扩展一个类的功能或给一个类添加附加的职责;动态给一个对象添加功能,这些功能还可以动态撤销。
优点:比继承更加灵活,继承是静态的在设计之初就确定好了而装饰者是动态的扩展功能;通过使用不同的装饰类或装饰类的排列组合可以达到不同的效果;符合开闭原则。缺点:会出现更多的代码,更多的类使程序复杂;动态装饰时,多层装饰会更复杂。
2 代码示例
场景:假设商家做了许多煎饼,这些煎饼有的加蛋,有的加烤肠那么如何计算出这些不同种类的的煎饼?
煎饼类:Battercake
public class Battercake { //描述 protected String getDesc(){ return "煎饼"; } //煎饼的基本价格 protected int cost(){ return 8; } }
煎饼加鸡蛋类:BattercakeWithEgg 继承煎饼类
public class BattercakeWithEgg extends Battercake { @Override public String getDesc() { return super.getDesc()+" 加一个鸡蛋"; } @Override //重写父类花费方法 public int cost() { return super.cost()+1; } }
煎饼加鸡蛋类加香肠类:BattercakeWithEggSausage 继承煎饼加鸡蛋类
public class BattercakeWithEggSausage extends BattercakeWithEgg { @Override public String getDesc() { return super.getDesc()+ " 加一根香肠"; } @Override public int cost() { return super.cost()+2; } }
应用层:Test
public class Test { public static void main(String[] args) { //基本的煎饼 Battercake battercake = new Battercake(); System.out.println(battercake.getDesc()+" 销售价格:"+battercake.cost()); //加鸡蛋的类 Battercake battercakeWithEgg = new BattercakeWithEgg(); System.out.println(battercakeWithEgg.getDesc()+" 销售价格:"+battercakeWithEgg.cost()); //加鸡蛋加香肠的类 Battercake battercakeWithEggSausage = new BattercakeWithEggSausage(); System.out.println(battercakeWithEggSausage.getDesc()+" 销售价格:"+battercakeWithEggSausage.cost()); } }
此时如果想加两个鸡蛋,加三个香肠等则需要分别建立对应的类这样可以预见一定会随着的需求的复杂而使得的类的数目上升,造成类爆炸。那么对于这种情形的解决方案便是装饰者模式。在装饰者模式中要有抽象的实体类、具体的实体类,抽象的装饰者、具体的装饰者根据这些来编写代码。
抽象的实体类:ABattercake
public abstract class ABattercake { protected abstract String getDesc(); protected abstract int cost(); }
具体的实体类:Battercake
public class Battercake extends ABattercake { @Override protected String getDesc() { return "煎饼"; } @Override protected int cost() { return 8; } }
0