1. 定义

使用装饰者模式可以在运行时动态地扩充一个类的功能,它提供了比继承更具弹性的代替方案。

在装饰模式中的角色有:

  1. **抽象构件(Component)角色:**给出一个抽象接口,以规范准备接收附加责任的对象。
  2. **具体构件(ConcreteComponent)角色:**定义一个将要接收附加责任的类。
  3. **装饰(Decorator)角色:**持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  4. **具体装饰(ConcreteDecorator)角色:**负责给构件对象「贴上」附加的责任。

2. 实现

下面就以买豆浆为例,实现一个装饰者模式。在买豆浆时,我们可以选择原味的,然后再添加红豆、绿豆等原料,从而磨出多种口味的豆浆。那么,这个添加的原料就属于对原味豆浆的扩展,所以使用装饰者模式再好不过了。

  1. 定义抽象构件角色,即豆浆和原料共同的接口。
public interface IMilk {/*** 描述** @return*/String getDescription();/*** 价格** @return*/double cost();
}复制代码
  1. 定义具体构件角色,即被装饰的原味豆浆。
public class SoybeanMilk implements IMilk {@Overridepublic String getDescription() {return "原味";}@Overridepublic double cost() {return 2;}
}复制代码
  1. 定义装饰角色,用来加入豆浆的原料。
public abstract class MilkAddition implements IMilk {protected IMilk milk;public MilkAddition(IMilk milk){this.milk = milk;}
}复制代码
  1. 定义具体装饰角色,即加入的不同原料。
public class RedBeanAddition extends MilkAddition {public RedBeanAddition(IMilk milk) {super(milk);}@Overridepublic String getDescription() {return milk.getDescription() + " + 红豆";}@Overridepublic double cost() {return milk.cost() + 3;}
}public class MungBeanAddition extends MilkAddition {public MungBeanAddition(IMilk milk) {super(milk);}@Overridepublic String getDescription() {return milk.getDescription() + " + 绿豆";}@Overridepublic double cost() {return milk.cost() + 2;}
}public class SugarAddition extends MilkAddition {public SugarAddition(IMilk milk) {super(milk);}@Overridepublic String getDescription() {return milk.getDescription() + " + 糖";}@Overridepublic double cost() {return milk.cost() + 0.5;}
}复制代码

测试:

        // 原味豆浆,两块钱IMilk milk = new SoybeanMilk();// 加糖,五毛钱milk = new SugarAddition(milk);// 加红豆,三块钱milk = new RedBeanAddition(milk);// 加绿豆,两块钱milk = new MungBeanAddition(milk);System.out.println("喝到的豆浆:" + milk.getDescription() + ", 价格:" + milk.cost() + "元");// 输出:喝到的豆浆:原味 + 糖 + 红豆 + 绿豆, 价格:7.5元复制代码

3. 应用

  • 优点:

    1. 装饰者模式与继承关系的目的都是要扩展对象的功能,但是装饰者可以提供比继承更多的灵活性。
    2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
    3. 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,原有类库代码无须改变,符合「开闭原则」。
  • 缺点:

    1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性,使用时更容易出错。
    2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 使用场景:

    1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
    2. 当不能采用继承的方式对系统进行扩展,或者采用继承不利于系统扩展和维护时,可以使用装饰模式。

Java IO 模块使用了不少装饰者模式,比如我们经常会这么写:

new DataInputStream(new BufferedInputStream(new FileInputStream("README.md")));复制代码

起初学习 IO 部分的时候就是一头雾水,心想怎么会包装这么多层,谁记得住这么多代码。现在来看,不过是装饰者模式的应用罢了,这就是进步吧。^_^

转载于:https://juejin.im/post/5c938ff3e51d4502ce53e771

Android 设计模式 - 装饰者模式相关推荐

  1. Python设计模式-装饰器模式

    Python设计模式-装饰器模式 代码基于3.5.2,代码如下; #coding:utf-8 #装饰器模式class Beverage():name = ""price = 0.0 ...

  2. [Head First设计模式]山西面馆中的设计模式——装饰者模式

    原文:[Head First设计模式]山西面馆中的设计模式--装饰者模式 引言 在山西面馆吃鸡蛋面的时候突然想起装饰者这个模式,觉得面馆这个场景跟书中的星巴兹咖啡的场景很像,边吃边思考装饰者模式.这里 ...

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

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

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

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

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

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

  6. 读书笔记---Head First 设计模式--- 装饰者模式

    读书笔记-Head First 设计模式- 装饰者模式 装饰者模式(Decorator Pattern) 装饰者模式--动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. ...

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

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

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

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

  9. Spring设计模式(装饰器模式)

    Spring设计模式(装饰器模式) 模式的定义: 装饰者模式定义: ​ 动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案. 模式的结构图 : 模式包含角 ...

最新文章

  1. pygame简单的俄罗斯方块游戏和简单的打字游戏
  2. ORA-07445 [kkoipt()+3881] [SIGSEGV] [Address not mapped to object] 问题
  3. Java时间对比------实际时间和设置时间对比
  4. php 比较,PHP类型比较
  5. ios开发 UITableView with xib 以及自定义TableViewCell
  6. 最大乘积|贪心算法|FOJ1698|TYVJ3024
  7. 30 个 Pandas技巧,加速你的数据分析处理速度!
  8. SAP Spartacus里modifiedtime的大小写问题
  9. 奥的斯服务器状态显示,奥的斯电梯调试服务器(俗称st)按键介绍
  10. JS中Date.parse()和Date.UTC()返回值不一致
  11. 智能化连锁门店解决方案
  12. matlab struct 结构体
  13. 【车间调度】基于matlab模拟退火算法求解车间调度(jobshop-3)问题【含Matlab源码 1082期】
  14. translator什么意思中文_translator是什么意思|translator的音标|translator的用法 - 英语词典...
  15. 一起读slam论文之PTAM-Parallel Tracking and Mapping for Small AR Workspace
  16. tp6 阿里云短信接口 php
  17. 谷歌浏览器任务栏图标变白解决办法
  18. excel sumif 多条件
  19. 2022陈箫箫胡程灿信息论课程作业 MIMO信道(multi-input multi-output,MIMO)简介
  20. ICPC北美中部赛区资格赛总结

热门文章

  1. input限制输入小数点后两位(vue版本)
  2. iscsi网络存储介绍及客户端配置操作
  3. Node.JS 学习路线图
  4. A English version for my blog start.
  5. 淘宝商品库MySQL优化实践的学习
  6. Sybase数据库中找回丢失的sa密码
  7. Cisco IOS防火墙的安全规则和配置方案
  8. java--HashMap与Hashtable的区别
  9. JVM调优:GC 参数
  10. 用 SpringBoot,亲自打造一个在线题库系统