Java设计模式之装饰者设计模式Decorator Pattern

2023-11-20


目录

一、基本概念

二、结构

1.图示

三、案例演示

被装饰对象的基类     一个接口  有cost()和description()两个抽象方法

具体被装饰的对象     实现上面这个接口

装饰者抽象类  (基类)  实现drink接口

具体的装饰者类    ------  糖

具体装饰者类   ----  黑豆

测试

结果:

四、设计原则

总结

一、基本概念

装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

运用场景

装饰者模式的应用场景:在不改变原有类结构的基础上,新增,限制,或者改造功能。

动态地将功能附加到对象身上。扩展功能,装饰者提供了比继承更有弹性的替代方案,可以防止类爆炸。

二、结构

1.图示

这是一张很经典的图:

Component:被装饰对象的基类   

定义对象的接口,可以给这些对象动态的添加职责。

ConcreteComponent:具体被装饰的对象

定义具体的对象,Decorator可以给它增加额外的功能

Decorator:装饰者抽象类

维护指向Component实例的引用,定义Component一致的接口

ConcreteDecorator 具体装饰者

具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责

三、案例演示

被装饰对象的基类     一个接口  有cost()和description()两个抽象方法

public interface Drink {
    float cost();//价格
    String description();// 描述
}

具体被装饰的对象     实现上面这个接口

package com.example.lib4;
/**
 * 被装饰的类
 * 豆浆
 * @author lzy
 * @deprecated
 * */
public class SoyaBeanMilk implements Drink{
    @Override
    public float cost() {
        return 10f;
    }

    @Override
    public String description() {
        return "纯豆浆";
    }
}

装饰者抽象类  (基类)  实现drink接口

public abstract class Decorator implements Drink {
    private Drink drink;
    public  Decorator(Drink drink){
        this.drink = drink;
    }

    @Override
    public float cost() {
        return drink.cost();
    }

    @Override
    public String description() {
        return drink.description();
    }
}

具体的装饰者类    ------  糖

public class SugarDecorator extends Decorator{
    public SugarDecorator(Drink drink) {
        super(drink);
    }

    @Override
    public float cost() {
        return super.cost()+1.0f;
    }

    @Override
    public String description() {
        return super.description()+"糖";
    }
}

具体装饰者类   ----  黑豆

public class BlacbeanDecorator extends Decorator{
    public BlacbeanDecorator(Drink drink) {
        super(drink);
    }

    @Override
    public float cost() {
        return super.cost()+2.0f;
    }

    @Override
    public String description() {
        return super.description()+"黑豆";
    }
}

测试


public class test {
    public static void main(String[] args) {
        Drink drink = new SoyaBeanMilk();  //纯豆浆(被装饰)    cost()  10f  description 纯豆浆
        SugarDecorator sugar = new SugarDecorator(drink);  //装饰者   继承Decorator        cost() +1.f   description  糖
        BlacbeanDecorator blackbean = new BlacbeanDecorator(sugar);//装饰者
        System.out.println("你点的豆浆是"+blackbean.description());
        System.out.println("花了"+blackbean.cost());
        /**
         * Decorator  装饰者抽象类    传入drink对象  然后重写cost()    description()方法
         *
         * 对类理解的不是很继承 抽象类 理解不是很好
         * */
    }
}

结果:

 这个案例的背景是      豆浆有很多口味的豆浆 ,有加糖的,加黑豆的 ,纯豆浆,又加糖又加黑豆的,等等 ,如果采用继承来添加这些功能,那可能子类太多了,类爆炸,不利于开发。所以采用设计者模式来代替类的继承。

再加一个小例子

File file = new File("D:\\io\\lzy1.txt");
        OutputStream out = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(out);
        DataOutputStream dos = new DataOutputStream(bos);

是不是很熟悉,其实已经在不知不觉已经使用过装饰者设计模式了。

四、设计原则

要使用装饰者模式,需要满足以下设计原则:

(1)封装变化多

(2)用组合,少用继承

