设计模式:装饰者模式
装饰者模式:动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
现在,我们有一个场景,咖啡店出售各种不同的咖啡,而不同的咖啡中可以加入各种不同的调料,根据咖啡种类和加入的调料来计算价格。下面我们就用代码来简单实现下这个场景,也就是装饰者模式,其中咖啡为主体,调料是用来装饰咖啡的,比如想要一杯摩卡和奶泡的深焙咖啡,那么要做的是:
1:拿一个深焙咖啡DarkRoast对象
2:以摩卡Mocha对象来进行装饰
3:以奶泡Whip对象进行装饰
4:调用cost方法,并依赖委托将调料价格加上去。
好了,直接上代码理解装饰者模式吧。
第一步:先创建一个基类,所有咖啡和调料都是扩展自这个类的。这就说明装饰者和被装饰者对象都有相同的超类型。
//基类 public abstract class Coffer { String descirption = "Unknown Coffer"; public String getDescription(){ return descirption; } //所有子类必须实现这个方法来计算价格 public abstract double cost(); }
第二步:创建一个调料的抽象类,也就是装饰者类,具体的装饰者类实现此类。
//抽象的装饰者,调料类,扩展自Coffer public abstract class Condiment extends Coffer{ public abstract String getDescription(); }
第三步:创建具体的咖啡类。
//具体的咖啡种类——浓缩咖啡类 public class Espresso extends Coffer{ public Espresso(){ descirption = "Espresso"; } @Override public double cost() { return 1.99; } }
//具体的咖啡种类——深焙咖啡类 public class DarkRoast extends Coffer{ public DarkRoast(){ descirption = "DarkRoast"; } @Override public double cost() { return 0.88; } }
第四步:创建具体的调料类
//具体的装饰者,摩卡调料 public class Mocha extends Condiment { //用于记录被装饰者,这里是在构造方法中将参数记录到咖啡的实例变量中,你也可以使用get/set方法 Coffer coffer; public Mocha(Coffer coffer){ this.coffer = coffer; } @Override public String getDescription() { return coffer.getDescription() + ", Mocha"; } @Override public double cost() { return 0.2 + coffer.cost(); } }
//具体的装饰者,奶泡调料 public class Whip extends Condiment{ Coffer coffer; public Whip(Coffer coffer){ this.coffer = coffer; } @Override public String getDescription() { return coffer.getDescription() + ", Whip"; } @Override public double cost() { return 0.15 + coffer.cost(); } }
第五步:测试
public class Test { public static void main(String[] args) { //来一杯Espresso咖啡 Coffer coffer = new Espresso(); System.out.println(coffer.getDescription() + ",价格:" + coffer.cost()); //来一杯深焙咖啡,加入2分摩卡和1分奶泡 Coffer coffer2 = new DarkRoast(); coffer2 = new Mocha(coffer2); coffer2 = new Mocha(coffer2); coffer2 = new Whip(coffer2); System.out.println(coffer2.getDescription() + ",价格:" + coffer2.cost()); } }
运行结果:
好了,这就是一个简单的装饰者模式了。在Java的API中,你可以发现,有关IO类就是采用装饰者模式的,如:
LineNumberInputStream inputStream = new LineNumberInputStream(new BufferedInputStream(new FileInputStream(fileName)));
顶层类都是InputStream,具体这里不讲解了。
下一节:工厂模式
作者:哀&RT
出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。