概述:

本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦你熟悉了装饰者的技巧,你将能够在不修改任何底层代码的情况下,给你的(或别人的)对象赋予新的职责。——《Head First 设计模式》

使用环境:

当我们有多种类型的事物,且每一种事物下面又有很多小的、细的分类。这些分类之间可以随意组合时(例如一种饮料有一个主原料和一些配料、一道菜会有一个主原料加上一些配料或是去装饰一个房间等等),我们就可以想一下是不是可以用装饰模式来实现。下面就《Head First 设计模式》中的例子星巴兹的咖啡说简单说明一下。

功能优点:

利用组合维护代码,通过动态地组合对象,可以写新的代码添加新功能,而无须修改现有代码。

思路分析:

在星巴兹的咖啡店里,有多种咖啡,和多种调料。如果我们选择一种咖啡另外配上一种或是几种配料(主要主是一个被装饰者和多个装饰者)。那么我们如何对这些咖啡和配料进行收费呢(这里采用收费是一个好的举例,当然也可以是其他的一些相同的事件)?如果你说我们对每一种可选搭配可以封装,天呐,那该会有多少个类啊。还有一点就是,如果咖啡店里如果有一种咖啡或是配料价格有变动,或是需要新添加一种咖啡或是配料,又该怎么办呢?

其实本文的模式就有一种很好的解决办法:我们不再使用继承,因为继承可能会导致类爆炸的。我们试想一下,能不能把咖啡店中的的所有原料(包括主原料和所有配料)都看成是一种东西(原料)。这样我们就可以在相互组合的过程中动态实现某些功能。可能你会问为什么要把其看成是一种东西,这样做的目的是为了在所有原料中实现同一功能,且无关代码中的组合顺序。

类图展示:

当然,你也可以把上面咖啡那4个类再封一层。这里我就书中的内容做了一个原样输出。

代码展示:

Beverage.java

public abstract class Beverage {

public String mDescription = "UnKnown Beverage";

private int size = 0;

public String getDescription() {

return mDescription;

}

public int getSize() {

return size;

}

public void setSize(int size) {

this.size = size;

}

public abstract double cost();

}

CondimentDecorator.java

public abstract class CondimentDecorator extends Beverage {

@Override

public double cost() {

return 0;

}

public abstract String getDescription();

}

DarkRoast.java

public class DarkRoast extends Beverage {

private double mCost = 0.99;

public DarkRoast() {

mDescription = "Dark Roast Coffee";

}

@Override

public double cost() {

return mCost;

}

}

Milk.java

public class Milk extends CondimentDecorator {

private Beverage mBeverage = null;

private double mCost = 0.10;

public Milk(Beverage beverage) {

mBeverage = beverage;

}

@Override

public String getDescription() {

return mBeverage.getDescription() + ", Milk";

}

public double cost() {

return mCost + mBeverage.cost();

}

}

StarbuzzCoffee.java

public class StarbuzzCoffee {

public static void main(String[] args) {

Beverage beverage = new Espresso();

System.out.println(beverage.getDescription() + " $" + beverage.cost());

Beverage beverage2 = new DarkRoast();

beverage2 = new Mocha(beverage2);

beverage2 = new Mocha(beverage2);

beverage2 = new Whip(beverage2);

System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

Beverage beverage3 = new HouseBlend();

beverage3 = new Soy(beverage3);

beverage3 = new Mocha(beverage3);

beverage3 = new Whip(beverage3);

System.out.println(beverage3.getDescription() + " $" + beverage3.cost());

}

}

运行图例:

源码下载:

http://download.csdn.net/detail/u013761665/8721015

