设计模式:装饰者模式

news2025/1/20 1:38:38

目录

一、定义

二、场景

三、例子

四、优缺点

        优点:

        缺点:


一、定义

        在不改变已有对象结构的情况下,动态添加新的功能到对象上,是继承的一种替代方案。属于结构型模式。

二、场景

        1.扩展一个类的功能,添加附加职责,但不改变原有结构。

        2.给一个对象动态添加或删除功能。

        3.无法使用子类进行扩展时,这有两种情况:一是功能的排列组合非常多,可能产生大量的子类;另一种是无法派生子类。

三、例子

刚好点了一杯瑞幸到了,就以此为例。

定义一个咖啡接口(抽象组件)

public interface Coffee {
    /**
     * 描述
     * @return
     */
    String info();

    /**
     * 价格
     * @return
     */
    double price();
}

创建一个拿铁(具体组件)

public class Latte implements Coffee {
    @Override
    public String info() {
        return "生椰丝绒拿铁";
    }

    @Override
    public double price() {
        return 21;
    }
}

然后创建一个咖啡装饰器(抽象装饰器)

public abstract class CoffeeDecorator implements Coffee {

    private Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public String info() {
        return this.coffee.info();
    }

    @Override
    public double price() {
        return this.coffee.price();
    }
}

下面创建2个具体装饰器:加糖、加奶油

public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    public String info() {
        return super.info() + " 加糖";
    }

    @Override
    public double price() {
        return super.price() + 1;
    }
}
public class CreamDecorator extends CoffeeDecorator{
    public CreamDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String info() {
        return super.info() + " 加奶油";
    }

    @Override
    public double price() {
        return super.price() + 3;
    }
}

好了,下面用一个测试类测试一下

public class Test {
    public static void main(String[] args) {
        Coffee coffee = new Latte();
        Coffee sugarCoffee = new SugarDecorator(coffee);
        Coffee creamCoffee = new CreamDecorator(sugarCoffee);

        System.out.println(creamCoffee.info() + ": " + creamCoffee.price());
    }
}

// 输出如下
// 生椰丝绒拿铁 加糖 加奶油: 25.0

看下类图:

四、优缺点

        优点:

                1.动态扩展,比继承灵活

                2.装饰类之间不同的排列组合实现不同的功能,可避免子类爆炸性增长

                3.符合开闭原则

        缺点:

                1.增加程序复杂性,对程序设计人员有着更高的要求

                2.增加代码复杂性,使维护更困难

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

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

相关文章

Python如何传递任意数量的实参及什么是返回值

