〇、简介

1、什么是装饰者模式

一句话解释:

  通过继承统一的抽象类来新增操作,再在使用时通过链式添加到对象中,达到与原有设定无关联可灵活附加。

装饰者模式是一种行为设计模式,它允许向一个现有的对象添加新的行为,同时又不改变其结构。

装饰者模式的基本概念是,将一个对象包装在一个含有对对象进行增强功能的对象中,从而达到对对象扩展功能的目的。

官方意图描述:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。别名:包装器(wrapper)。

一个比喻:(班级内部毕业晚会,提供各种零食)

   毕业晚会开始了,有很多种零食,陆续由供应商送来,送来一种相当于实现了一次装饰者抽象类,对于使用者每位同学,可以按照自己的需求选择是否装进自己的肚子。

2、优缺点和适用场景

优点:

  • 动态添加功能:装饰者模式允许在运行时为对象添加新的功能,而不需要修改其代码。这使得代码更加灵活和可维护。
  • 代码复用:装饰者模式可以避免代码重复,因为可以在一个对象上添加多个装饰器,而不需要为每个对象都编写新的代码。
  • 易于扩展:装饰者模式可以很容易地添加新的装饰器,而不需要修改现有的代码。
  • 提高代码可读性:装饰者模式可以使代码更加模块化,使得代码更易于理解和维护。

缺点:

  • 过度使用可能导致代码难以理解和维护:装饰者模式可以使代码变得更加灵活,但如果过度使用,可能会导致代码难以理解和维护。
  • 依赖关系增加:装饰者模式会增加对象之间的依赖关系,这可能会导致系统的复杂性增加。
  • 无法改变对象的类:装饰者模式无法改变对象的类,只能在现有类的基础上添加新的功能。这可能会限制了装饰者模式的使用。
  • 性能问题:如果过度使用装饰者模式,可能会导致系统的性能下降。因为在运行时需要动态创建和销毁对象,这可能会消耗大量的系统资源。

适用场景:

  • 在游戏开发中,装饰者模式可以用于为角色添加新的能力和技能,而不影响原先已有的设定。
  • 在UI设计中,装饰者模式可以用于为界面元素添加新的样式和效果,如边框、背景、阴影、动画等。
  • 在图像处理中,装饰者模式可以用于为图像添加新的滤镜和效果,如锐化、模糊、旋转、裁剪等。
  • 在文本处理中,装饰者模式可以用于为文本添加新的格式和效果,如加粗、斜体、下划线、高亮等。
  • 在购物车应用中,装饰者模式可以用于为商品添加新的属性和功能,如价格、库存、优惠券等。

一、通过示例代码简单实现

下面是一段示例代码,假设需要画一个圆,需要设置宽度和颜色:

// 测试代码
class Program
{
static void Main(string[] args)
{
IShape circle = new Circle(); // 准备画个圆
IShape borderCircle = new BorderDecorator(circle, 2); // 边框宽度设置为 2
IShape fillCircle = new FillDecorator(borderCircle, "blue"); // 颜色设置为 blue
fillCircle.Draw(); // 最后开始画
}
}
// 定义一个抽象装饰者接口
public interface IShape
{
void Draw();
}
// 定义一个抽象装饰者类
public abstract class ShapeDecorator : IShape
{
protected IShape Shape { get; set; }
public ShapeDecorator(IShape shape)
{
Shape = shape;
}
public abstract void Draw();
}
// 定义一个具体装饰者类
public class BorderDecorator : ShapeDecorator
{
private readonly int _borderWidth;
public BorderDecorator(IShape shape, int borderWidth)
: base(shape)
{
_borderWidth = borderWidth;
}
public override void Draw()
{
Console.WriteLine($"Drawing a {Shape.GetType().Name} with border width {_borderWidth}");
Shape.Draw();
}
}
// 定义另一个具体装饰者类
public class FillDecorator : ShapeDecorator
{
private readonly string _fillColor;
public FillDecorator(IShape shape, string fillColor)
: base(shape)
{
_fillColor = fillColor;
}
public override void Draw()
{
Console.WriteLine($"Drawing a {Shape.GetType().Name} with fill color {_fillColor}");
Shape.Draw();
}
}
// 定义一个原始形状类
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a circle");
}
}

