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

装饰者模式(设计模式)

装饰模式就是对一个类进行装饰,增强其方法行为,在装饰模式中,作为原来的这个类使用者还不应该感受到装饰前与装饰后有什么不同,否则就破坏了原有类的结构了,所以装饰器模式要做到对被装饰类的使用者透明,这是对装饰器模式的一个要求。总之装饰器设计模式就是对于原有功能的扩展
不改变原有代码基础之上 额外实现增强。装饰者模式是一种结构型设计模式,它允许你在运行时为对象动态添加新的行为,同时不改变其原有的结构。这种模式是作为替代继承的一种方式而存在的。
在装饰者模式中,有一个抽象组件(Component)定义了基本功能,并且可以有一个或多个具体组件(ConcreteComponent)实现这些基本功能。此外,还有一个抽象装饰者(Decorator)类,它也实现了抽象组件,并且包含了一个指向抽象组件的引用。具体装饰者(ConcreteDecorator)类继承自抽象装饰者类,并且可以在运行时为抽象组件添加新的行为。

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给对象添加职责(功能)。装饰者模式与继承不同,它通过创建装饰者类来包装原始类,而不是通过继承来扩展功能。装饰者模式在许多情况下非常有用,特别是在需要组合功能或动态地调整功能的时候。
优点

  1. 灵活性:通过组合不同的装饰器,可以灵活地为对象添加不同的功能。
  2. 遵循开闭原则:不修改现有类的情况下扩展功能。
  3. 细粒度控制:可以对对象功能进行细粒度控制和组合。
    缺点
  4. 复杂性:会增加系统的复杂性,尤其是在有大量不同装饰器的时候。
  5. 性能:可能会增加系统的性能开销,特别是在装饰器链比较长的情况下。
    装饰者模式非常适合那些需要在不修改类定义的情况下动态地添加功能的场景。
    装饰者模式的组成

装饰者模式主要包括以下几个部分:
组件接口(Component):定义对象的接口,可以是具体组件或装饰器共同实现的接口。
具体组件(ConcreteComponent):实现组件接口的基本功能对象。
装饰器抽象类(Decorator):实现组件接口,并包含一个组件接口的引用,可以是具体组件或另一个装饰器。
具体装饰器(ConcreteDecorator):继承装饰器抽象类,添加额外的功能。
UML 类图

Component (接口)
^
|
ConcreteComponent (具体组件)
^
|
Decorator (装饰器抽象类)
^
|
ConcreteDecoratorA, ConcreteDecoratorB (具体装饰器)

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给对象添加职责(功能)。装饰者模式与继承不同,它通过创建装饰者类来包装原始类,而不是通过继承来扩展功能。装饰者模式在许多情况下非常有用,特别是在需要组合功能或动态地调整功能的时候。

UML 类图
Component (接口)
^
|
ConcreteComponent (具体组件)
^
|
Decorator (装饰器抽象类)
^
|
ConcreteDecoratorA, ConcreteDecoratorB (具体装饰器)

java样例1

以下是一个简单的 Java 示例,展示了如何使用装饰者模式:

// 组件接口
public interface Coffee {String getDescription();double getCost();
}// 具体组件
public class SimpleCoffee implements Coffee {@Overridepublic String getDescription() {return "Simple coffee";}@Overridepublic double getCost() {return 2.0;}
}// 装饰器抽象类
public abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee coffee) {this.decoratedCoffee = coffee;}@Overridepublic String getDescription() {return decoratedCoffee.getDescription();}@Overridepublic double getCost() {return decoratedCoffee.getCost();}
}// 具体装饰器A
public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return decoratedCoffee.getDescription() + ", Milk";}@Overridepublic double getCost() {return decoratedCoffee.getCost() + 0.5;}
}// 具体装饰器B
public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return decoratedCoffee.getDescription() + ", Sugar";}@Overridepublic double getCost() {return decoratedCoffee.getCost() + 0.2;}
}// 使用装饰者模式
public class DecoratorPatternDemo {public static void main(String[] args) {Coffee coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " $" + coffee.getCost());coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.getCost());coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.getCost());}
}