Python如何传递任意数量的实参 传递任意数量的实参 形参前加一个 * ,Python会创建一个已形参为名的空元组,将所有收到的值都放到这个元组中: def make_pizza(*toppings):print("\nMaking a pizza with the following toppings: "…

【部署】预处理和后处理加速方案:CVCuda

预处理 和 后处理加速方案大概可以包括以下几种 (1)nvidia开源的CVCuda (2)使用opencv4的cuda加速模块 (3)手写cuda算子 这一章我们先从CVCuda开始 一.基本要求 1.1 何时可以使用CVcuda库 在模型的 预…

SpringBoot_02

Web后端开发_07 SpringBoot_02 SpringBoot原理 1.配置优先级 1.1配置 SpringBoot中支持三种格式的配置文件: application.propertiesapplication.ymlapplication.yaml properties、yaml、yml三种配置文件,优先级最高的是properties 配置文件优先级…

【前端开发】每一位高级Web工程师都应该掌握的10个Web API!

Photo by Hisu lee on Unsplash JavaScript中的某些API的使用率可能相对较低。下面我们将逐一介绍它们的使用和使用场景。 Blob API Blob API用于处理二进制数据,可以轻松地将数据转换为Blob对象或从Blob对象读取数据。 // Create a Blob object const myBlob …

【Vulnhub 靶场】【hacksudo: FOG】【简单 - 中等】【20210514】

1、环境介绍 靶场介绍:https://www.vulnhub.com/entry/hacksudo-fog,697/ 靶场下载:https://download.vulnhub.com/hacksudo/hacksudo-FOG.zip 靶场难度:简单 - 中等 发布日期:2021年05月14日 文件大小:1.3 GB 靶场作…

Centos7 制作Openssh9.5 RPM包

Centos7 制作Openssh9.5 RPM包 最近都在升级Openssh版本到9.3.在博客里也放了openssh 9.5的rpm包. 详见:https://blog.csdn.net/qq_29974229/article/details/133878576 但还是有小伙伴不停追问这个rpm包是怎么做的,怕下载别人的rpm包里被加了盐. 于是做了个关于怎么用官方的o…

15.(vue3.x+vite)组件间通信方式之默认插槽(匿名插槽)

前端技术社区总目录(订阅之前请先查看该博客) 示例效果 默认插槽(匿名插槽) 插槽 slot 通常用于两个父子组件之间,最常见的应用就是我们使用一些 UI 组件库中的弹窗组件时,弹窗组件的内容是可以让我们自定义的,这就是使用了插槽的原理。 (1)slot 是 Vue中的内置标签…

vmware ubuntu22 访问github

1.虚拟机选NAT模式。 2.firefox找到下图setting。 3.选第四个,填主机ip和局域网代理的端口号。 4. 此时你应该能访问github了。

JAVA 线程池,及7大参数,4大拒绝策略详解

为什么要使用线程池 线程的生命周期:运行、就绪、运行、阻塞、死亡 下面是一个简单的创建多线程的方法。注意:工作中不可取。 创建线程的时候,我们避不开线程的生命周期。上面的方法虽然可以创建多线程,但是创建完成后&#xff0c…

设计一个简易版本的分布式任务调度系统

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理🔥如果感觉博主的文章还不错的话&#xff…

【Math】高斯分布的乘积 Product of Guassian Distribution【附带Python实现】

【Math】高斯分布的乘积 Product of Guassian Distribution【附带Python实现】 文章目录 【Math】高斯分布的乘积 Product of Guassian Distribution【附带Python实现】1.推导2. CodeReference 结果先放在前面 1.推导 在学习PEARL算法的时候,encoder的设计涉及到了…

读书笔记-《数据结构与算法》-摘要3[选择排序]

选择排序 核心:不断地选择剩余元素中的最小者。 找到数组中最小元素并将其和数组第一个元素交换位置。在剩下的元素中找到最小元素并将其与数组第二个元素交换,直至整个数组排序。 性质: 比较次数(N-1)(N-2)(N-3)…21~N^2/2交换次数N运行…

jquery 判断是手机端还是电脑端

判断为手机端: var sUserAgent navigator.userAgent.toLowerCase(); var bIsIpad sUserAgent.match(/ipad/i) "ipad"; var bIsIphoneOs sUserAgent.match(/iphone os/i) "iphone os"; var bIsMidp sUserAgent.match(/midp/i) "mid…

Navicat在分辨率不同的屏幕窗口显示大小不一致问题解决

1.主屏幕为2560*1600分辨率,能够显示较多数据连接 2.在第二屏幕分辨率低,字体变大,显示内容变少 解决办法: 1.右击navicat图标-属性 2.选择【兼容性】-在兼容性页面中选择**“更改高DPI设置”** 3…勾选“高DPI缩放替代”&a…

chown和chmod

chown和chmod都是在Linux和Unix系统中用于设置文件和文件夹权限的命令,但它们的功能和用途有所不同。 功能:chown主要用于修改文件或文件夹的所有者和所属组,而chmod则主要用于修改文件或文件夹的读写执行权限。用途:如果想要授权…

GD32F103*固件库移植FreeRTOS详细教程与解析

GD32F103*固件库移植FreeRTOS详细教程与解析 GD32F103*移植μCOS-Ⅲ详细教程与解析,欢迎指正 文章目录 GD32F103*固件库移植FreeRTOS详细教程与解析前言一、移植前的准备二、移植步骤1.文件结构2.添加代码3.编译与配置 三、注意事项总结 前言 FreeRTOS是一个可以基…

力扣973. 最接近原点的 K 个点(java 排序法,大顶堆法)

Problem: 973. 最接近原点的 K 个点 文章目录 题目描述思路解题方法复杂度Code 题目描述 给定一个数组 points ,其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。 这里,平面…

.NET微信网页开发相关文章教程

前言 今天我们主要总结一下.NET微信网页开发的相关文章教程。 微信网页开发详细文档可以看微信官方文档:背景 | 微信开放文档 全面的.NET微信网页开发之JS-SDK使用步骤、配置信息和接口请求签名生成详解 微信官方文档对于accessToken和jsapi_ticket生成的示例代码…

智能优化算法应用:基于类电磁机制算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于类电磁机制算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于类电磁机制算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.类电磁机制算法4.实验参数设定5.算法结果…

最全Web前端校招面试真题合集(附答案)

历时半年,我们整理了这份市面上最全面的前端校招面试题解析大全。 包含了腾讯、字节跳动、百度、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目。希望对大家参加前端校招有所帮助吧! HTML 浏览器页面有哪三层构成&…