下面如果需要增加一个画法该怎么扩展呢?如下代码,增加一个画法的扩展:

// 再定义另一个具体装饰者类,定义画法
public class MethodDecorator : ShapeDecorator
{
private readonly string _fillColor;
public MethodDecorator(IShape shape, string fillColor)
: base(shape)
{
_fillColor = fillColor;
}
public override void Draw()
{
Console.WriteLine($"Drawing a {Shape.GetType().Name} with method {_fillColor}");
Shape.Draw();
}
}
// 测试代码
class Program
{
static void Main(string[] args)
{
IShape circle = new Circle(); // 准备画个圆
IShape borderCircle = new BorderDecorator(circle, 2); // 边框宽度设置为 2
IShape fillCircle = new FillDecorator(borderCircle, "blue"); // 颜色设置为 blue
IShape methodCircle = new MethodDecorator(fillCircle, "clockwise"); // 设计画法顺时针 clockwise
methodCircle.Draw(); // 最后开始画
}
}

这就是装饰者模式的基本思想:通过将一个对象包装在一个含有对对象进行增强功能的对象中,从而达到对对象扩展功能的目的。

二、装饰者模式的结构

根据上一章节的示例代码,可得如下结构图:

IShape:定义一个对象接口,可以给这些对象动态地添加职责。

Cricle:定义一个对象,可以给这个对象添加一些职责。

ShapeDecorator:维持一个指向 IShape 对象的指针,并定义一个与 IShape 接口一致的抽象类。

BorderDecorator、FillDecorator:向  Cricle 对象添加职责。

三、相关模式

关于适配器模式 Adapter:Decorator 模式不同于 Adapter 模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。

关于组合模式 Composite:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责————它的目的不在于对象聚集。

关于策略模式 Strategy:装饰者模式改变的是对象的外表;而 Strategy 模式使得你可以改变对象的内核。这是改变对象的两种途径。

Decorator 装饰者模式简介与 C# 示例【结构型4】【设计模式来了_9】的更多相关文章

  1. Decorator装饰者模式(结构型模式)

    1.需求 假设让我们去设计FCL中的Stream类,该类具有流类的基本功能,除了有各种不同类型的流外(如内存流.文件流.网络流等等),但是在不同的业务场景下,如处理银行业务,需要给相关的内存流进行加密 ...

  2. C#设计模式之十一外观模式(Facade)【结构型】

    一.引言 快12点半了,要开始今天的写作了.很快,转眼设计模式已经写了十个了,今天我们要讲[结构型]设计模式的第五个模式,该模式是[外观模式],英文名称是:Facade Pattern.我们先从名字上 ...

  3. C#设计模式之十三代理模式(Proxy)【结构型】

    一.引言   今天我们要讲[结构型]设计模式的第七个模式,也是"结构型"设计模式中的最后一个模式,该模式是[代理模式],英文名称是:Proxy Pattern.还是老套路,先从名字 ...

  4. C#设计模式之八桥接模式(Bridge)【结构型】

    一.引言 今天我们要讲[结构型]设计模式的第二个模式,该模式是[桥接模式],也有叫[桥模式]的.大家第一次看到这个名称会想到什么呢?我第一次看到这个模式根据名称猜肯定是连接什么东西的.因为桥在我们现实 ...

  5. C#设计模式之十组合模式(Composite)【结构型】

    一.引言   今天我们要讲[结构型]设计模式的第四个模式,该模式是[组合模式],英文名称是:Composite Pattern.当我们谈到这个模式的时候,有一个物件和这个模式很像,也符合这个模式要表达 ...

  6. C#设计模式之十二享元模式(Flyweight)【结构型】

    一.引言   今天我们要讲[结构型]设计模式的第六个模式,该模式是[享元模式],英文名称是:Flyweight Pattern.还是老套路,先从名字上来看看."享元"是不是可以这样 ...

  7. 设计模式(十):Decorator装饰者模式 -- 结构型模式

    1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继 ...

  8. 12、Decorator 装饰器 模式 装饰起来美美哒 结构型设计模式

    1.Decorator模式 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式(Decorator Pattern)允许向一个现 ...

  9. HeadFirst设计模式 之 C++实现(三):Decorator(装饰者模式)

    装饰者模式是非常有意思的一种设计模式,你将可以在不改动不论什么底层代码的情况下.给你的(或别人的)对象赋予新的职责. 不是使用继承每回在编译时超类上改动代码,而是利用组合(composition)和托 ...

  10. [C++设计模式] decorator 装饰者模式

    <head first>中 的样例:咖啡店有各种咖啡饮料,能够往咖啡里面加各种调料变成还有一种饮料.假设使用继承的方式来为每一种饮料设计一个类,代码的复杂度非常easy膨胀,并且会继承父类 ...

