装饰着模式示例_装饰器设计模式示例

装饰着模式示例

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

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

目录

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

1.简介

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

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

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

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

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

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

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

decorator_design_pattern_class_diagram_1

图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

装饰着模式示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

强烈推荐!10个超赞的C语言开源项目

关注星标,每天学习C语言新技能因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源:网络今天给大家分享10个超赞的C语言开源项目,希望这些内容能对大家有所帮助!01WebbenchWebbench是一个在 L…

以外的文件 删除_原来C盘还可以删除这五个文件,难怪电脑越来越卡!

马上就要年底了,大家肯定都是欢欢喜喜准备过年,将家里变得焕然一新。韩博士也捯饬好大包小包打算风风火火赶回家,结果刚打开电脑,哦豁,立马卡到爆炸。想着都年底了,这电脑还打算给我搞出什么幺蛾子&#xf…

设计模式示例_复合设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

给大家收集了一些C语言代码优化的方法!

关注星标,每天学习C语言新技能因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源:网络在本篇文章中,我收集了很多经验和方法。应用这些经验和方法,可以帮助我们从执行速度和内存使用等方面来…

设计模式示例_介体设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

清空list_还在为邮箱爆掉而烦恼吗?学会清空你的收件箱

less is more | 越不繁,越不凡还在为邮箱爆掉而烦恼吗?学会清空你的收件箱我一般只用Gmail收发邮件,而且处理邮件已经成为日常工作的核心之一。我每个小时能收到大量邮件,并且快速回复。但是,有一件事要特别提一下&…

这才是B站的正确打开方式!

关注星标,每天学习C语言新技能因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源:网络每天都在用B站刷杂七杂八的视频,有没有考虑过挖掘一些优质UP主?想要发掘优质UP主,靠B站官方…

pcl_openmap_OpenMap教程–第1部分

pcl_openmap介绍 本系列教程将向您展示如何使用OpenMap GIS Java Swing库构建Java应用程序。 OpenMap的开发人员指南是非常有用的文档,描述了OpenMap的体系结构,但没有说明如何逐步启动和构建应用程序。 源代码附带的示例很有用,但还不够。 …

网页编程从入门到精通 杨凡_干货 | web前端入门基础知识

一名合格的web前端工程师必须得掌握HTML、CSS和JavaScript。只懂其中一个或两个还不行,你必须对这三门语言都很熟悉。也不是说必须对这三门语言都非常精通,但你至少要能够运用它们完成大多数任务,而无需地频繁地寻求别人的帮助。今天给大家分…

100 个网络基础知识

关注星标,每天学习C语言新技能因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源:网络1)什么是链接?链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。2)OSI 参考模型的层次…

策略模式示例代码_策略设计模式示例

策略模式示例代码本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 &am…

加白名单_Android保活从入门到放弃:乖乖引导用户加白名单吧

1、引言IM在Android上的保活问题经常在即时通讯网的论坛和技术群里被讨论,自从Android 8.0后系统大大降低了后台运行应用的保活容忍度(详见《Android P正式版即将到来:后台应用保活、消息推送的真正噩梦》),保活从黑科技横行的时代进入了技术…

子模板继承父模板示例_模板设计模式示例

子模板继承父模板示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看…

10个超赞的C语言开源项目!

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删今天分享10个超赞的C语言开源项目,希望这些内容能对大家有所帮助!目录:1. Webbench2. Tinyhttpd3. cJSON4. C…

jboss eap 7_使用JBoss EAP 7的HTTP / 2

jboss eap 7就在几天前,新的JBoss EAP 7 ALPHA版本已经发布。 而且我已经写过博客,介绍如何开始使用它 。 一个非常有趣的部分是HTTP / 2支持,它已作为技术预览添加。 它由新的Web服务器Untertow提供。 HTTP / 2通过压缩头并在同一TCP连接上多…

Modern C++ 最核心的变化是什么?

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删个人觉得最核心的变化是右值引用的引入,右值引用是 C 走向现代化的最重要一步。建议每一位 C 开发者都应该深入去了解并充分使用它。…

设计模式示例_命令设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

第一个C语言编译器是怎样编写的

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删不知道你有没有想过,某种编程语言的第一个编译器是怎么来的呢?这不就是“鸡生蛋,蛋生鸡”的问题吗&#xff1…

备忘录模式 命令模式_备忘录设计模式示例

备忘录模式 命令模式本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 …

还在分析我写的 bug 啊,我都是随便写的!

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删还在分析我写的 bug 啊,我都是随便写的!客户就是可以为所欲为,怎么地!下面教大家如何对付产品经理…