【结构型模式】装饰器模式

​一、装饰器模式概述

        装饰器模式(装饰者模式)定义装饰器模式动态地将责任附加到对象上。若要拓展功能,装饰者提供了比继承更有弹性地替代方案。(对象结构型模型)通俗点来说:动态的给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。

  • 利用继承来达到“类型匹配”
    • 1.装饰者与被装饰对象有相同地超类型;
    • 2.可以用一个或多个装饰者包装一个对象;
    • 3.既然装饰者与被装饰对象有相同地超类型,所以在任何需要原始对象(被包装地)的场合,可以用装饰过的兑现代替它;
    • 4.装饰者可以在所委托被装饰者的行为之前与/之后,加上自己的行为,以达到特定的目的;
    • 5.对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
  •  装饰模式分析
    • 1.可以在不改变一个对象本身功能的基础上给对象增加额外的新行为;
    • 2.是一种用于替代继承的技术,它通过一种无需有定义子类的方式给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系;
    • 3.引入了装饰类,在装饰类中既可以调用装饰的原有类的方法,还可以增加新的方法,以扩展原有类的功能。

        ​透明装饰模式与半透明装饰模式

  • 半透明装饰模式
    • 1.可以给系统带来更多的灵活性,设计相对简单,使用起来也方便;
    • 2.客户端使用具体装饰类型来定义装饰后的对象,因此可以单独调用addedBehavior()方法;
    • 3.最大的缺点在于不能实现对同一个对象的多次装饰,而且客户端需要有区别地对待装饰之前的对象和装饰之后的对象;
    • 4.用具体装饰定义装饰之后的对象,而具体构件使用抽象构件类型来定义;
    • 5.对于客户而言,具体构件类型无须关心,是透明的;但是具体装饰类型必须指定,这并不是透明的。
  • 透明装饰模式
    • 1.要求客户端完全针对抽象编程,装饰模式的透明性要求客户端程序不应该将对象声明为具体构件类型或具体装饰类型,而应该全部声明为抽象构件类型;
    • 2.对客户端而言,具体构件对象和具体装饰对象没有任何区别;
    • 3.可以让客户透明地使用装饰之前地对象和装饰之后地对象,无须关心他们的区别;
    • 4.可以对一个已装饰过地对象进行多次装饰,得到更多复杂、功能更为强大的对象;
    • 5.无法在客户端单独调用新增addedBehavior()方法
  • 适用环境
    • 1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责;
    • 2.当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式

        装饰者模式优缺点

  • 优点
    • 1.对于扩展一个对象功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加;
    • 2.可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为;
    • 3.可以对一个对象进行多次装饰;
    • 4.具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,且原有类库代码无需变化,符合开闭原则。
  • 缺点
    • 1.使用装饰模式进行系统设计时将产生很多小对象,大量对象对象的产生势必会占用更多的系统资源,在一定程度上影响程序的性能;
    • 2.比继承更加易于出错,排错也更困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。

二、代码实现

        结构包含四个角色:

  • 抽象构件(Component)
  • 具体构件(ConcreteComponent)
  • 抽象装饰类(Decorator)
  • 具体装饰类(ConcreteDecorator)
         2.1 星巴兹咖啡

        2.1.1 抽象构件(抽象基类饮料Beverage)
package decorator.dec;
//抽象构件:饮料
public abstract class Beverage {String description = "Unknown Noodle";int size;//小杯TALL、中杯GRANDE、大杯WENTIpublic final static int TALL=1;public final static int GRANDE=2;public final static int WENTI=3;public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}public abstract double cost();
}
        2.1.2 具体构件(基于饮料的咖啡:DarkRoast、Decaf、Espressio、HouseBlend)
package decorator.dec;
//意大利浓咖啡
public class DarkRoast extends Beverage{public DarkRoast() {description = "DarkRoast";}public double cost() {return 3;}
}
package decorator.dec;
//不加咖啡因的咖啡
public class Decaf extends Beverage{public Decaf() {description = "Decaf";}public double cost() {return 2;}
}
package decorator.dec;
//意式浓缩咖啡
public class Espressio extends Beverage{public Espressio() {description = "Espressio";}public double cost() {return 2.5;}
}
package decorator.dec;
//混合咖啡
public class HouseBlend extends Beverage{public HouseBlend() {description = "HouseBlend";}public double cost() {return 1.5;}
}
        2.1.3 抽象装饰类(抽象装饰类CondimentDecorator)