(3).针对接口编程,不针对实现编程

(4)开放-关闭原则:类应该对扩展开放,对修改关闭

(5)为交互对象之间的松耦合设计而努力


总结

优点:

(1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性

(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难

tip:这个例子来源于Java之io的学习整理

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java设计模式之装饰者设计模式Decorator Pattern 的相关文章

  • 读取文件并获取 key=value 而不使用 java.util.Properties

    我正在构建一个 RMI 游戏 客户端将加载一个包含一些键和值的文件 这些键和值将用于多个不同的对象 它是一个保存游戏文件 但我不能为此使用 java util Properties 它符合规范 我必须读取整个文件并忽略注释行和与某些类不相关
  • 如何以编程方式找出我的 PermGen 空间使用情况?

    我正在尝试诊断java lang OutOfMemoryError PermGen Space在 Sun 的 Hotspot JVM 上运行时出现错误 并且想知道我的程序在不同时刻使用了多少 PermGen 空间 有没有办法以编程方式找出这
  • 如何使用 Java 将 HTML 内容转换为 PDF 而不丢失格式?

    我有一些 HTML 内容 包括格式化标签 例如strong 图像等 在我的 Java 代码中 我想将此 HTML 内容转换为 PDF 文档 而不丢失 HTML 格式 有没有办法用 Java 来实现 使用 iText 或任何其他库 I use
  • 在 Tomcat 上部署 Java Web 项目,无需 WAR 或 EAR

    我有一个 Java Web 项目 Struts Spring 在我的本地主机上完美运行 我必须将其部署在我的网站上 但虚拟主机提供的 Tomcat Manager 界面显示 由于安全原因 它无法上传 WAR 文件 当联系技术支持时 我被告知
  • 如何在Mac上使用eclipse安装jetty

    我是一个新手 jetty 和 RESTful API 我想使用 Jetty 创建 REST 服务 并希望将嵌入式 jetty 与 eclipse 一起使用 任何人都可以建议我在 Mac OS 中使用 Eclipse 安装 Jetty Jet
  • WebLogic 10 中的临时目录

    每当 WL 停止时 它都不会删除其临时目录 即 domains mydomain servers myserver tmp WL TEMP APP DOWNLOADS domains mydomain servers myserver tm
  • JAX-WS:有状态 WS 在独立进程中失败

    我在 Tomcat 上部署了一个有状态的 Web 服务 它由工厂服务和主要 API 服务组成 并且工作得很好 工厂服务将 W3CEndpointReference 返回到主 API 实例 客户端使用会话 现在 我尝试将相同的服务作为独立应用
  • 代码编译期间遇到警告消息“使用或覆盖已弃用的 API”

    我编译了我的程序并收到以下错误 我该如何解决呢 Note ClientThreadClients java uses or overrides a deprecated API Note Recompile with Xlint depre
  • 动画图像视图

    目前我正在开发一款游戏 这是我的游戏的详细信息 用户应选择正确的图像对象 我希望图像从左到右加速 当他们到达终点时 他们应该再次出现在活动中 这是我正在处理的屏幕截图 我有 5 个图像视图 它们应该会加速 您有此类动画的示例代码吗 非常感谢
  • FFmpeg 不适用于 android 10,直接进入 onFailure(String message) 并显示空消息

    我在我的一个项目中使用 FFmpeg 进行视频压缩 在 Android 10 Google Pixel 3a 上 对于发送执行的任何命令 它会直接进入 onFailure String message 并显示空消息 所以我在我的应用程序 g
  • 通过 JNI 从 Applet 调用 DLL

    我有一个 概念验证 的作品 它跨越了一些不熟悉的领域 我的任务是将 EFTPOS 机器连接到在内联网浏览器中作为小程序运行的应用程序 我暂时忽略了 EFTPOS dll 并用我选择的语言 Delphi 创建了一个简单的 JNI 修饰的 DL
  • 用于防止滥用的 Servlet 过滤器? (DoS、垃圾邮件等)

    我正在寻找一个 Servlet 过滤器库 它可以帮助我保护我们的 Web 服务免受未经授权的使用和 DDoS 攻击 我们的网络服务有 授权客户 因此理想情况下 过滤器将帮助检测未经授权或行为不当的客户 或检测使用同一帐户的多个人 此外 我们
  • MessageDigest MD5 算法未返回我期望的结果

    我脑后的某个东西告诉我 我在这里遗漏了一些明显的东西 我正在将现有的 java 项目与第三方 api 集成 该第三方 api 使用 api 密钥的 md5 哈希进行身份验证 它对我不起作用 在调试过程中我意识到我生成的哈希值与他们提供的示例
  • 如何将txt文件添加到你的android项目中? [复制]

    这个问题在这里已经有答案了 我的Android studio版本是1 5 1 显然这个 never 版本没有 txt 文件的 asset 文件夹 您打算如何将这些文件包含到您的项目中 以及如何进一步使用您内部的应用程序 谢谢你的建议 Pro
  • 如何获取 Android 中临时文件的文件大小?

    如果我使用 openFileOutput 创建并写入临时文件 写入完成后如何获取文件大小 我希望这可以帮助你 File file new File selectedPath int file size Integer parseInt St
  • XSLT:我们可以使用abs值吗?

    我想知道在 XSLT 中我们是否可以使用 math abs 我在某处看到过这个 但它不起作用 我有类似的东西
  • C++ 中的 Java ArrayList [重复]

    这个问题在这里已经有答案了 在Java中我可以做 List
  • 如何使用 Hibernate Session.doWork(...) 进行保存点/嵌套事务?

    我正在使用 JavaEE JPA 托管事务与 Oracle DB 和 Hibernate 并且需要实现某种嵌套事务 据我所知 此类事情不受开箱即用的支持 但我应该能够为此目的使用保存点 正如建议的https stackoverflow co
  • 设计抽象类时是否应该考虑序列化问题?

    一般来说这个问题来自Eclipse建议在抽象类上添加串行版本UID 由于该类是抽象类 因此该类的实例永远不会存在 因此它们永远不会被序列化 只有派生类才会被序列化 所以我的问题是放置一个安全 SuppressWarnings serial
  • Java中的媒体播放器库[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在评估用于在 Java 中播放音频 视频的库 它不需要 100 Java Java 与本机库的绑定

随机推荐

  • 洛谷P1010 [NOIP1998 普及组] 幂次方

    文章目录 前言 题目描述 输入格式 输出格式 样例 1 样例输入 1 样例输出 1 数据范围 代码 解析 结尾 前言 在做完洛谷P1010 NOIP1998 普及组 幂次方这道题之后 我对于现在的学习有了些许认识 题目描述 任何一个正整数都
  • 如何处理低概率出现的bug???

    原文链接 一般的低概率bug 不足以导致系统崩溃的bug 方案1 仔细检查是否是自己的执行步骤 或者误操作导致的bug 提交给相关人员 方案2 通过日志相关信息处理 提交相关开发人员 方案3 通过截图方式尽量复现当时的情景 方案4 和相关测
  • Java 中使用 protobuf

    主要参考 Java 中使用 protobuf 入门基础篇 看这篇就够了 https blog csdn net wxw1997a article details 116755542 Java 中使用 protobuf 复杂深入篇 看这篇就够
  • 成都瀚网科技有限公司:抖音怎么绑定抖音小店才好?

    抖音是一款非常流行的短视频应用 为用户提供了一个展示才华 分享生活的平台 在抖音上 用户可以通过绑定抖音商店来销售自己的产品或服务 从而实现商业变现 那么 抖音如何绑定抖音商店呢 1 抖音如何绑定抖音商店 用户绑定抖音商店需要按照以下步骤操
  • PCIe专题学习——3.2(数据链路层Ack/Nak机制解析)

    之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍 了解了PCIe是一种封装分层协议 packet based layered protocol 主要包括事务层 Transaction layer 数据链路层 Data link lay
  • 数据挖掘计算题-1

    一 设某事务项集构成如下表 填空完成表1中支持度和置信度的计算 1 12 15分 表1 支持度与置信度 事务ID 项集 L2 支持度 规则 置信度 T1 A D A B 1 A B 7 T2 D E A C 2 C A 8 T3 A C E
  • JavaScript 中的 `this` 指向问题与其在加密中的应用

    JS中的 this 关键字是一个非常重要的概念 它在不同情况下会指向不同的对象或值 在本文中 我们将深入探讨 JavaScript 中 this 的各种情况 并思考如何将其应用于 JS加密中的一些有趣用途 1 全局上下文中的 this 在全
  • 安卓逆向之去除app游戏入口广告

    安卓逆向学习群692903341 首先来看一下app游戏入口界面广告 lt
  • Python轻量级Web框架Flask(1)——简介/虚拟环境介绍/安装

    1 Redis简介 1 数据库分类 关系型数据库 MySQL Oracle 非关系型数据库 Redis MongoDB 2 介绍 Redis是一个开源 高级的键值存储和一个适用的解决方案 用于构建高性能 可扩展的Web应用程序 3 特点 R
  • BUUCTF [极客大挑战 2019] Http

    BUUCTF 极客大挑战 2019 Http 启动环境 主页为三叶草技术小组纳新 查看网页源码 发现隐藏的页面 div class image img src images pic01 jpg alt div div class conte
  • HTML--后台管理系统

    后台管理系统
  • [网络安全自学篇] 八十七.恶意代码检测技术详解及总结

    这是作者网络安全自学教程系列 主要是关于安全工具和实践操作的在线笔记 特分享出来与博友们学习 希望您喜欢 一起进步 前文分享了威胁情报分析 通过Python抓取FreeBuf网站 APT 主题的相关文章 这篇文章将详细总结恶意代码检测技术
  • 【SpringMVC】参数传递与用户请求和响应

    目录 一 Postman 工具使用 1 1 Postman安装 1 2 Postman的使用 1 2 1 创建WorkSpace工作空间 1 2 2 创建请求 二 参数传递 2 1 添加 Slf4j 依赖 2 2 普通传参 知识点1 Req
  • js formatDate 时间转换

    formatDate function time fmt type type 类型 0 时间为秒 1 时间为毫秒 var date new Date type 0 time 1000 time var o M date getMonth 1
  • ltconfig: you must&nbs…

    在64位机器下编译libghttp碰到的问题 libghttp是gnome下的HTTP客户端库 实现http功能 可以替换curl 的http功能 在32位的机器上编译没问题 在64位的机器上 configure 不过去 错误信息是 ltc
  • vue+C#后台上传excel处理数据

    比较简洁的excel处理方法 希望对大家有所帮助 1 界面
  • POJ - 2325 Persistent Numbers

    The multiplicative persistence of a number is defined by Neil Sloane Neil J A Sloane in The Persistence of a Number publ
  • angular:ng add “@nguniversal/express-engine“提示Data path ““ must NOT have additional properties

    出现原因 未知 只知道有个项目能成功 拷贝这个项目uninstall后再次ng add也能成功 而其他项目无法成功 提示这个 解决办法 手动添加相关代码 一样能够运行 ssr
  • 《零基础入门学习Python》第061讲:论一只爬虫的自我修养9:异常处理

    高级语言的一个有些特性就是它可以从容不迫的处理每一个遇到的错误 不至于说遇到一个小错误就导致整个程序崩溃了 大部分高级语言处理错误的方法都是通过检测异常 处理异常来实现的 Python也是一样 用程序用代码进行互联网访问的时候 会出现异常是
  • Java设计模式之装饰者设计模式Decorator Pattern

    目录 一 基本概念 二 结构 1 图示 三 案例演示 被装饰对象的基类 一个接口 有cost 和description 两个抽象方法 具体被装饰的对象 实现上面这个接口 装饰者抽象类 基类 实现drink接口 具体的装饰者类 糖 具体装饰者