当前位置: 首页 > news >正文

设计模式总结-装饰者模式

模式动机

一般有两种方式可以实现给一个类或对象增加行为:
继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)。
在这里插入图片描述

装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰模式的模式动机。

模式结构

装饰模式包含如下角色:
Component: 抽象构件
ConcreteComponent: 具体构件
Decorator: 抽象装饰类
ConcreteDecorator: 具体装饰类
在这里插入图片描述

模式分析

与继承关系相比,关联关系的主要优势在于不会破坏类的封装性,而且继承是一种耦合度较大的静态关系,无法在程序运行时动态扩展。在软件开发阶段,关联关系虽然不会比继承关系减少编码量,但是到了软件维护阶段,由于关联关系使系统具有较好的松耦合性,因此使得系统更加容易维护。当然,关联关系的缺点是比继承关系要创建更多的对象。
使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

装饰模式实例与解析

实例一:多重加密系统

某系统提供了一个数据加密功能,可以对字符串进行加密。最简单的加密算法通过对字母进行移位来实现,同时还提供了稍复杂的逆向输出加密,还提供了更为高级的求模加密。用户先使用最简单的加密算法对字符串进行加密,如果觉得还不够可以对加密之后的结果使用其他加密算法进行二次加密,当然也可以进行第三次加密。现使用装饰模式设计该多重加密系统。

在这里插入图片描述

public interface Cipher
{public String encrypt(String plainText);
}public final class SimpleCipher implements Cipher {public String encrypt(String plainText) {String str = "";for (int i = 0; i < plainText.length(); i++) {char c = plainText.charAt(i);if (c >= 'a' && c <= 'z') {c += 6;if (c > 'z') c -= 26;if (c < 'a') c += 26;}if (c >= 'A' && c <= 'Z') {c += 6;if (c > 'Z') c -= 26;if (c < 'A') c += 26;}str += c;}return str;}
}public class CipherDecorator implements Cipher {private Cipher cipher;public CipherDecorator(Cipher cipher) {this.cipher = cipher;}public String encrypt(String plainText) {return cipher.encrypt(plainText);}
}public class ComplexCipher extends CipherDecorator {public ComplexCipher(Cipher cipher) {super(cipher);}public String encrypt(String plainText) {String result = super.encrypt(plainText);result = this.reverse(result);return result;}public String reverse(String text) {String str = "";for (int i = text.length(); i > 0; i--) {str += text.substring(i - 1, i);}return str;}
}public class AdvancedCipher extends CipherDecorator {public AdvancedCipher(Cipher cipher) {super(cipher);}public String encrypt(String plainText) {String result = super.encrypt(plainText);result = mod(result);return result;}public String mod(String text) {String str = "";for (int i = 0; i < text.length(); i++) {String c = String.valueOf(text.charAt(i) % 6);str += c;}return str;}
}
public class Client {public static void main(String args[]) {String password = "sunnyLiu";   String cpassword;        Cipher sc, ac, cc;sc = new SimpleCipher();cpassword = sc.encrypt(password);System.out.println(cpassword);System.out.println("---------------------");cc = new ComplexCipher(sc);cpassword = cc.encrypt(password);System.out.println(cpassword);System.out.println("---------------------");ac = new AdvancedCipher(cc);cpassword = ac.encrypt(password);System.out.println(cpassword);System.out.println("---------------------");}
}

实例二:经典举例咖啡店模式

在这里插入图片描述
(咖啡馆订单项目:1)、咖啡种类:Espresso、ShortBlack、LongBlack、Decaf2)、调料(装饰者):Milk、Soy、Chocolate),类图如上
被装饰的对象和装饰者都继承自同一个超类

public abstract class Drink {public String description="";private float price=0f;;public void setDescription(String description){this.description=description;}public String getDescription(){return description+"-"+this.getPrice();}public float getPrice(){return price;}public void setPrice(float price){this.price=price;}public abstract float cost();}

