装饰者模式

设计模式——装饰模式 装饰模式是一种用来替代继承的思想,它使用对象之间的关联关系来取代类之间的继承关系。继承是一种常用的一种拓展原有类的功能的方法,通过创建一个继承父类的子类来拓展原有的功能,在“合成复用原则”中曾提到,在处理类的功能拓展这个问题上应尽量使用类之间的关联关系而少使用继承关系。为什么要用这个模式:以对客户透明的方式动态地给一个对象附加上更多的责任,装饰模式可以在不需要创造更多的子类的情况下,将对象的功能加... 阅读详情

咖啡订单项目:

​ 咖啡种类:Espresso、ShortBlack、LongBlack、Decaf
​
 调料:Mike、Soy、Chocolate
​
 要求:在拓展新咖啡种类时,具有较好的扩展性、改动方便、维护方便

​ 使用OO的方式计算不同种类的费用,可有单点,也可单点+调料组合

方案1:

​ 在这里插入图片描述
​   Drink:抽象类,表示饮料

​     description:对咖啡的描述,不然咖啡的名字

​     cost():计算费用,由具体实现类实现。

​ 问题:

​   该设计需要许多类,当增加一个新种类或者新调料时,则需要增加更多的类,易导致类爆炸。

 

方案二:

​在这里插入图片描述

​   将配料作为饮料的属性,则减少了许多类的产生

​   但在增加或者删除种类,代码的维护量很大。

 

装饰者模式

  允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。动态地将新功能附加在对象上。

装饰模式结构

在这里插入图片描述
  1.部件 (Component) 声明封装器和被封装对象的公用接口。
  2.具体部件 (Concrete Component) 类是被封装对象所属的类。 它定义了基础行为, 但装饰类可以改变这些行为。
  3.基础装饰 (Base Decorator) 类拥有一个指向被封装对象的引用成员变量。 该变量的类型应当被声明为通用部件接口, 这样它就可以引用具体的部件和装饰。 装饰基类会将所有操作委派给被封装的对象。
  4.具体装饰类 (Concrete Decorators)定义了可动态添加到部件的额外行为。 具体装饰类会重写装饰基类的方法, 并在调用父类方法之前或之后进行额外的行为。
  5.客户端 (Client) 可以使用多层装饰来封装部件, 只要它能使用通用接口与所有对象互动即可。
 

装饰模式适合应用场景

  1.如果你希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为, 可以使用装饰模式。

  2.如果用继承来扩展对象行为的方案难以实现或者根本不可行, 你可以使用该模式。
 

实现方式

  1.确保业务逻辑可用一个基本组件及多个额外可选层次表示。

  2.找出基本组件和可选层次的通用方法。 创建一个组件接口并在其中声明这些方法。

  3.创建一个具体组件类, 并定义其基础行为。

  4.创建装饰基类, 使用一个成员变量存储指向被封装对象的引用。 该成员变量必须被声明为组件接口类型, 从而能在运行时连接具体组件和装饰。 装饰基类必须将所有工作委派给被封装的对象。

  5.确保所有类实现组件接口。

  6.将装饰基类扩展为具体装饰。 具体装饰必须在调用父类方法 (总是委派给被封装对象) 之前或之后执行自身的行为。

  7.客户端代码负责创建装饰并将其组合成客户端所需的形式。
 

装饰模式优缺点

  优点:
    ✔️​你无需创建新子类即可扩展对象的行为。
    ✔️​你可以在运行时添加或删除对象的功能。
    ✔️​你可以用多个装饰封装对象来组合几种行为。
    ✔️​单一职责原则。 你可以将实现了许多不同行为的一个大类拆分为多个较小的类。
  缺点:
    ❌在封装器栈中删除特定封装器比较困难。
    ❌实现行为不受装饰栈顺序影响的装饰比较困难。
    ❌各层的初始化配置代码看上去可能会很糟糕。

 

更改后的咖啡订单

​在这里插入图片描述

装饰者模式下如何表示:2份巧克力+1份牛奶的LongBlack

​chocolate->chocolate->Milk->LongBlack

采用递归的方式来组成。便可以组成任意的单品咖啡+调料组合

代码:

public abstract class Drink {
    public String des;//描述
    private float price =0.0F;

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    //由子类完成
    public abstract float cost();
}
public class Coffee extends Drink {
    @Override
    public float cost() {
        return super.getPrice();
    }
}

public class Espresso extends Coffee {
    public Espresso(){
        setDes("意大利咖啡");
        setPrice(6.0F);
    }
}

public class LongBlack extends Coffee {
    public LongBlack(){
        setDes("LongBlack");
        setPrice(5.0F);
    }
}

public class DeCaf  extends Coffee{
    public DeCaf(){
        setDes("无因咖啡");
        setPrice(1.0f);
    }
}
public class Decorator extends Drink{
    private Drink drink;

    //组合
    public Decorator(Drink drink) {
        this.drink = drink;
    }