随机推荐

  1. requests的基础使用

    爬虫介绍 # 爬虫:又称网络蜘蛛,spider,一堆程序,从互联网中抓取数据---->数据清洗---->入库 # 爬虫需要掌握的知识 -抓取数据:发送网络请求(http),获得响应(htt ...

  2. 国内可用的GPT4镜像站

    我做了个镜像站,GPT4的费用目前太贵了. 虽然做了个低价的月费,但基本上亏本在做,接口的实际费用高出太多. 运行了1个月,每天有几十人在用吧. 有兴趣的可以收藏一下 GPT4的验明正身的问题&quo ...

  3. HTML前端js

    ajax请求方法书写 $.ajax({ type:"POST", url:CONTEXT_PATH+"/appAudit/insertSnDocCountAdmin&qu ...

  4. PTA 21级数据结构与算法实验4—字符串和数组

    目录 7-1 字符串模式匹配(KMP) 7-2 [模板]KMP字符串匹配 7-3 统计子串 7-4 好中缀 7-5 病毒变种 7-6 判断对称矩阵 7-7 三元组顺序表表示的稀疏矩阵转置运算Ⅰ 7-8 ...

  5. [SCOI2005] 栅栏【题解】

    简要题意 木材店老板给出一个整数 \(m\) 和 \(m\) 个木板的长度.老板给出的木板可以随意无损耗切割. 约翰给出一个整数 \(n\) 和所需要的 \(n\) 个木板的长度. 求约翰能得到最多木 ...

  6. C#/.net/DotNet/Emgu.CV裁剪照片头像

    头像裁剪有利于人脸识别批量照片预处理,安防领域可以快速通过视频定位人脸,进行抓拍,做人脸识别相关功能的可能会应用到人脸裁剪,以下是我在实践中应用的代码,如有需要复制粘贴即可使用. using Emgu ...

  7. 【微信小程序的开发】初步认识

    目录 项目结构 页面组成 json配置文件 ​ app.json ​ project.config.json ​ sitemap.json ​ 每个页面的json ​ 实例 wxml ​ 标签名称 ​ ...

  8. OpenCV实战:从图像处理到深度学习的全面指南

    本文深入浅出地探讨了OpenCV库在图像处理和深度学习中的应用.从基本概念和操作,到复杂的图像变换和深度学习模型的使用,文章以详尽的代码和解释,带领大家步入OpenCV的实战世界. 1. OpenCV ...

  9. .NET 8 发布的最后一个预览版Preview 7, 下个月发布RC

    微软在2023年8月9日 发布了.NET 8 Preview 7[1],这是它在11月14日 RTM 之前进入发布候选阶段之前的最后预览版. 该预览版也于也与 VS 2022 v17.7 版本一起发布 ...

  10. Python 潮流周刊#15:如何分析 FastAPI 异步请求的性能?

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中一则分享,不代表全部内容都是该主题,特此声明. 本周刊精心筛选国内外的 250+ 信息源,为你挑选最值 ...