被装饰的对象,不用去改造。原来怎么样写,现在还是怎么写。

public  class Coffee extends Drink {@Overridepublic float cost() {// TODO Auto-generated method stubreturn super.getPrice();}}

装饰者不仅要考虑自身,还要考虑被它修饰的对象,它是在被修饰的对象上继续添加修饰。例如,咖啡里面加牛奶,再加巧克力。加糖后价格为coffee+milk。再加牛奶价格为coffee+milk+chocolate。

public class Decorator extends Drink {private Drink Obj;public Decorator(Drink Obj) {this.Obj = Obj;};@Overridepublic float cost() {// TODO Auto-generated method stubreturn super.getPrice() + Obj.cost();}@Overridepublic String getDescription() {return super.description + "-" + super.getPrice() + "&&" + Obj.getDescription();}
}

装饰者实例化(加牛奶)。这里面要对被修饰的对象进行实例化。

public class Milk extends Decorator {public Milk(Drink Obj) {          super(Obj);// TODO Auto-generated constructor stubsuper.setDescription("Milk");super.setPrice(2.0f);}
}

coffee店:初始化一个被修饰对象,修饰者实例需要对被修改者实例化,才能对具体的被修饰者进行修饰。

public class CoffeeBar {public static void main(String[] args) {Drink order;order = new Decaf();System.out.println("order1 price:" + order.cost());System.out.println("order1 desc:" + order.getDescription());System.out.println("****************");order = new LongBlack();order = new Milk(order);order = new Chocolate(order);order = new Chocolate(order);System.out.println("order2 price:" + order.cost());System.out.println("order2 desc:" + order.getDescription());}
}

相关文章:

设计模式总结-装饰者模式

模式动机 一般有两种方式可以实现给一个类或对象增加行为&#xff1a; 继承机制&#xff0c;使用继承机制是给现有类添加功能的一种有效途径&#xff0c;通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的&#xff0c;用户不能控制增…...

Stunnel网络加密服务

简介&#xff1a; Stunnel是一个用于创建SSL加密隧道的工具&#xff0c;针对本身无法进行TLS或SSL通信的客户端及服务器&#xff0c;Stunnel 可提供安全的加密连接。可以用于保护服务器之间的通信。您可以在每台服务器上安装Stunnel&#xff0c;并将其配置为在公网上加密传输数…...

算法练习第16天|101. 对称二叉树

101. 对称二叉树 力扣链接https://leetcode.cn/problems/symmetric-tree/description/ 题目描述&#xff1a; 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#x…...

YOLOV8实战教程——最新安装(截至24.4)

前言&#xff1a;YOLOV8更新比较快&#xff0c;最近用的时候发现有些地方已经跟之前不一样&#xff0c;甚至安装都会出现差异&#xff0c;所以做一个最新版的 yolov8 安装教程 一、Github 或者 GitCode 搜索 ultralytics 下载源码包&#xff0c;下载后解压到你需要安装的位置…...

redis zremove删除不掉【bug】

redis zremove删除不掉【bug】 前言版权redis zremove删除不掉错误产生相关资源EldDataEchartsTestDataService 解决 最后 前言 2024-4-12 20:35:21 以下内容源自《【bug】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星…...

对象的本地保存

对象的本地保存 对象的创建和保存 对象的特点&#xff1a; 对象“生活”在内存空间中&#xff0c;因此&#xff0c;程序一旦关闭&#xff0c;这些对象也都会被CLR的垃圾回收机制销毁。程序第二次运行时&#xff0c;对象会以“全新”的状态出现,无法保留上次对象的运行状态。…...

PostgreSQL入门到实战-第二十一弹

PostgreSQL入门到实战 PostgreSQL中表连接操作(五)官网地址PostgreSQL概述PostgreSQL中RIGHT JOIN命令理论PostgreSQL中RIGHT JOIN命令实战更新计划 PostgreSQL中表连接操作(五) 使用PostgreSQL RIGHT JOIN连接两个表&#xff0c;并从右表返回行 官网地址 声明: 由于操作系统…...

李彦宏放话:百度AI大模型绝不抢开发者饭碗

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 昨晚&#xff0c;李彦宏内部讲话称&#xff1a;AI大模型开源意义不大&#xff0c;百度绝不抢开发者饭碗。 但你一定要说话算话哦&#xff0c;可千万别说&#xff1a;“我永远不做手机&#xff0c;谁再敢提做手机就给…...

es 倒排索引

es 倒排索引TRee 倒排索引树&#xff08;TRee&#xff09;通常指的是Elasticsearch中用于支持高速搜索的一种数据结构。它是一种树状结构&#xff0c;可以通过特定的词项&#xff08;terms&#xff09;来快速定位包含这些词项的文档。 在Elasticsearch中&#xff0c;倒排索引…...

阿里云服务器公网带宽费用全解析(不同计费模式)

阿里云服务器公网带宽怎么收费&#xff1f;北京地域服务器按固定带宽计费一个月23元/M&#xff0c;按使用流量计费0.8元/GB&#xff0c;云服务器地域不同实际带宽价格也不同&#xff0c;阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表&#xff1a; 公网…...

python-pytorch实现lstm模型预测文本输出0.1.00

python-pytorch实现lstm模型预测文本输出0.1.00 数据参考效果分词到数组准备数数据查看频次获取vacab生成输入数据训练测试连续预测有问题还需要完善 数据 一篇新闻:https://news.sina.com.cn/c/2024-04-12/doc-inarqiev0222543.shtml 参考 https://blog.csdn.net/qq_1953…...

77、WAF攻防——权限控制代码免杀异或运算变量覆盖混淆加密传参

文章目录 WAF规则webshell免杀变异 WAF规则 函数匹配 工具指纹 webshell免杀变异 php 传参带入 eval可以用assert来替换,assert也可以将字符串当作php代码执行漏洞 php 变量覆盖 php 加密 使用加密算法对php后门进行加密 php 异或运算 简化:无字符webshellP 无数字字母rc…...

A12 STM32_HAL库函数 之 HAL-ETH通用驱动 -- A -- 所有函数的介绍及使用

A12 STM32_HAL库函数 之 HAL-ETH通用驱动 -- A -- 所有函数的介绍及使用 1 通用定时器&#xff08;TIM&#xff09;预览1.1 HAL_ETH_Init1.2 HAL_ETH_DeInit1.3 HAL_ETH_DMATxDescListInit1.4 HAL_ETH_DMARxDescListInit1.5 HAL_ETH_MspInit1.6 HAL_ETH_MspDeInit1.7 HAL_ETH_T…...

Linux从入门到精通 --- 1.初始Linux

文章目录 第一章&#xff1a;1.1 Linux的诞生1.2 Linux系统内核1.3 Linux系统发行版 第一章&#xff1a; 1.1 Linux的诞生 1991年由林纳斯 托瓦兹创立并发展至今称为服务器操作系统领域的核心系统。 1.2 Linux系统内核 Linux内核提供了系统的主要功能&#xff0c;甚至是开源…...

linux使用docker实现redis主从复制和哨兵模式

目录 1. 拉取redis镜像 2.使用可视化redis工具 3. 设置从redis 4.设置哨兵模式 5. 使用docker-compose快速创建 1. 拉取redis镜像 docker pull redis 默认拉取最新的镜像。 然后pull结束后使用docker images检查镜像&#xff1a; 然后docker run创建container容器 首先…...

新版chrome 解决在http协议下无法调用摄像头和麦克风的问题(不安全)

解决办法&#xff1a;亲测可行 chrome浏览器地址栏中输入chrome://flags/#unsafely-treat-insecure-origin-as-secure&#xff0c;回车&#xff0c;如下图&#xff0c;将该选项置为Enabled&#xff0c; edge浏览器打开&#xff1a;edge://flags/#unsafely-treat-insecure-orig…...

机器学习入门项目二(逻辑回归)

如果输入数据长度为2&#xff0c;上一章的方程就无法满足需求了&#xff0c;需要修改方程&#xff1a; z w 1 x w 2 y b zw_1xw_2yb zw1​xw2​yb 数据产生器&#xff1a; import matplotlib.pyplot as plt import numpy as npclass DataGenerator2Input:"""…...

C++类引用的好处

简化代码&#xff1a;引用可以简化代码&#xff0c;使其更加易读和易懂。通过使用引用&#xff0c;可以避免在函数参数中复制大型对象&#xff0c;从而提高代码的效率和性能。 传递大型对象的效率高&#xff1a;使用引用作为函数参数传递大型对象时&#xff0c;不需要进行对象…...

从零自制docker-9-【管道实现run进程和init进程传参】

文章目录 命令行中输入参数长度过长匿名管道从父进程到子进程传参[]*os.File{}os.NewFile和io.ReadAllexe.LookPathsyscall.Execstrings.Split(msgStr, " ")/bin/ls: cannot access : No such file or directory代码 命令行中输入参数长度过长 用户输入参数过长或包…...

全量知识系统 程序详细设计 之 三种“活物” 之1(QA百度搜索 )

Q1. 今天聊聊 全知系统中 三种“活物”。先从他们的一个简单描述开始&#xff1a; 自主&#xff1a;计算机“集群”的“沉”与“浮”&#xff1b; 自然&#xff1a;AI “众生”的“世”和“界” &#xff1b;自由&#xff1a;人类 “公民”的“宇”或“宙”。 全知系统中的三…...

QT 线程之movetothread

上文列举了qt中线程的几种方法&#xff0c;其中2种方法最为常见。 这两种方法都少不了QThread类&#xff0c;前者继承于QThread类&#xff0c;后者复合QThread类。 本文以实例的方式描述了movetothread&#xff08;&#xff09;这种线程的方法&#xff0c;将QObject的子类移动…...

如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示

Ubuntu 22.04 LTS 中使用命令行升级软件或安装任何新软件时&#xff0c;您可能收到“Daemons using outdated libraries”&#xff0c;“Which services should be restarted?”的提示&#xff0c;提示下面列出备选的重启服务&#xff0c;如下。 使用以下命令&#xff0c;能够…...

跟TED演讲学英文:The inside story of ChatGPT‘s astonishing potential by Greg Brockman

The inside story of ChatGPT’s astonishing potential Link: https://www.ted.com/talks/greg_brockman_the_inside_story_of_chatgpt_s_astonishing_potential Speaker: Greg Brockman Date:April 2023 文章目录 The inside story of ChatGPTs astonishing potentialIntro…...

mybatis05:复杂查询:(多对一,一对多)

mybatis05&#xff1a;复杂查询&#xff1a;&#xff08;多对一&#xff0c;一对多&#xff09; 文章目录 mybatis05&#xff1a;复杂查询&#xff1a;&#xff08;多对一&#xff0c;一对多&#xff09;前言&#xff1a;多对一 &#xff1a; 关联 &#xff1a; 使用associatio…...

微电网优化:基于肝癌算法(Liver Cancer algorithm, LCA)的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…...

VUE_H5页面跳转第三方地图导航,兼容微信浏览器

当前项目是uniapp项目&#xff0c;若不是需要替换uni.showActionSheet选择api onMap(address , organName , longitude 0, latitude 0){var ua navigator.userAgent.toLowerCase();var isWeixin ua.indexOf(micromessenger) ! -1;if(isWeixin) {const mapUrl_tx "…...

智慧安全运营:智能化运维,确保服务无忧

智慧安全运营&#xff1a;智能化运维&#xff0c;确保服务无忧 中国联通新一代全球智云数据中心采用先进的智能化运维管理系统&#xff0c;实现对数据中心设施、IT设备、能源消耗、环境参数等全方位、实时监控。通过物联网技术、人工智能算法以及大数据分析&#xff0c;运维团…...

R-tree总结

引言&#xff1a; 在处理空间数据和地理信息系统&#xff08;GIS&#xff09;中&#xff0c;高效的空间索引机制对于提升查询性能至关重要。R-tree是一种流行的平衡树数据结构&#xff0c;专门用于索引多维信息&#xff0c;如二维的地理坐标或三维的物体位置。它以其灵活性、高…...

Python 与机器学习,在服务器使用过程中,常用的 Linux 命令包括哪些?

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 本博客旨在分享在实际开发过程中&#xff0c;开发者需要了解并熟练运用的 Linux 操作系统常用命令。Linux 作为一种操作系统&#xff0c;与 Windows 或 MacOS 并驾齐驱&#xff0c;尤其在服务器和开发环…...

js通过Object.defineProperty实现数据响应式

目录 数据响应式属性描述符propertyResponsive 依赖收集依赖队列寻找依赖 观察器 派发更新Observer完整代码关于数据响应式关于Object.defineProperty的限制 数据响应式 假设我们现在有这么一个页面 <!DOCTYPE html> <html lang"en"><head><m…...

怎么做网站最便宜/如何做个人网站

团队介绍 成员 工作描述 武松桦&#xff08;组长&#xff09; 1 领导团队 召开团队会议 2与需求方进行联系沟通 3页面代码 王亚正 1页面代码 2测试和bug修复 3后端开发 詹元成 1服务器配置和维护 2 页面代码 3 博客撰写 尹宇飞 1页面代码 2美工制作 3博客撰写 张军 …...

做淘宝内部优惠券网站要钱么/百度关键词工具入口

Hello, I’m Shendi 最近小程序要接入微信的内容安全方面 这里记录一下 获取 Token 封装 首先这两个接口都需要使用到 Token 这里我直接贴上代码&#xff0c;其中的参数都是直接追加在 url 上 JSON方面使用的是 fastjson /** * 判断返回的数据是否为错误数据.* param json…...

服装网站建设进度及实施过程/产品seo怎么优化

浮点数的表示和精度如果a>0&#xff0c;那么1a一定大于1吗&#xff1f;在数学上&#xff0c;答案是肯定的。但在计算机上&#xff0c;答案就与a的大小和浮点数的精度有关了。在matalb上&#xff0c;可以作以下计算&#xff1a;>> a1/2^52a 2.220446049250313e-016>…...

wordpress 秀米/深圳seo公司排名

首先我们打开引擎&#xff0c;引擎窗口——文件——新建——55ide客户端——新建一个工程 一般新建在引擎根目录下面的&#xff0c;游戏作品里面。当然&#xff0c;你要放到其他位置&#xff0c;也可以&#xff0c;谁叫你这么叼 这就是进入主程序的界面。 加载&#xff1a;初始…...

wordpress 命令执行时间/营销策划公司介绍

文/黑水泛金波 问题一、套头是不是都很差&#xff1f; 答&#xff1a;不是。肯定不是。 事实上&#xff0c;厂家在决定用什么样的头来作为“套头”、跟机身组成“套机”一起销售的时候&#xff0c;的确就已经先考虑好了、用户最可能需要的镜头会是哪一个。这往往跟机身的“气质…...

哪个网站做长图免费转高清图片/网页设计培训学校

日子一去不复返了HTML用于造型的网页。今天&#xff0c;CSS规则&#xff0c;很难想象没有它的任何网页设计。CSS在最近非常先进&#xff0c;用于创建复杂的Web设计和风格。那么&#xff0c;我们为什么要使用CSS框架&#xff1f;答案很简单。CSS框架主要包括预定义的书库&#x…...