    public float cost(){
        //super.Price == 自己的价格
        return super.getPrice()+drink.cost();
    }

    @Override
    public String getDes() {
        return des+" "+":"+getPrice()+"+"+drink.getDes();
    }
    
}
public class Chocolate extends Decorator {
    public Chocolate(Drink drink) {
        super(drink);
        setDes("巧克力");
        setPrice(3.0f);
    }
}

public class Milk extends Decorator {
    public Milk(Drink drink) {
        super(drink);
        setDes("牛奶");
        setPrice(2.0f);
    }
}

public class Soy extends Decorator {
    public Soy(Drink drink) {
        super(drink);
        setDes("豆浆");
        setPrice(1.5f);
    }
}
public class CofferBar {
    public static void main(String[] args) {
        //2份巧克力+1份牛奶的 LongBlack

        //LongBlack
        Drink drink = new LongBlack();
        System.out.println("目前情况"+drink.getDes());
        System.out.println("花费+"+drink.cost());

        //+Milk
        drink = new Milk(drink);


        System.out.println("目前情况"+drink.getDes());
        System.out.println("花费+"+drink.cost());

        //+2份巧克力
        for (int i = 0; i < 2; i++) {
            drink = new Chocolate(drink);
        }
        System.out.println("目前情况"+drink.getDes());
        System.out.println("花费+"+drink.cost());

		 /*
            花费+5.0
            目前情况LongBlack
            花费+7.0
            目前情况牛奶 :2.0+LongBlack
            花费+13.0
            目前情况巧克力 :3.0+巧克力 :3.0+牛奶 :2.0+LongBlack
         */
    }
}
京瓷扫描驱动安装_京瓷喷头拆解和供墨原理剖析 在工业喷头打印领域,京瓷喷头作为主流喷头广泛应用于喷墨行业,目前京瓷喷头市面上销售主要有两个系列:KJ4A和KJ4B。其中KJ4A系列设计是用于油性墨水,例如UV墨水,主要用在广告领域;而KJ4B设计用于水性墨水,例如活性、分散墨水等,主要用在数码印花领域。最近我们团队对京瓷喷头进行了拆解分析,本期和大家分享一下我们对京瓷喷头拆解和喷头供墨原理的研究。京瓷喷头介绍1. KJ4A系列(油性)如下图所... 阅读详情

相关推荐

PayPal支付集成完全指南:开源库实践

本文介绍了如何从零开始集成PayPal支付功能。首先概述了PayPal提供的多语言SDK和开源库,包括PHP、Python、Node.js等版本。然后详细说明了准备工作,包括注册开发者账号、获取API凭证和使用沙盒环境测试。文章以Node.js为例,演示了安装SDK、基础配置和实现支付流程的完整代码,包括创建订单和捕获支付两个核心功能。最后提及了订阅支付等高级功能,为开发者提供了完整的支付集成方案。通过清晰的代码示例和步骤说明,帮助开发者快速实现PayPal支付功能集成。

2501_93501927的博客 1259

装饰模式(Decorator模式)详解

