装饰着模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。

在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !

目录

1.简介 2.什么是装饰器设计模式 3.实施装饰器设计模式 4.何时使用装饰设计模式 5. Java中的装饰器设计模式 6.下载源代码

1.简介

要了解装饰器设计模式,让我们帮助比萨公司制作一个额外的打顶计算器。 用户可以要求向披萨添加额外的配料,而我们的工作是使用该系统添加配料并提高价格。

这就像在运行时为我们的披萨对象增加了额外的责任,Decorator Design Pattern适合这种要求。 但是在此之前,让我们进一步了解这种美丽的图案。

2.什么是装饰器设计模式

装饰器设计模式的目的是动态地将附加职责附加到对象上。 装饰器为子类提供了灵活的替代方案,以扩展功能。

装饰器模式用于动态扩展对象的功能,而无需更改原始类的源或使用继承。 这是通过在实际对象周围创建一个称为Decorator的对象包装来完成的。

Decorator对象被设计为具有与基础对象相同的接口。 这允许客户端对象与Decorator对象进行交互,方式与与基础实际对象进行交互的方式完全相同。 Decorator对象包含对实际对象的引用。 Decorator对象接收来自客户端的所有请求(调用)。 反过来,它将这些调用转发到基础对象。 Decorator对象在将请求转发到基础对象之前或之后添加了一些其他功能。 这样可以确保可以在运行时从外部将附加功能添加到给定对象,而无需修改其结构。

装饰器可防止子类的泛滥,从而减少复杂性和混乱。 添加功能的任意组合都很容易。 相同的功能甚至可以添加两次。 对于给定的对象,可以同时具有不同的装饰器对象。 客户端可以通过将消息发送到适当的装饰器来选择所需的功能。

图1-类图

零件

  • 为可以动态添加职责的对象定义接口。

混凝土构件

  • 定义可以附加其他职责的对象。

装饰器

  • 维护对Component对象的引用,并定义一个符合Component接口的接口。

混凝土装饰工

  • 向组件添加责任。

3.实施装饰器设计模式

为简单起见,让我们创建一个仅包含两种方法的简单Pizza接口。

package com.javacodegeeks.patterns.decoratorpattern;public interface Pizza {public String getDesc();public double getPrice();
}

getDesc方法用于获取披萨的说明,而getPrice用于获取价格。

以下是两个具体的Pizza类:

package com.javacodegeeks.patterns.decoratorpattern;public class SimplyVegPizza implements Pizza{@Overridepublic String getDesc() {return "SimplyVegPizza (230)";}@Overridepublic double getPrice() {return 230;}}
package com.javacodegeeks.patterns.decoratorpattern;public class SimplyNonVegPizza implements Pizza{@Overridepublic String getDesc() {return "SimplyNonVegPizza (350)";}@Overridepublic double getPrice() {return 350;}}

装饰器包装需要增加功能的对象,因此需要实现相同的接口。 下面是一个抽象的装饰器类,它将由所有具体的装饰器扩展。

package com.javacodegeeks.patterns.decoratorpattern;public abstract class PizzaDecorator implements Pizza {@Overridepublic String getDesc() {return "Toppings";}}

以下是具体的装饰器类。

