学习笔记-设计模式之装饰器模式
一、概念
装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。
简言之:大桶套小桶
二、实现
需求:现在有人在路边卖煎饼,原价5元,加1个鸡蛋1元,加1个香肠2元,要求给顾客做两个煎饼:
第一个加一个鸡蛋,第二个加一个鸡蛋一个香肠。
首先创建煎饼类
1 public class BatterCake { 2 3 protected String getMsg(){ 4 return "煎饼"; 5 } 6 7 public int getPrice(){ 8 return 5; 9 } 10 11 }
getMsg方法返回当前煎饼信息,getPrice返回当前煎饼价格。
创建加一个鸡蛋的煎饼
1 public class BatterCakeWithEgg extends BatterCake { 2 3 protected String getMsg() { 4 return super.getMsg() + "+1 个鸡蛋"; 5 } 6 7 //加一个鸡蛋加 1 块钱 8 public int getPrice() { 9 return super.getPrice() + 1; 10 } 11 }
这里通过继承的方式来实现,同理创建加一个鸡蛋一个香肠煎饼
1 public class BatterCakeWithEggAndSausage extends BatterCakeWithEgg { 2 @Override 3 protected String getMsg() { 4 return super.getMsg() + "+1 根香肠"; 5 } 6 7 @Override 8 //加一个香肠加 2 块钱 9 public int getPrice() { 10 return super.getPrice() + 2; 11 } 12 13 }
测试类
1 public class BatterCakeTest { 2 3 public static void main(String[] args) { 4 BatterCake battercake = new BatterCake(); 5 System.out.println(battercake.getMsg() + ",总价格:" + battercake.getPrice()); 6 7 BatterCake batterCakeWithEgg = new BatterCakeWithEgg(); 8 System.out.println(batterCakeWithEgg.getMsg() + ",总价格:" + batterCakeWithEgg.getPrice()); 9 BatterCake batterCakeWithEggAndSausage = new BatterCakeWithEggAndSausage(); 10 System.out.println(batterCakeWithEggAndSausage.getMsg() + ",总价格:" + batterCakeWithEggAndSausage.getPrice()); 11 } 12 }
输出
煎饼,总价格:5 煎饼+1 个鸡蛋,总价格:6 煎饼+1 个鸡蛋+1 根香肠,总价格:8
虽然实现了基本的业务需求,但是,当用户需要加两个鸡蛋两根香肠的煎饼,或者是一个鸡蛋两根香肠的煎饼时都需要新增一个类。增加了系统复杂度。
下面看看用装饰器实现。
创建煎饼接口
1 public interface BatterCake { 2 3 String getMsg(); 4 5 int getPrice(); 6 }
创建鸡蛋装饰类
public class EggDecorator implements BatterCake { private BatterCake battercake; public EggDecorator(BatterCake battercake) { this.battercake = battercake; } @Override public String getMsg() { return battercake.getMsg() + "+1个鸡蛋"; } @Override public int getPrice() { return battercake.getPrice() + 1; } }
创建香肠装饰类
1 public class SausageDecorator implements BatterCake { 2 private BatterCake battercake; 3 4 public SausageDecorator(BatterCake battercake) { 5 this.battercake = battercake; 6 } 7 8 @Override 9 public String getMsg() { 10 return battercake.getMsg() + "+1根香肠"; 11 } 12 13 @Override 14 public int getPrice() { 15 return battercake.getPrice() + 2; 16 } 17 }
测试类
1 public class BatterCakeTest { 2 3 public static void main(String[] args) { 4 BatterCake battercake = new BaseCake(); 5 // 加一个鸡蛋 6 BatterCake cakeWithOneEgg = new EggDecorator(battercake); 7 System.out.println(); 8 // 加两个鸡蛋 9 BatterCake cakeWithTowEgg = new EggDecorator(new EggDecorator(battercake)); 10 // 加两个鸡蛋两根香肠 11 BatterCake cakeWithTowEggAndTowSausage = new SausageDecorator(new SausageDecorator(new EggDecorator(new EggDecorator(battercake)))); 12 System.out.println(cakeWithTowEggAndTowSausage.getMsg() + ",总价:" + cakeWithTowEggAndTowSausage.getPrice()); 13 } 14 }
这样,无论用户需要多少个鸡蛋,多少根香肠都能轻松实现。