在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰模式来实现。 1.装饰模式的定义与特点 装饰(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式...

傅红雪的专栏 6021

从零到一:基于Blazor和Elsa Workflows的工作流系统开发实战

本文详细介绍了如何利用Blazor和Elsa Workflows构建高效的工作流系统,从技术选型到生产环境部署,涵盖动态工作流建模、Blazor前端集成及性能优化等核心内容。通过实战案例,展示如何实现订单处理系统的自动化与灵活性,提升企业流程效率。

weixin_26875109的博客 428

装饰器模式(Decorator Pattern)

装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

FH的博客 1001

CSM中一些常见问题的解决方式

CSM中一些常见问题的解决方式 抖动 摄像机在每帧移动或者旋转时,会产生较严重的抖动问题。

小龙虾的博客 2130

deepin启动异常处理

修复的命令在执行时会输出大量的修复信息,正常情况下修复完之后输入exit命令回车后,即可正常启动系统。

whxxiang的博客 4370

设计模式第7讲——装饰者模式(Decorator)

装饰者模式是一种结构型设计模式。一、什么是装饰者模式 二、角色组成 三、优缺点 四、应用场景 4.1 应用实例 4.2 java实例 五、代码实现5.0 UML类图5.1 Hero(英雄-抽象组件)5.2 BlindMonk(盲僧-具体构件)5.3 SkillDecorator(技能装饰-抽象装饰器)5.4 QDecorator(Q技能-具体装饰器)5.5 WDecorator(W技能-具体装饰器)5.6 EDecorator(E技能-具体装饰器)5.7

让~学习~成为一种习惯(橡 皮 人の技术博客) 6798

清理异常值(MAD:绝对中位差)

清理异常数据: 中位数绝对偏差(MAD):用来描述单变量样本在定量数据中可变的一种标准 在统计学中,绝对中位差是刻画一元数据样本变化的一个鲁棒度量。由公式可以看出,其求解还算简单,给定一个数据样本集,首先求其中位数,然后求原始数据减去中位数的绝对值从而形成一个新的数据样本,再求新的数据样本的中位数即为绝对中位差。比如说有一个数据样本集X={2 3 8 7 9 6 4},这时候数据的中位数是6,原...

spider_man 1万+

23种设计模式——装饰者模式

文章目录23种设计模式——装饰者模式1、装饰者模式概述2、装饰者模式的结构3、装饰者模式的实现4、装饰者模式的应用场景 23种设计模式——装饰者模式 1、装饰者模式概述 背景 有些人为了早上多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框、咖啡加调料等,都是装饰器模式。 装饰者模式的定义 装饰者(Decorator)模式的定义:指在不改

万里顾一程的博客 5291

大津法(OTSU)点云强度信息分割

大津法(OTSU)是一种灰度图像自适应的阈值分割方法,大津法根据图像的灰度分布,将图像分成背景和前景两部分,前景就是需要按照阈值分割出来的部分。由于点云的强度信息的特性,也可以利用此方法进行分类,但需要保证信息干扰较少,例如道路标线分割等场景较为适用。

qq_48694523的博客 965

MFC C++ 中实现跨平台(WindowsLinux)的远程桌面控制

**输入捕获**:在显示窗口中捕获鼠标/键盘事件(重写 `OnLButtonDown`、`OnMouseMove`、`OnKeyDown` 等),将事件坐标/键值通过网络发送到服务端。- **显示窗口**:使用 `CStatic` 或自定义 `CWnd` 派生类显示远程桌面图像(通过 `StretchDIBits` 绘制解压后的像素数据)。// 转换为相对坐标。- **Wayland 支持**:需使用 `libweston` 或 `xdg-desktop-portal`,较复杂,建议优先支持 X11。

寒寒豆豆软件公司的博客 155

23种设计模式之装饰模式

装饰模式是一种用于替代继承的技术,通过无需定义子类的方式动态地增强对象的功能,使用对象间关联关系替代类之间的继承关系。

weixin_45284646的博客 4907

Dify智能体开发:发布嵌入网站

Dify 支持将你的 AI 应用嵌入到业务网站中,你可以使用该能力在几分钟内制作具有业务数据的官网 AI 客服、业务知识问答等应用。点击 WebApp 卡片上的嵌入按钮,复制嵌入代码,粘贴到你网站的目标位置。

王国平的博客 3245

设计模式 —— 装饰者模式

目录 一、星巴克咖啡订单项目需求 二、方案1-解决星巴克咖啡订单项目(较差) 三、方案2-解决星巴克咖啡订单(好点) 四、装饰者模式定义 4.1 装饰者模式原理 4.2 装饰者模式解决星巴克咖啡订单 五、装饰者模式在 JDK 应用的源码分析 装饰者模式定义: 动态给一个对象添加一些额外的职责,就像在墙上刷油漆,使用Decorator 模式相比用生成子类方式达到功能的扩充显得更为灵活。 初计初衷: 通常可以使用继承来实现功能的扩展,如果这些需要扩展的功能的种类很繁多,那么势必...

认知 行动 坚持 6790

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

什么是装饰者模式?

一、 什么是装饰者模式 装饰者模式又称包装模式,是指不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案.属于结构型设计模式. 二、装饰者模式uml图 装饰器其中包含4个角色: 抽象组件(Component): 可以是一个接口或者抽象类,规定了被装饰者的行为. 具体组件(ConcreteComponent): 实现或继承(component)的一个具体对象.也即被装饰者....

weixin_40980639的博客 2369

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

装饰模式

装饰模式 1.介绍 装饰模式,也称为包装模式,结构型设计模式之一,其使用一种对客户端透明的方式来动态地拓展对象的功能,同时它也是继承关系的一种替代方案之一,在现实生活中你也可以看见很多装饰模式的例子。从人来说,人需要各式各样的一桌,不管穿着什么样,但是对于个人的本质来说是不变的,充其量只是在外面披上一层衣物而已,这就是装饰模式,装饰物也许各不相同但是装饰的对象本质是不变的。 2.定义 动态地给一个...

祁门路搅屎王的博客 1478

java设计模式——装饰者模式

目录一、装饰者模式的定义与类型二、装饰者模式的适用场景三、装饰者模式的优点四、装饰者模式的缺点五、装饰者模式相关的设计模式六、普通示例:七、普通示例演进,使用装饰者模式示例: 一、装饰者模式的定义与类型 1、定义 在不改变原有对象的基础之上,将功能附加到对象上 提供了比继承更具有弹性的替代方法(扩展原有对象功能) 2、类型 结构型 二、装饰者模式的适用场景 扩展一个类的功能或给一个类添加附加职责 动态的给一个对象添加功能,这些功能可以在动态的撤销 三、装饰者模式的优点 继承的有力补充,比继承灵

小志的博客 1047
上一篇: 桥接模式的学习
下一篇: 组合模式的学习
code_Floyed
博客等级 码龄7年 3粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值