开放原则:类应该对扩展开放,对修改关闭。

  - 上篇博客中的观察者模式中,通过加入新的观察者,我们可以在任何时候扩展主题(Subject),而且不需向主题中添加代码。

  - 装饰者模式也完全遵循开放原则。

装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

  记住:是你,还有你,一切拜托你。

    是你:包装类继承(或实现)被包装类

    还有你:包装类包含被包装类的一个实例

      一切拜托你:非增强方法全部拜托 被包装类的实例来完成

    增强方法:根据需求重写方法

 代码

/**
* 饮料
* @author oy
* @date 2019年8月28日 下午11:07:33
* @version 1.0.0
*/ public abstract class Beverage {
public String description; public String getDescription() {
return description;
} public abstract double cost(); // 其他方法
public abstract String method1();
}

  CondimentDecorator

/**
* 装饰类 = 饮料 + 调料
* @author oy
* @date 2019年8月28日 下午11:13:55
* @version 1.0.0
*/
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription(); // 空实现
public String method1() {
return "";
}
}

  Espresso

/**
* 浓缩咖啡
*/
public class Espresso extends Beverage { public Espresso() {
description = "Espresso";
} @Override
public double cost() {
return 1.0;
} @Override
public String method1() {
return "Espresso method1()";
}
}

  HouseBlend

/**
* House Blend Coffee*/
public class HouseBlend extends Beverage { public HouseBlend() {
description = "House Blend Coffee";
} @Override
public double cost() {
return 2.0; } @Override
public String method1() {
// TODO Auto-generated method stub
return "HouseBlend method1()";
}
}

  Mocha

/**
* 具体的装饰类:是你,还有你,一切拜托你。*/ public class Mocha extends CondimentDecorator {//是你:Mocha是Beverage类型 Beverage beverage; // 还有你:Mocha包含Beverage的对象实例 public Mocha(Beverage beverage) {
this.beverage = beverage;
} @Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
} // 一切拜托你:Beverage的不需要增强的方法全部拜托给beverage对象来处理
@Override
public String method1() {
return beverage.method1();
} // 重写增强方法
@Override
public double cost() {
return 0.20 + beverage.cost();
}
}

  Whip

/**
* 具体的装饰类:是你,还有你,一切拜托你。
* @author oy
* @date 2019年9月1日 上午10:06:53
* @version 1.0.0
*/
public class Whip extends CondimentDecorator {//是你 Beverage beverage; // 还有你 public Whip(Beverage beverage) {
this.beverage = beverage;
} @Override
public String getDescription() {
return beverage.getDescription() + ", Whip";
} @Override
public String method1() {
return beverage.method1();
} // 增强方法
@Override
public double cost() {
return 0.30 + beverage.cost();
}
}

  测试代码

public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
System.out.println(beverage.method1()); // 用摩卡装饰Espresso(浓缩饮料)
Beverage mocha = new Mocha(beverage);
System.out.println(mocha.getDescription() + " $" + mocha.cost());
System.out.println(mocha.method1());
// 还可以继续装饰mocha
mocha = new Whip(mocha);
System.out.println(mocha.getDescription() + " $" + mocha.cost());
System.out.println(mocha.method1());
}

  打印结果:

Espresso $1.0
Espresso method1()
Espresso, Mocha $1.2
Espresso method1()
Espresso, Mocha, Whip $1.5
Espresso method1()

head first 设计模式笔记3-装饰者模式:星巴兹饮料的更多相关文章

  1. JAVA设计模式之【装饰者模式】

    JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...

  2. 【读书笔记】读《JavaScript设计模式》之装饰者模式

    一.定义 装饰者模式可用来透明地把对象包装在具有同样接口的另一个对象之中.这样一来,你可以给一个方法添加一些行为,然后将方法调用传递给原始对象.相对于创建子类来说,使用装饰者对象是一种更灵活的选择(装 ...

  3. 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式

    装饰者模式是JDK中还有一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源代码,也是为了学习大牛们的设计思路.--- ...

  4. HeadFirst设计模式读书笔记(3)-装饰者模式(Decorator Pattern)

    装饰者模式:动态地将责任附件到对象上.若要扩展功能,装饰者提东了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型 你可以用一个或者多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超 ...

  5. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  6. 设计模式学习心得<装饰器模式 Decorator>

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  7. 设计模式のDecoratorPattern(装饰器模式)----结构模式

    一.产生背景 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  8. 设计模式C++实现——装饰者模式

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/walkerkalr/article/details/28633123 模式定义:         装 ...

  9. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  10. 《Head First 设计模式》之装饰者模式

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5922248.html 模式名称 装饰者模式(Decorator Pattern) 需求 定义咖啡厅中的 ...

随机推荐

  1. sqlalchemy映射数据库

    from sqlalchemy import create_engine,Column,Integer,String from sqlalchemy.ext.declarative import de ...

  2. idea导入eclipse的web项目

    idea导入eclipse的web项目 一.导入自己的web项目      步骤:File->New->Project from Existing Source... 二.选择项目的所在位 ...

  3. git 添加第二个远程仓库地址,一次修改到处上传~

    上传本机git 公钥到对应的代码托管平台 github/码云等 本地仓库执行 git remote set-url --add origin https://gitee.com/qichengTech ...

  4. [转帖]开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 https://www.geek-workshop.com/thread-1860-1-1.html     liamj ...

  5. 在Ubuntu上安装Spark

    1.下载spark2.4.3 使用用户的hadoop的版本,解压并放到/usr/local下并改名为spark目录 2.设置spark目录为本用户所有 3.设置环境变量 (1)#~/.bashrc e ...

  6. vue cli3项目发布在apache www/vue目录下并配置history路由

    注意:vue项目打包后默认是指向服务器的根路径(比如apache默认www目录是根路径,当然也可以修改),这种情况不需要做路径的配置,只需要做history配置,如果不是发布到根路径而是www/vue ...

  7. php和java语法区别

    Java和PHP的基本语法基本相同,其实大部分的语言的基本语法也都相同,但是他们还是有一些细微的区别: 1.PHP是一种脚本语言,代码在服务器上执行,而结果以纯文本返回浏览器. 2.PHP能够运行在各 ...

  8. 客户端相关知识学习(二)之h5与原生app交互的原理

    前言 现在移动端 web 应用,很多时候都需要与原生 app 进行交互.沟通(运行在 webview中),比如微信的 jssdk,通过 window.wx 对象调用一些原生 app 的功能.所以,这次 ...

  9. 数据绑定-@ CookieValue

    测试:

  10. 前端页面多级联动传输数据类型问题(数组or字符串)后端处理

    在最近的工作中,遇到一个问题,个人所做的简历模块中有两个字段,分别是个人信息中的户口所在地和现居住城市. 前端界面中这两个选项框是用到了二级和三级联动,在向后端传输时希望可以通过数组类型进行传输,例如 ...