设计原则
类应该对扩展开发,对修改关闭
不修改现有代码的情况下,可以添加新的行为,这样的设计具有弹性,可以应对变化,提供新的功能。
装饰者模式完全遵循开放-关闭的原则
遵循开放-关闭原则,通常会引入新的抽象层次,增加代码的复杂度
应该把注意力集中在主要的容易发生变化的地方,然后应用开放-关闭原则
装饰:最低层的功能不变,对外提供了更灵活更方便的方法
委托:低层功能调用还得依赖与具有该行为的对象,委托这个对象去完成它自己才能完成的事
咖啡馆的故事
Beverage为所有类的基类,它将作为方法的参数接受各种类型的子类对象
HouseBend,DarkRoster,Espresso,Decaf,都是被装饰对象,通过cost方法计算各自的价钱
CondimentDecorator继承Beverage,自身为一个抽象类,为子类封装共有的属性和方法
Milk,Mocha,Soy,Whip,都是装饰者,将对被装饰对象进行装饰,在内部会让被装饰者去调用自己的方法计算价格
公共的基类,将来作为方法的参数,接收各种子类对象
package decorator.coffee; import java.text.NumberFormat; public abstract class Beverage { public static enum BeverageSize { BIG, MEDIUM, SMALL;// 大杯,中杯,小杯 } //杯子大小 private BeverageSize size; public BeverageSize getSize() { return size; } public void setSize(BeverageSize size) { this.size = size; } //饮料描述信息 protected String description = "Unknow Beverage"; public String getDescription() { return description; } //需由子类去实现去方法 public abstract double cost(); /** * 计算总价时,加上杯子的钱(只能加1次) * @return */ public double costTotal() { double total = cost(); if(size!=null) { switch (this.size.ordinal()) { case 0: total += 0.20;//大杯 break; case 1: total += 0.15;//中杯 break; case 2: total += 0.10;//小杯 break; } } NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); return Double.valueOf(nf.format(total)); } }
将要被装饰的类(一)
package decorator.coffee; public class Espresso extends Beverage { public Espresso() { this.description = "Espresso"; } @Override public double cost() { return 1.99; } }
将要被装饰的类(二)
package decorator.coffee; public class HouseBlend extends Beverage { public HouseBlend() { this.description = "HouseBlend"; } @Override public double cost() { return 0.89; } }
中转作用的类,实现装饰者与被装饰者都是Beverage的子类
package decorator.condiment; import decorator.coffee.Beverage; /** * 继承Beverage,让装饰者继承它,这样装饰者(调料)与被装饰者(具体的饮料)都属于Beverage * 都是Beverage的子类,从而在面向父类/接口编程时,都可以作为参数传入到方法中! */ public abstract class CondimentDecorator extends Beverage { //持有祖先的引用 //通过祖先获取旁系,祖先对子孙的设计,这样便可以利用多态的功能,动态绑定子类对象了! //【这里的做法与javascript中getParentNode()获取sibing的思想有一丁点儿的类似】 Beverage beverage;//实为组合的应用,特殊的地方:被组合的对象为自己的父类 public CondimentDecorator(Beverage beverage) { this.beverage = beverage;//参数为父类,为多态做准备 } @Override public String getDescription() { return this.beverage.getDescription()+", "+this.getClass().getSimpleName(); } }
装饰者(一)
package decorator.condiment; import decorator.coffee.Beverage; /** * 真正的装饰者 * */ public class Mocha extends CondimentDecorator { public Mocha(Beverage beverage) { super(beverage);//将实际的coffee传进来 } @Override public double cost() { return 0.20 + this.beverage.cost();//delegate委托beverage的具体实现类去计算自己的价钱 } }
装饰者(二)
package decorator.condiment; import decorator.coffee.Beverage; /** * 真正的装饰者 * */ public class Soy extends CondimentDecorator { public Soy(Beverage beverage) { super(beverage);//将实际的coffee传进来 } @Override public double cost() { return 0.40 + this.beverage.cost();//delegate委托beverage的具体实现类去计算自己的价钱 } }
装饰者(三)
package decorator.condiment; import decorator.coffee.Beverage; /** * 真正的装饰者 * */ public class Whip extends CondimentDecorator { public Whip(Beverage beverage) { super(beverage);//将实际的coffee传进来 } @Override public double cost() { return 0.30 + this.beverage.cost();//delegate委托beverage的具体实现类去计算自己的价钱 } }
测试
package test; import decorator.coffee.Beverage; import decorator.coffee.Beverage.BeverageSize; import decorator.coffee.Espresso; import decorator.condiment.Mocha; public class BeverageTest { public static void main(String[] args) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription()+" $"+beverage.costTotal()); beverage = new Mocha(beverage); System.out.println(beverage.getDescription()+" $"+beverage.costTotal()); beverage = new Mocha(beverage); System.out.println(beverage.getDescription()+" $"+beverage.costTotal()); //设置杯子的大小 beverage.setSize(BeverageSize.BIG); System.out.println(beverage.getDescription()+" $"+beverage.costTotal()); } }
JAVA I/O中对装饰者模式的应用
相关推荐
【标题】:“装饰者模式(decorator)在Head First设计模式中的详解” 【内容】: 装饰者模式(Decorator Pattern)是结构型设计模式之一,它允许动态地给一个对象添加新的功能,而无需修改其原有代码。这个模式的...
在Head First的设计模式系列书籍中,第三部分详细介绍了装饰者模式的原理和应用。该模式的核心思想是定义一个抽象组件接口(Component),以及实现了这个接口的类(ConcreteComponent)。然后创建一系列装饰者类...
装饰者模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码。这种模式在C++中的应用尤为广泛,因为它提供了灵活性,能够扩展对象的功能,同时保持代码的可读性和可维护性。 ...
在“HeadFirst 设计模式学习笔记3--装饰模式 Demo”中,作者通过实例讲解了装饰模式的基本概念、结构和应用场景。这篇文章可能是从CSDN博客平台上的一个链接访问的,遗憾的是,由于我们当前无法直接访问该链接,所以...
《Headfirst设计模式》是一本深受开发者欢迎的设计模式学习书籍,尤其对于初学者而言,其独特的教学方式使得复杂的概念变得易于理解。这本书以其高清的中文版PDF格式提供,结合书中源码,为读者提供了深入实践的可能...
总的来说,这个压缩包包含的资源可以帮助你深入理解设计模式,通过《HeadFirst设计模式》和《HeadFirst in Java》的源码,你可以学习到如何在实际项目中应用这些模式。而UML类图则提供了直观的视角,便于你把握设计...
《Head First Design Patterns》是一本深入浅出介绍设计模式的图书,由Eric Freeman、Elisabeth Freeman、Bert Bates和Kathy Sierra联合编写。本书结合认知科学原理和神经生物学研究,采用引导式教学方法,通过故事...
《Head First设计模式》是一本深受开发者喜爱的经典书籍,它以独特、生动的方式讲解了设计模式这一核心的软件工程概念。设计模式是经验丰富的开发者在解决常见问题时总结出的最佳实践,它们为软件设计提供了可复用的...
《HeadFirst设计模式》是一本深受开发者欢迎的书籍,它以独特、易理解的方式介绍了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的最佳实践,它们为软件设计提供了可复用的...
第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、Abstract Factory、Factory Method、Singleton、Command、Adapter、Facade、Template Method、iterator、Composite、State、proxy。最后三章比较...
《HeadFirst设计模式源代码》是一本面向程序员的深度学习设计模式的书籍,它通过直观易懂的方式将复杂的概念转化为生动的图像和有趣的例子,帮助读者深入理解并掌握设计模式。设计模式是软件工程中的一种最佳实践,...
《Head First设计模式》是一本深受开发者欢迎的设计模式教程,以其独特的视觉呈现方式和易于理解的语言,让初学者也能快速掌握设计模式的核心概念。这本书深入浅出地介绍了23种GOF(GoF,Gamma、Erich、Johnson、...
《Head First 设计模式》是一本深受欢迎的设计模式书籍,由Eric Freeman、Elisabeth Robson、Bert Bates和Kathy Sierra合著。这本书以其独特的视觉呈现方式和易理解的教学方法,深受程序员们的喜爱,尤其是那些希望...
《Head First 设计模式》的英文版是一本面向初学者的设计模式入门书籍,它以幽默风趣的文风,深入浅出地介绍了软件设计中经常使用的设计模式。设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的...
《Head First设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、...
《Head First设计模式》是一本深受开发者欢迎的设计模式学习书籍,以其独特的教学方式,通过丰富的图解和幽默的语言,帮助读者深入理解设计模式的核心概念。这本书的官方源码提供了书中所讲解的每个设计模式的实际...
《Head First设计模式》是软件开发领域的一本经典著作,主要介绍了面向对象设计中的各种模式。这本书通过生动、直观的方式,使读者能够更好地理解和应用设计模式。源代码是书中理论知识的具体实现,可以帮助读者深入...