package decorator.dec;
//抽象装饰类:描述->>配料继承父类,附加在父类上
public abstract class CondimentDecorator extends Beverage{Beverage beverage;public abstract String getDescription();
}
        2.1.4 具体装饰类(添加在咖啡上的牛奶milk、抹茶Mocha、豆奶Soy、咖啡的大小Size、搅拌Whip)
package decorator.dec;
//牛奶
public class milk extends CondimentDecorator{public milk(Beverage beverage) {this.beverage=beverage;}public String getDescription() {return beverage.getDescription() + ",Milk";}public double cost() {return 1+beverage.cost();}
}
package decorator.dec;
//抹茶
public class Mocha extends CondimentDecorator {public Mocha(Beverage beverage) {this.beverage=beverage;}@Overridepublic String getDescription() {// TODO 自动生成的方法存根return beverage.getDescription() + ",Mocha";}public double cost() {return 1+beverage.cost();}}
package decorator.dec;
//豆奶
public class Soy extends CondimentDecorator {public Soy(Beverage beverage) {this.beverage=beverage;}@Overridepublic String getDescription() {return beverage.getDescription() + ",Soy";}public double cost() {return 1+beverage.cost();}
}
package decorator.dec;
//大小
public class Size extends CondimentDecorator {public Size(Beverage beverage,int size) {this.beverage = beverage;this.size=size;}@Overridepublic String getDescription() {// TODO 自动生成的方法存根if(size == beverage.TALL) {return beverage.getDescription() + ",小杯";}else if(size == beverage.GRANDE) {return beverage.getDescription() + ",中杯";}else if(size == beverage.WENTI) {return beverage.getDescription() + ",大杯";}return null;}@Overridepublic double cost() {double cost = beverage.cost();if(size == beverage.TALL) {cost += 0.1;}else if(size == beverage.GRANDE) {cost +=0.2;}else if(size == beverage.WENTI) {cost +=0.3;}return cost;}}
package decorator.dec;
//搅拌
public class Whip extends CondimentDecorator {//Noodle beverage;public Whip(Beverage beverage) {this.beverage=beverage;}@Overridepublic String getDescription() {return beverage.getDescription() + ",Whip";}public double cost() {return 1+beverage.cost();}
}
        2.1.5  main方法实现装饰者模式
package decorator.dec;public class Test {public static void main(String[] args) {// TODO 自动生成的方法存根Beverage beverage1 =new Mocha(new milk(new DarkRoast()));System.out.println(beverage1.getDescription()+" 合计$"+beverage1.cost());Beverage beverage2 =new Mocha(new milk(new DarkRoast()));Beverage beverage3 =new Size(new Mocha(new milk(new DarkRoast())),2);Beverage size = new Size(beverage2,2);System.out.println(size.getDescription()+" 合计$"+size.cost());}
}
        2.1.6 UML图

        2.2 窗口显示
        2.2.1 抽象构件(抽象基类:显示构件Component)
package decorator.visualCompanent;
//显示构件
public abstract class Component {public abstract void display();
}
        2.2.2 具体构件(列表框、文本框、窗体)
package decorator.visualCompanent;public class ListBox extends Component {@Overridepublic void display() {// TODO 自动生成的方法存根System.out.println("显示列表框!");}}
package decorator.visualCompanent;public class TextBox extends Component {@Overridepublic void display() {// TODO 自动生成的方法存根System.out.println("显示文本框!");}}
package decorator.visualCompanent;public class Window extends Component {@Overridepublic void display() {// TODO 自动生成的方法存根System.out.println("显示窗体!");}}
         2.2.3 抽象装饰类(ComponentDecorator)
package decorator.visualCompanent;public class ComponentDecorator extends Component{private Component component;//维持对抽象构件类型对象的引用//注入抽象构件类型的对象public ComponentDecorator(Component component) {this.component = component;}public void display() {component.display();}
}
          2.2.4 具体装饰类(增加新的构件:黑色边框和滚动条)
package decorator.visualCompanent;public class BlackBorderDecorator extends ComponentDecorator {public BlackBorderDecorator(Component component) {super(component);}public void display() {// TODO 自动生成的方法存根this.setBlackBorder();super.display();}public void setBlackBorder() {System.out.println("为构件增加黑色边框!");}
}
package decorator.visualCompanent;public class ScrollBarDecorator extends ComponentDecorator {public ScrollBarDecorator(Component component) {super(component);}public void display() {// TODO 自动生成的方法存根this.setScrollBar();super.display();}public void setScrollBar() {System.out.println("为构件增加滚动条!");}}
        2.2.5 main方法实现装饰者模式
package decorator.visualCompanent;public class Client {public static void main(String[] args) {// TODO 自动生成的方法存根//使用抽象构件定义全部对象Component component,componentSB,componentBB;component = new Window(); //创建具体对象//创建装饰后的构件对象componentSB = new ScrollBarDecorator(component);//将装饰了一次的对象componentBB = new BlackBorderDecorator(componentSB);componentBB.display();}}
        2.2.6 UML图

三、代码结构图

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

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

相关文章

淘宝购物更智能:taobao.item_search API接口实现关键字精准匹配

随着电子商务的飞速发展,淘宝作为中国最大的网络购物平台之一,为亿万消费者提供了便捷、丰富的购物体验。然而,在海量商品中快速找到符合自己需求的商品,一直是消费者面临的挑战。为了提升购物体验,淘宝开放平台提供了…

【JS】js数字转k、w结尾 | 1000 = 1k

问题 数字转k、w结尾 如&#xff1a;10001k 100001w 码 /*** 数字转k,w* param {Number} num * returns String*/ const numberTokw num > {if (num < 1000) return numlet endStr w,numVal 10000;if (num > 999 && num < 10000) {endStr knumVal …

使用python socket搭建Client测试平台

目录 概述 1 背景 2 Client功能实现 2.1 何谓Client 2.2 代码功能介绍 2.3 代码实现 2.3.1 代码介绍 2.3.2 代码内容 3 测试 3.1 PC上创建Server 3.2 同一台PC上运行Client 3.2.1 建立连接 3.2.2 测试数据交互 3.3 Linux 环境下运行Client 3.3.1 建立连接 3.3.…

ElasticSearch实战之项目搜索高亮

文章目录 1. 前情配置2、数据操作2.1 操作API2.2 数据入库 3. 高亮搜索3.1 方法封装3.2 高亮搜索 1. 前情配置 为满足ElasticSearch可在项目中实现搜索高亮&#xff0c;我们需要先做一些前情配置 导入ElasticSearch依赖 <dependency><groupId>org.springframewor…

EPSON晶振应用到汽车电子产品上的型号有哪些?

EPSON品牌应用在汽车电子产品上的晶振.&#xff0c;当然也少不了晶振可能最熟悉的就是32.768K系列和26MHZGPS晶振用的多。 在汽车里每一个部件都应有的不一样,甚至多次使用到同一尺寸,不同频率的晶振.爱普生品牌晶振型号就有几百种,很容易混淆,要想记住汽车里所应用到的不是件…

B树(B-tree)

B树(B-tree) B树(B-tree)是一种自平衡的多路查找树&#xff0c;主要用于磁盘或其他直接存取的辅助存储设备 B树能够保持数据有序&#xff0c;并允许在对数时间内完成查找、插入及删除等操作 这种数据结构常被应用在数据库和文件系统的实现上 B树的特点包括&#xff1a; B树为…

学习空间转换-3D转换

1.什么是空间转换&#xff1f; 使用的是transform属性实现元素在空间内的位移&#xff0c;旋转&#xff0c;缩放等效果。 空间&#xff1a;是从坐标轴角度定义的。x,y,z三条坐标轴构成的一个立体空间&#xff0c;Z轴位置与视线方向相同。 所以空间转换也被叫做3D转换 语法&a…

PICkit 3 v3.10中的 Device Family 识别不到芯片

1&#xff1a;现象描述 在使用 PICkit3烧写hex文件的时候&#xff0c;Device Family只有默认芯片&#xff0c;识别不到当前使用的芯片&#xff0c;导致报错“Device Error - hex file not loaded”&#xff0c;我当前使用的是 PIC16F1826芯片&#xff0c;默认不支持&#xff1…

快速开发部署平台Replit

Replit 是可以快速搭建开发、部署环境的平台。能够快速将原型进行部署&#xff0c;代码编辑器支持协同开发&#xff0c;他的在线编辑器做的不错&#xff0c;相当于云上提供了一个 vscode&#xff0c;代码实时更新。Replit 底层是基于容器技术的&#xff0c;可以安全的隔离多个用…

html、css、QQ音乐移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示

CSDN将我上传的免费资源私自变成VIP专享资源&#xff0c;且作为作者的我不可修改为免费资源&#xff0c;不可删除&#xff0c;寻找客服无果&#xff0c;很愤怒&#xff0c;&#xff08;我发布免费资源就是希望大家能免费一起用、一起学习&#xff09;&#xff0c;接下来继续寻找…

分享|网红阳哥介绍的项目能赚钱吗?具体有哪些项目?

在当今的互联网时代&#xff0c;网红的影响力不容小觑&#xff0c;他们通过分享自己的经验和见解&#xff0c;往往能带动一股潮流或引领一种趋势。其中&#xff0c;网红阳哥以其独到的眼光和丰富的经验&#xff0c;分享了一系列赚钱项目&#xff0c;引起了广泛关注。那么&#…

C语言 逻辑运算符

本文 我们来说 逻辑运算符 有时做出决策需要测试多个条件&#xff0c;C语言提供了用于将简单条件组合成复杂条件的逻辑运算符。 逻辑运算符 如下图 用逻辑运算符连接操作数组成的表达式称为逻辑表达式。 逻辑运算的结果只有0和1 逻辑运算的对象可以是任意数值型&#xff0c;但…

VMWare Ubuntu压缩虚拟磁盘

VMWare中ubuntu会越用越大&#xff0c;直到占满预分配的空间 即使系统里没有那么多东西 命令清理 开机->open Terminal sudo vmware-toolbox-cmd disk shrink /关机-> 编辑虚拟机设置->硬盘->碎片整理&压缩 磁盘应用 开机->disk usage analyzer(应用) …

Springboot+Vue项目-基于Java+MySQL的影城管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

苹果 IPA 应用部署软件 iMazing 3 Windows 版获 3.0.0.4 Beta 4

在数字化时代&#xff0c;我们的iOS设备已经成为生活中不可或缺的一部分。为了更加高效、便捷地管理这些设备&#xff0c;iMazing 3.0.0.3 应运而生&#xff0c;它以其独特的功能和卓越的性能&#xff0c;为用户带来了前所未有的全新体验。 首先&#xff0c;iMazing 3.0.0.3 提…

2024第二十一届五一数学建模B题思路 五一杯建模思路

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

机器学习-随机森林算法预测房租模型

文章目录 机器学习-随机森林算法预测房租模型解决问题数据集探索性数据分析数据预处理构建模型并训练结果分析与评估参数调优结果预测模型保存经验总结参考文章 机器学习-随机森林算法预测房租模型 解决问题 根据待租房源相关信息&#xff0c;通过随机森林机器学习算法构件预…

车载以太网DoIP 协议,万字长文详解

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

[图解]软件开发中的糊涂用语-03-文档

0 00:00:00,280 --> 00:00:04,550 今天呢&#xff0c;我们来看一个糊涂用语&#xff0c;文档 1 00:00:07,810 --> 00:00:10,106 我们经常听到这样的话 2 00:00:10,106 --> 00:00:10,566 3 00:00:10,566 --> 00:00:13,322 你们怎么一上手就写代码 4 00:00:13,322…

Ps 滤镜:路径模糊

Ps菜单&#xff1a;滤镜/模糊画廊/路径模糊 Filter/Blur Gallery/Path Blur 路径模糊 Path Blur滤镜可以沿路径创建运动模糊&#xff0c;还可以控制形状和模糊量。Photoshop 可自动合成应用于图像的多个路径的模糊效果。 ◆ ◆ ◆ 主要用途 1、相对于动感模糊 Motion Blur滤镜…