Hello,即将要写的这篇文章,是对刚刚学习完的装饰者模式的一个总结啦,也不是什么技术难点,就是巩固一下啦。

一.装饰者模式的定义

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

只看定义真的有些不明白,先简单说明一下,下面还有例子呢。

(1)定义中提到了继承,看来装饰者模式是来解决扩展功能时使用继承的不足的;

(2)可以做到运行时装饰类,给对象赋予新的职责。

(3)还是看下面的例子吧。

二.实例--饮品店

饮品店里有,饮品--咖啡、果汁、茶类,饮品中可以加不同的配料--摩卡、牛奶、糖、奶泡;不同的饮品加上不同的配料有不同的价钱,怎样实现呢?

方式一:单纯的继承

最突出的缺点--造成类爆炸(组合的种类太多);

方式二:使用装饰者模式

1.装饰者模式的组成:抽象组件(Beverage)、具体组件(Coffee、Tea等)、抽象装饰者(IngredientDecorator)、具体装饰者(Mocha、Milk等),以例子说明的关系图如下:

2.代码示例:

抽象组件--超类--Beverage:

public abstract class Beverage {

//description实例变量表示不同的描述,由子类赋值使用

String description = "Uknown Beverage";

public String getDescription() {

return description;

}

//抽象方法,由子类实现

public abstract double cost();

}

具体组件--B_Coffee、B_FruitJuice等:public class B_Coffee extends Beverage{

/**

* 在构造器中设置饮料的描述

*/

public B_Coffee(){

description = Description.COFFEE;

}

/**

* 实现父类--抽象组件中的抽象方法

* 计算该饮料的价钱

*/

public double cost() {

return Cost.COFFEE;

}

}public class B_FruitJuice extends Beverage{

public B_FruitJuice(){

description = Description.FRUIT_JUICE;

}

public double cost() {

return Cost.FRUIT_JUICE;

}

}

抽象装饰者--IngredientDecorator:/**

* 继承的目的是为了IngredientDecorator能够取代Beverage

* @author wangzhaoli

*

*/

public abstract class IngredientDecorator extends Beverage{

/**

* IngredientDecorator中覆盖父类中的getDescription()方法

* 继承IngredientDecorator的所有观察者需各自实现

*/

public abstract String getDescription();

}

具体装饰者们--C_Mocha、C_Milk等:/**

* C_Mocha是一个装饰者

* C_Mocha继承的CondimentDecorator

* CondimentDecorator继承了Beverage

* @author wangzhaoli

*

*/

public class C_Mocha extends IngredientDecorator{

/**

* 要让C_Mocha能够引用一个Beverage,做法是:

* 1.用一个实例变量记录Beverage,也就是被装饰者;

* 2.想办法让Beverage被记录到实例变量中,即构造器参数实例化。

*/

private Beverage beverage;

public C_Mocha(Beverage beverage){

this.beverage = beverage;

}

/**

* 实现父类CondimentDecorator中的抽象方法

*/

public String getDescription() {

//利用委托的方法得到之前的描述

return beverage.getDescription() + "," + Description.MOCHA;

}

/**

* 实现父类的父类Beverage中的抽象方法

*/

public double cost() {

return beverage.cost() + Cost.MOCHA;

}

}public class C_Milk  extends IngredientDecorator{

private Beverage beverage;

public C_Milk(Beverage beverage){

this.beverage = beverage;

}

public String getDescription() {

return beverage.getDescription() + "," + Description.MILK;

}

public double cost() {

return beverage.cost() + Cost.MILK;

}

}

测试类--main:public class MainTest {

public static void main(String[] args) {

Beverage fruitJuice = new B_FruitJuice();

System.out.println(fruitJuice.getDescription()+":"+fruitJuice.cost());

System.out.println();

Beverage coffee = new B_Coffee();

coffee = new C_Mocha(new C_Mocha(new C_Suger(coffee)));

System.out.println(coffee.getDescription()+":"+coffee.cost());

System.out.println();

Beverage tea = new B_Tea();

tea = new C_Mocha(tea);

tea = new C_Milk(tea);

tea = new C_Suger(tea);

tea = new C_Form(tea);

System.out.println(tea.getDescription()+":"+tea.cost());

System.out.println();

}

}

测试结果:Fruit Juice:8.0

Coffee,Suger,Mocha,Mocha:9.5

Tea,Mocha,Milk,Suger,Form:9.5

二.由实例说明装饰者模式

1.装饰者模式中很好的体现了组合(composition)和委托(delegation):

(1)利用继承设计子类的行为是在编译时静态决定的,利用组合的做法扩展对象的行为可以在运                    行时动态的进行扩展;

(2)利用继承达到"类型匹配",而不是获得"行为",新的行为是由"组合对象"得来的;

(3)利用组合和委托可以实现在运行时具有继承的效果;

2.装饰者模式完全遵循"开放--关闭原则":类应该对扩展开放,对修改关闭。

3.以例子说明装饰者的使用:

拿一个咖啡对象,用摩卡装饰它,再用牛奶装饰它,然后调用cost()方法,并依赖委托                     (delegate)将各种配料的价格加上去。

4.每个具体的组件都可以单独使用,或者被装饰者包装起来动态的加上新行为使用;

5.装饰者与抽象组件是"有一个"的关系,所以需要在每一个具体装饰者中定义一个实例变量以保存

某个具体组件的引用;

6.装饰者的新行为是指:通过在旧行为前面/后面加上一些计算、拼接等处理;

7.装饰者和被装饰者对象有相同的超类型;

8.可以用一个或多个装饰者包装一个对象;

9.装饰者可以所委托被装饰者的行为之前/之后,加上自己的行为,以达到指定的目的;

java 装饰者_Java装饰者模式相关推荐

  1. java 装饰器_JAVA装饰器模式

    Java程序员们应该对java.io对不会陌生,因为java.io包采用了装饰器模式. 一.定义: Decorator装饰器,顾名思义,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样 ...

  2. java 装饰者_java装饰者模式怎么用?

    1.使用说明 (1)装饰者模式可以带来比继承更加灵活的扩展功能,使用更加方法,可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果.装饰者模式比继承更具良好的扩展性,完美的遵循开闭原则,继 ...

  3. java 装饰流_java装饰流的使用【转】

    装饰流使用 除了按照流的方向可以把流划分为输入流和输出流两类,按照流读写数据的基本单位把流划分为字节流和字符流两类以外,还可以按照流是否直接连接实际数据源,例如文件.网络.字节数组等,将流又可以划分为 ...

  4. java设计模式建造_Java设计模式——建造模式(Builder Pattern)

    Builder模式常用例子 今天就简单粗暴的介绍一下Builder模式概念和使用. Dialog的创建 AlertDialog dialog = new AlertDialog.Builder(thi ...

  5. java中组合_java中组合模式详解和使用方法

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...

  6. java创建型_Java创建型模式

    Java创建型模式 在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象.基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度.创建型模式通过以某种方式控制 ...

  7. java输出不同颜色_Java设计模式-策略模式、状态模式

    推荐阅读: 一只Tom猫:都是"Redis惹的祸",害我差点挂在美团三面,真是"虚惊一场"! java喵:6大面试技能树:JAVA基础+JVM+算法+数据库+计 ...

  8. java控制灯_Java使用桥接模式实现开关和电灯照明功能详解

    本文实例讲述了Java使用桥接模式实现开关和电灯照明功能.分享给大家供大家参考,具体如下: 一.模式定义 桥接模式,也称桥梁模式,在软件系统中,由于自身的逻辑,具有两个或多个维度的变化,如何应对这种多 ...

  9. java设计模式建造_java设计模式-建造者模式

    建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创造不同的表示. 建造者模式将一个产品的内部表象和产品的生成过程分割开来,建造对象的时候只需要指定需要建造的类型,而不必了解具体的 ...

最新文章

  1. jetty9请求form表单太小限制
  2. jittor自定义矩阵乘法(图解矩阵乘法)
  3. Win7下安装配置PHP+Apache+Mysql+PHPMyAdmin环境教程(非集成)
  4. 2018 年度 GtiHub 开源项目 TOP 25:数据科学 机器学习
  5. Go进阶(4): string接口函数+时间接口函数+内置函数+错误处理
  6. 十一、深入Java的判断语句
  7. PHP面向对象之旅:抽象类继承抽象类(转)
  8. Proxy(代理)--对象结构型模式
  9. [LeetCode-JAVA] Remove Linked List Elements
  10. HTML,CSS的class与id命名规则
  11. LeetCode 684. 冗余连接(并查集)
  12. 基因表达热图聚类并增加行列注释
  13. Latex插入图片并固定图片位置
  14. 测试文档模板_学会word2007创建自定义模板的方法,让你新建的文档结构都一致...
  15. Java电子书下载地址
  16. 中国慢病管理行业市场形势调查分析及价值研究报告2021-2027年版
  17. #多个基因批量cox 多因素回归cox univariate Adjust for age sex单个基因cox 回归分析 多因素 矫正年龄性别之后的cox回归分析 矫正年龄性别之后的cox生存分析
  18. 曾经的王者,如今被遗忘的 Android 开发!
  19. codevs 4939 欧拉函数
  20. Go 限流器 limter

热门文章

  1. 微信小程序跳转页面传参是出现错误Unexpected end of JSON inpu
  2. 前端实现tts(文字转语音)
  3. 01分数规划c语言,POJ 1330(LCA/倍增法模板)
  4. 心舞服务器维护中,《阴阳师》手游5月19日维护更新公告
  5. switch的四种散热方法分享
  6. php提取字符串substr,php字符串截取substr函数简介
  7. PR 2019 快速入门(10)
  8. matlab如何定义一个序列,EXCEL中如何创建自定义序列 看完你就知道了
  9. 九龙证券|避险情绪升温,黄金上破2000大关,概念股逆市大涨
  10. 什么是YUI?YUI简介