package com.javacodegeeks.patterns.decoratorpattern;public class Broccoli extends PizzaDecorator{private final Pizza pizza;public Broccoli(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Broccoli (9.25)";}@Overridepublic double getPrice() {return pizza.getPrice()+9.25;}}
package com.javacodegeeks.patterns.decoratorpattern;public class Cheese extends PizzaDecorator{private final Pizza pizza;public Cheese(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Cheese (20.72)";}@Overridepublic double getPrice() {return pizza.getPrice()+20.72;}}
package com.javacodegeeks.patterns.decoratorpattern;public class Chicken extends PizzaDecorator{private final Pizza pizza;public Chicken(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Chicken (12.75)";}@Overridepublic double getPrice() {return pizza.getPrice()+12.75;}}
package com.javacodegeeks.patterns.decoratorpattern;public class FetaCheese extends PizzaDecorator{private final Pizza pizza;public FetaCheese(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Feta Cheese (25.88)";}@Overridepublic double getPrice() {return pizza.getPrice()+25.88;}}
package com.javacodegeeks.patterns.decoratorpattern;public class GreenOlives extends PizzaDecorator{private final Pizza pizza;public GreenOlives(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Green Olives (5.47)";}@Overridepublic double getPrice() {return pizza.getPrice()+5.47;}}
package com.javacodegeeks.patterns.decoratorpattern;public class Ham extends PizzaDecorator{private final Pizza pizza;public Ham(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Ham (18.12)";}@Overridepublic double getPrice() {return pizza.getPrice()+18.12;}}
package com.javacodegeeks.patterns.decoratorpattern;public class Meat extends PizzaDecorator{private final Pizza pizza;public Meat(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Meat (14.25)";}@Overridepublic double getPrice() {return pizza.getPrice()+14.25;}}
package com.javacodegeeks.patterns.decoratorpattern;public class RedOnions extends PizzaDecorator{private final Pizza pizza;public RedOnions(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Red Onions (3.75)";}@Overridepublic double getPrice() {return pizza.getPrice()+3.75;}}
package com.javacodegeeks.patterns.decoratorpattern;public class RomaTomatoes extends PizzaDecorator{private final Pizza pizza;public RomaTomatoes(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Roma Tomatoes (5.20)";}@Overridepublic double getPrice() {return pizza.getPrice()+5.20;}}
package com.javacodegeeks.patterns.decoratorpattern;public class Spinach extends PizzaDecorator{private final Pizza pizza;public Spinach(Pizza pizza){this.pizza = pizza;}@Overridepublic String getDesc() {return pizza.getDesc()+", Spinach (7.92)";}@Overridepublic double getPrice() {return pizza.getPrice()+7.92;}}

我们需要用这些浇头装饰披萨对象。 上面的类包含对需要装饰的披萨对象的引用。 装饰器对象在调用装饰器的函数后将其功能添加到装饰器。

package com.javacodegeeks.patterns.decoratorpattern;import java.text.DecimalFormat;public class TestDecoratorPattern {public static void main(String[] args) {DecimalFormat dformat = new DecimalFormat("#.##");Pizza pizza = new SimplyVegPizza();pizza = new RomaTomatoes(pizza);pizza = new GreenOlives(pizza);pizza = new Spinach(pizza);System.out.println("Desc: "+pizza.getDesc());System.out.println("Price: "+dformat.format(pizza.getPrice()));pizza = new SimplyNonVegPizza();pizza = new Meat(pizza);pizza = new Cheese(pizza);pizza = new Cheese(pizza);pizza = new Ham(pizza);System.out.println("Desc: "+pizza.getDesc());System.out.println("Price: "+dformat.format(pizza.getPrice()));}}

上面的代码将产生以下输出:

Desc: SimplyVegPizza (230), Roma Tomatoes (5.20), Green Olives (5.47), Spinach (7.92)
Price: 248.59
Desc: SimplyNonVegPizza (350), Meat (14.25), Cheese (20.72), Cheese (20.72), Ham (18.12)
Price: 423.81

在上面的类中,我们首先创建了SimplyVegPizza ,然后用RomaTomatoesGreenOlivesSpinach装饰它。 输出中的desc显示添加在SimplyVegPizza中的浇头,且价格为所有价格的总和。

我们对SimplyNonVegPizza做了同样的事情,并在SimplyNonVegPizza添加了不同的SimplyNonVegPizza 。 请注意,您可以为一个对象多次装饰同一件事。 在上面的示例中,我们两次添加了cheese ; 价格也增加了两倍,可以在输出中看到。

当您需要在运行时为对象添加额外功能并对其进行修改时,Decorator设计模式看起来不错。 但这会导致很多小物体。 使用Decorator的设计通常会导致系统由许多看起来相似的小对象组成。 对象的区别仅在于它们的互连方式不同,不在于它们的类或变量的值。 尽管这些系统很容易被了解它们的人定制,但它们可能很难学习和调试。

4.何时使用装饰设计模式

在以下情况下,请使用Decorator模式:

  • 动态透明地向单个对象添加职责,即不影响其他对象。
  • 对于可以撤销的责任。
  • 当通过子类扩展不可行时。 有时可能会有大量独立的扩展,并且会产生大量的子类来支持每种组合。 或者,类定义可能是隐藏的,或者子类无法使用。

5. Java中的装饰器设计模式

  • java.io.BufferedInputStream(InputStream)
  • java.io.DataInputStream(InputStream)
  • java.io.BufferedOutputStream(OutputStream)
  • java.util.zip.ZipOutputStream(OutputStream)
  • java.util.Collections#checked[List|Map|Set|SortedSet|SortedMap]()

6.下载源代码

这是关于装饰设计模式的课程。

您可以在此处下载相关的源代码: DecoratorPattern-Project

翻译自: https://www.javacodegeeks.com/2015/09/decorator-design-pattern.html

装饰着模式示例

装饰着模式示例_装饰器设计模式示例相关推荐

  1. 设计模式示例_责任链设计模式示例

    设计模式示例 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此重要的原因 ...

  2. 访客模式 无痕模式 区别_访客设计模式示例

    访客模式 无痕模式 区别 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如 ...

  3. 单例模式示例_单例设计模式示例

    单例模式示例 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此重要的原因 ...

  4. 抽象工厂和工厂方法示例_工厂方法设计模式示例

    抽象工厂和工厂方法示例 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此 ...

  5. 抽象工厂和工厂方法示例_抽象工厂设计模式示例

    抽象工厂和工厂方法示例 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此 ...

  6. java 设计模式 示例_Java中的中介器设计模式-示例教程

    java 设计模式 示例 中介者模式是行为设计模式之一 ,因此它处理对象的行为. 中介器设计模式用于在系统中不同对象之间提供集中式通信介质. 根据GoF,中介者模式意图是: 通过封装不同对象集相互交互 ...

  7. Java中的中介器设计模式-示例教程

    中介者模式是行为设计模式之一 ,因此它处理对象的行为. 中介器设计模式用于在系统中不同对象之间提供集中式通信介质. 根据GoF,中介者模式意图是: 通过封装不同对象集相互交互和通信的方式,允许松散耦合 ...

  8. 装饰者模式 php,php装饰者模式简单应用案例分析

    本文实例讲述了php装饰者模式简单应用.分享给大家供大家参考,具体如下: 装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的 ...

  9. python创建模式对象_【python设计模式-创建型】单例模式

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自己的对 ...

最新文章

  1. Idea terminal:不是内部或外部命令,也不是可行的程序或批处理文件
  2. C# Combobox联动
  3. 数据结构基础:树结构的学习笔记
  4. 一起开心2020暑假训练第一周
  5. 前端学习(1998)vue之电商管理系统电商系统之实现步骤条和tab栏的数据
  6. vue3数据绑定显示列表数据局
  7. opencv roberts算子_图像之HOG特征描述算子-行人检测
  8. java 难度_java中难度大一点的面试题
  9. redis 值字符串前面部分乱码_Spring-RedisTemplate写入数据乱码问题的复现与解决
  10. php重定向在header头加参数,php的header重定向的域名参数后边可以加路由吗?
  11. mysql日志监控 zabbix_zabbix日常监控项mysql(七)
  12. [转载] python接口测试:封装get和post请求+重新封装requests类
  13. 在windows下添加php的Imagick扩展
  14. 怎么看作业部落的html,HTML问题汇总
  15. Windows系统下查询本机IP地址和MAC地址
  16. Android 设备在Play Store无法搜索下载Netflix软件
  17. 目标框选之单阶段与两阶段目标检测区别
  18. 利用pyecharts绘制新浪微博传播图(文末附完整代码地址)
  19. PSI成长之路_配置并成功运行
  20. 【分布式版本控制系统Git】| Git 分支操作、Git 团队协作机制、GitHub 操作

热门文章

  1. nssl1519-背包签到题【数论】
  2. P1993-小K的农场【差分约束,SPFA】
  3. nssl1211-好文章【字符串hash,map】
  4. SpringCloud Greenwich(六)集成dubbo与openfeign的feignTargeter报错,cannot access its superinterface Targeter
  5. Spark入门(十五)之分组求最小值
  6. 乐观锁的一种实现方式——CAS
  7. 204787 ,194787 |0001 1131 0001 4226 7035 ![2480 ]
  8. springmvc中报错Request processing failed;
  9. 新闻发布项目——分页公共类(PageUitl )
  10. 264. 丑数 II---LeetCode---JAVA(动态规划)