首页 > 其他分享 >装饰模式

装饰模式

时间:2023-01-29 22:55:23浏览次数:34  
标签:对象 模式 抽象 构件 具体 装饰 类中

装饰模式

一 场景

在软件开发中,我们有时候需要对一个已经存在对象的某个功能进行扩展。如果我们在这个对象的功能基础上进行修改,比如加入了新的字段,新的方法。这样就会增加原有对象的复杂度,不符合开闭原则。

有没有什么方法能既可以不改变原对象,又可以对对象的功能进行扩展了?装饰模式恰好针对这种情况提供了一个非常好的解决方案,它把要装饰的功能单独的封装在一个新的装饰类中,再让这个装饰类包装它所要装饰的原对象。在装饰类中既可以调用原对象的方法,还可以增加新的方法,以扩充原对象的功能。这样装饰模式就有效地把类的原核心功能和新增的装饰功能区分开,并去除了相关类中重复的装饰逻辑,符合了开闭原则。

二 定义

    装饰模式动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式提供了比继承实现更为灵活的替代方案。

三 类图

 

 

Component(抽象构件类):抽象构件类一般被定义为一个接口或者是一个抽象类。具体构件类和抽象装饰类都是它的子类。在抽象构建类中定义了一些业务方法,具体构件类负责对这些业务方法给出具体的实现。

抽象构件类的引入,可以使客户端以一致的方式处理具体的构件对象和具体装饰对象。

 

ConcreteComponent(具体构件类):具体构件类是抽象构件类的子类,它实现了在抽象构件类中声明的业务方法,在装饰模式中就是对具体构件类中的业务方法给予增强,增加了额外的职责。

 

Decorator(抽象装饰类):抽象装饰类是具体装饰类的父类,它同时也是抽象构建类的子类。

在抽象装饰类主要是声明了用于给具体构件对象增加的职责,这些增加的具体职责是在具体装饰类中给予实现的。

在抽象装饰类中维护了一个对抽象构件对象的引用,通过这个引用可以调用未装饰的具体构件对象中的业务方法。

 

ConcreteDecorator(具体装饰类):具体装饰类是抽象装饰类的子类,负责向具体构件类中添加新的职责。

每一个具体装饰类都实现了一些新的用于增强行为的方法。它可以调用在抽象装饰类中定义的业务方法时候,可以增加这些新的方法,来扩充和增强原具体构件对象的业务方法,从而达到装饰的目的。

 

四 代码示例

我们平时会过很多节日,传统的节日有春节,洋节的话有圣诞节。过节的话,我们一般都会进行一些庆祝的活动。在节日中为了烘托气氛,我们会对家里进行一些装饰活动。以春节为例的话,我们一般会大门上贴春联,在屋檐下挂红灯笼,来装饰我们的房子,以此来烘托节日的气氛。针对以上情景,我可以使用装饰模式来进行设计。

我们定义一个IHoliday接口(抽象构件类)来表示抽象的节日,在接口中定义了一个庆祝的方法。

 

节日有很多种,我们可以以春节(具体构件类)为例,定义一个SpringFestival类。SpringFestival类继承了IHoliday接口,实现了celebrate()方法。

 

我们定义了一个抽象的节日装饰类AbstractHolidayDecorator(抽象装饰类),该类也实现了IHoliday接口,并在该类中维持了一个IHoliday实例的引用。IHoliday实例的引用是通过在构造函数中来赋值。

 

挂红灯笼是对节日的一种装饰,我们定义了HangRedLanternDecorator类(具体装饰类)。它继承了AbstractHolidayDecorator类,覆写了celebrate()方法。在原celebrate()方法中,增加挂红灯笼这个功能doHangRedLantern()。对原celebrate()方法进行了增强。

 

 同理贴春联的子类也是一样

 

运行示例

运行结果

 

五 总结

装饰模式是一种对象结构型模式。它是为已有的功能动态地进行增强的一种方式。装饰模式是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系来取代类之间的继承关系。

优点:

  1. 装饰模式可以动态的增强一个对象的功能,且比继承更加具有灵活性。装饰模式无需定义子类,不会导致类的个数急剧增加。
  2. 装饰模式把的装饰功能代码从原类中搬移去除,这样简化了原有的类。装饰模式有效地把类中的原有核心职责和新增的装饰功能区分开,使得系统易于维护。
  3. 装饰模式可以对一个对象进行多次装饰,我们可以根据需要有选择地、按顺序地使用装饰功能来多次包装对象,从而得到一个功能更为强大的对象。

缺点:

  1. 装饰模式中对于原对象每一种增加的功能,我们都需要对应的定义一个具体的装饰类。这样就会导致系统出现比较多的小类。

 

标签:对象,模式,抽象,构件,具体,装饰,类中
From: https://www.cnblogs.com/YaoxTao/p/17074042.html

相关文章

  • 24种设计模式--策略模式(strategy)、模板模式(template)
    @目录第一部分:策略模式1.定义接口:Game2.实现Game接口:2.1DNF2.2LOL3.引用的上下文:4.测试类4.1测试结果:第二部分:模板模式复用策略模式的代码1.定义钩子(抽象类):2.具体实现类......
  • 09-建造者模式
    09-建造者模式概念建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示建造者模式主要是用于创建一些复杂的对象,这些对象内部......
  • Blazor模式讲解
    Blazor的三种模式BlazorServer:BlazorServer在ASP.NETCore应用中支持在服务器上托管Razor组件。可通过SignalR连接处理UI更新。运行时停留在服务器上并处理......
  • Seata源码结构及事务模式介绍
    1.Seata是什么Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式......
  • redis的简易哨兵模式
    某一天突然收到通知说redis的服务器挂了,因为是支付服务用到的redis,所以赶紧去查一下对服务流程有没有影响,结果是一切正常,松了一口气。后面看了一下代码发现里面自己封装的......
  • 装饰器
    参考https://www.runoob.com/w3cnote/python-func-decorators.html简洁记录一些对我有用的笔记python的装饰器是通过闭包的方式实现先理解了第一段代码,函数式实现的闭包......
  • java常用的设计模式
     java的设计模式一、单例模式  基本概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。常见写法:  1.饿汉式publicclassSingleton{priva......
  • C++ 设计模式--模板方法Template Method
    1.定义定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。TemplateMethod使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某......
  • 装饰者模式和代理模式
    代理模式和装饰器模式很像,这里用【到咖啡馆喝咖啡】作例子来讲解。基础实现定义一个咖啡的接口。publicinterfaceCoffee{/***打印当前咖啡里有什么......
  • 【设计模式】行为型
    职责链模式Client->A->B->C,避免请求发送者与接收者耦合,将接收者对象连接成一条链,直到有对象处理命令模式 将请求转换为一个包含与请求相关的所有信息的独立对象。 可......