运行结果
Simple coffee $2.0
Simple coffee, Milk $2.5
Simple coffee, Milk, Sugar $2.7
解释

  1. 组件接口(Coffee):定义了 getDescription 和 getCost 方法。
  2. 具体组件(SimpleCoffee):实现了组件接口,表示基本的咖啡。
  3. 装饰器抽象类(CoffeeDecorator):实现了组件接口,并持有一个组件接口的引用。
  4. 具体装饰器(MilkDecorator 和 SugarDecorator):扩展了装饰器抽象类,为咖啡添加额外的功能(牛奶和糖)。

Java样例2

下面是一个简单的装饰者模式的示例,假设我们有一个接口 Shape 表示图形,以及一个具体实现 Circle:

public interface Shape {void draw();
}public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing Circle");}
}
然后我们创建一个抽象装饰者 ShapeDecorator,它也实现了 Shape 接口,并且包含了一个指向 Shape 的引用:
public abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape) {this.decoratedShape = decoratedShape;}public void draw() {decoratedShape.draw();}
}
接着,我们可以创建具体的装饰者,例如 RedShapeDecorator,它继承自 ShapeDecorator 并且在原有的基础上添加新的行为:
public class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape){System.out.println("Border Color: Red");}
}
最后,我们可以使用装饰者模式来动态地为对象添加新的行为,例如:
public class DecoratorPatternDemo {public static void main(String[] args) {Shape circle = new Circle();Shape redCircle = new RedShapeDecorator(new Circle());System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();}
}

在这个示例中,RedShapeDecorator 动态地为 Circle 对象添加了红色边框的功能,而不需要改变 Circle 类的代码。
装饰者模式的优点在于它能够灵活地扩展对象的功能,而不需要修改现有的代码,同时遵循了开放-封闭原则。但是,过度使用装饰者模式可能会导致系统中出现大量的小类,增加复杂性。因此,在使用装饰者模式时需要权衡利弊。

相关文章:

  • JavaScript中的解构赋值
  • 为啥找对象千万别找大厂男,还好我不是大厂的。。
  • Python武器库开发-武器库篇之链接提取器(六十)
  • 【跟我学RISC-V】(三)openEuler特别篇
  • 园区无线网新架构:无CAPWAP的集中式转发
  • 一文详解:什么是小程序SDK?
  • java1.8运行arthas-boot.jar运行报错解决
  • 编程属于什么类学科门类:深入探索与解析
  • PDM 测试
  • idea自定义注释模板
  • Github 2024-06-15Rust开源项目日报Top10
  • 77道经典的软件测试面试题(答案+文档)
  • Windows Server 远程桌面显示登录界面而不是直接登录进入的问题
  • [Cloud Networking] Layer3 (Continue)
  • CCAA质量管理【学习笔记】​​ 备考知识点笔记(五)质量设计方法与工具
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 5、React组件事件详解
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • CSS魔法堂:Absolute Positioning就这个样
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • PHP 7 修改了什么呢 -- 2
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 测试如何在敏捷团队中工作?
  • 从零开始在ubuntu上搭建node开发环境
  • 翻译:Hystrix - How To Use
  • 用jquery写贪吃蛇
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • Java总结 - String - 这篇请使劲喷我
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • #includecmath
  • #window11设置系统变量#
  • #微信小程序(布局、渲染层基础知识)
  • $.ajax,axios,fetch三种ajax请求的区别
  • (12)目标检测_SSD基于pytorch搭建代码
  • (13)Hive调优——动态分区导致的小文件问题
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (三)Honghu Cloud云架构一定时调度平台
  • (三十五)大数据实战——Superset可视化平台搭建
  • (十八)Flink CEP 详解
  • (十六)、把镜像推送到私有化 Docker 仓库
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (原)Matlab的svmtrain和svmclassify
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)大道至简,职场上做人做事做管理
  • .describe() python_Python-Win32com-Excel
  • .Net Core 生成管理员权限的应用程序
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET 直连SAP HANA数据库
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • .Net语言中的StringBuilder:入门到精通
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @html.ActionLink的几种参数格式