装饰模式java咖啡_Java设计模式——装饰者模式相关推荐

  1. java装饰模式模拟流_Java设计模式--装饰器模式到Java IO 流

    装饰器模式 抽象构件角色:给出一个抽象接口,以规范准备接受附加责任的对象. 具体构件角色:定义准备接受附加责任的对象. 抽象装饰角色:持有一个构件对象的实例,并对应一个与抽象构件接口一致的接口. 具体 ...

  2. 访问者模式的java语言_Java 设计模式 之 访问者模式

    package com.visit.theory; import java.util.ArrayList; public class Test { public static void main(St ...

  3. 设计模式 —— 装饰者模式

    目录 一.星巴克咖啡订单项目需求 二.方案 1-解决星巴克咖啡订单项目(较差) 三.方案 2-解决星巴克咖啡订单(好点) 四.装饰者模式定义 4.1 装饰者模式原理 4.2 装饰者模式解决星巴克咖啡订 ...

  4. 10. 设计模式-装饰者模式

    文章目录 设计模式-装饰者模式 1. 案例引出装饰者模式 2. 装饰者模式 2.1 装饰者模式定义 2.2 装饰者模式原理 2.3 装饰者模式解决星巴克咖啡订单问题 2.4 代码实现 抽象类Drink ...

  5. 设计模式——装饰者模式

    本文是阅读 Head First 设计模式--装饰者模式的总结. 这本书的教学模式很不错,个人很喜欢,由实际的案例由浅入深,循序渐进的让你明白良好的设计是多么的优雅迷人(回头看看自己的代码,WTF!) ...

  6. 设计模式装饰者模式_装饰者模式如何拯救了我的一天

    设计模式装饰者模式 在工作中,我正在处理庞大的Java代码库,该代码库是由许多不同的开发人员在15年的时间里开发的. 并不是所有的事情都由书来完成,但是同时我通常无法重构遇到的每一个奇怪的事物. 尽管 ...

  7. 23种设计模式——装饰者模式

    文章目录 23种设计模式--装饰者模式 1.装饰者模式概述 2.装饰者模式的结构 3.装饰者模式的实现 4.装饰者模式的应用场景 23种设计模式--装饰者模式 1.装饰者模式概述 背景 有些人为了早上 ...

  8. Go 设计模式 - 装饰器模式

    装饰模式使用对象组合的方式动态改变或增加对象行为.Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式.使用匿名组合,在装饰器中不必显式定义转调原对象方法. 设计模式 装饰器模式 装饰器模式主要 ...

  9. 米线店结账程序 装饰着模式_设计模式——装饰者模式

    <Head First 设计模式> 学习笔记,码云同步更新中 如有错误或不足之处,请一定指出,谢谢~ 目录 查看其它设计模式笔记,点这里→设计模式笔记汇总 装饰者模式 定义: 动态地将责任 ...

最新文章

  1. 人脸对齐--Face Alignment by Explicit Shape Regression
  2. jquery ajax异步和同步从后天取值
  3. SysTick的优先级是高还是低
  4. Teams Bot开发系列:Middleware
  5. .NET Core 仿魔兽世界密保卡实现
  6. php整合支付宝,Thinkphp5.0整合支付宝在线下单
  7. PHP5时间相差八小时问题[三种方法]
  8. 如何向小白讲述软件架构发展历程?
  9. My_arduino(4)-------LiquidCrystal_I2C库文件
  10. 项目管理九大知识领域过程逻辑关系图
  11. 不要在意别人的目光,走自己的路
  12. android 空调遥控,安卓版万能空调遥控器
  13. 得力针式打印机第一联清晰第二联不清晰解决办法
  14. 不知道照片如何拼图?这3个方法能帮上你
  15. C++MYSQL:获取表结构:MYSQL_FEILD
  16. GPT-3会是第一个通用人工智能吗?
  17. Delphi文件正文提取开发组件--文件内容搜索的高效工具
  18. 2018上交软科计算机科学排名,2018年上海软科世界一流学科排名出炉!
  19. Linux 通配符和特殊符号
  20. OpenMV物品清单

热门文章

  1. 基于哈夫曼编码对文件进行压缩和解压缩(详细讲解)
  2. proe计算机id,三种proe安装时主机ID查找方法
  3. MySQL查询之子查询
  4. 天津市行政区划 (2023)
  5. golang大厂面试2
  6. WEB前端开发简易网页制作
  7. 中通开放平台简介——签名生成
  8. python编写音乐-python写的定时播放音乐
  9. List的初始化和赋值操作
  10. Three.js入门 (参考胖达老师)| 大帅老猿threejs特训