首页 > 其他分享 >装饰模式(decorator)

装饰模式(decorator)

时间:2023-09-07 18:25:48浏览次数:43  
标签:__ AbsPrint 模式 使用 print 装饰 decorator coutprint

装饰器模式(Decorator)

1、作用

引入一个设计原则:类应该对扩展开发,对修改关闭。简单的说,就是允许我们的我们的类进行扩展,在不修改现有代码的情况 下,适应新的行为改变。

当实现好的类有了新的需求,不考虑重用的话,会直接修改(现在写代码都这样,没有满足开闭原则的修改关闭原则),如果考虑代码的重用,以面向对象的设计思想,多数会想到使用继承,增加新添加的需求,但是如果需求很多,继承类的层次就很深,不方便维护和使用。使用装饰器模式,可以满足新加需求的功能,同时照顾的重用代码,并且避免继承的层次很深。

对原有的输出进行处理得到需要的输出(修饰),而不是修改原点代码,来改变原来代码的输出。这个模式最能够用到编写的脚本上,扩展脚本的功能。

2、实现方式

假设要实现一个简单的打印功能,实用了一个抽象类AbsPrint定义了接口,同时实现了一个具体的打印类BasePrint类,完成打印的基本功能。

img

但是后续需要添加新的打印需求,比如在打印内容的前后增加"*"和给打印内容加“()”。前面已经分析过,如果直接使用继承的方式,会导致类的层次很深,比利于后期维护,并且在设计模式中:Favor object composition over class inheritance,所以使用装饰器模式是一个比较好的方法(装饰类与原有类是一个关联关系),在不改变原有接口的情况下,添加新的功能,原有接口输出的内容进行处理。

使用Decorator模式,要添加一个中间类:AbsDecorator,这个类唯一功能就是封装一个AbsPrint对象(有的像),从AbsDecorator扩展出两个装饰类,AddBrackets和AddStar类来实现新增的功能。

装饰器可以嵌套使用(即使用AddBrackets又使用AddStart)

img

3、C++代码

print.h

#include <iostream>

#ifndef __PRINT__H__
#define __PRINT__H__

using namespace std;

class AbsPrint {
    public:
        AbsPrint() = default;
        virtual ~AbsPrint() = default;
        virtual void print(const string &str) = 0;
};

class BasePrint : public AbsPrint {                     // 已有的功能,下面的都是新增的需求
    public:
        void print(const string &str) override {
            cout<<str;
        }
};


class AbsDecorator : public AbsPrint {                    // 这个类的唯一目的就是封装AbsPrint对象,这样可以避免每个装饰器类都加这个成员。
    public:
        AbsDecorator(AbsPrint *p) : p(p) {}
        ~AbsDecorator() { delete p; }
    protected:
        AbsPrint *p;
};

class AddBrackets : public AbsDecorator {                  // 添加换行符的装饰器
    public:
        AddBrackets(AbsPrint *p):AbsDecorator(p){}
        void print(const string &str) override {
            cout<<"(";
            p->print(str);
            cout<<")";
        }
};


class AddStar : public AbsDecorator {                       // 首尾添加*的装饰器
    public:
        AddStar(AbsPrint *p): AbsDecorator(p) {}
        void print(const string &str) override {
            cout<<"*";
            p->print(str);
            cout<<"*";
        }
};

#endif

test.cc

#include <iostream>
#include "print.h"

using namespace std;

int main() {
    AbsPrint *p1 = new BasePrint;
    p1->print("hello world!");      // 直接使用基本的功能
    cout<<endl;

    AbsPrint *p2 = new AddStar(new BasePrint);
    p2->print("hello world!");      // 使用了添加"*"的装饰器
    cout<<endl;

    AbsPrint *p3 = new AddBrackets(new BasePrint);
    p3->print("hello world!");      // 使用了添加"()"的装饰器
    cout<<endl;

    AbsPrint *p4 = new AddBrackets(new AddStar(new BasePrint));
    p4->print("hello world!");      // 同时使用了加"*"和加"()"的装饰器
    cout<<endl;

    return 0;
}

输出:

标签:__,AbsPrint,模式,使用,print,装饰,decorator,coutprint
From: https://www.cnblogs.com/yuandonghua/p/17685753.html

相关文章

  • 享元模式(flyweight)
    享元模式(flyweight)1、作用一些对象在使用一次后就可以销毁了,比如画一个圈,这个对象调用draw()函数后,这个对象就没有作用,除非再次画相同的圈。但是在应用中需要画很多圈,如果每次画一次圈都构造一个对象,这样内存消耗很多,构造销毁也很费时,这个时候就可以考虑一下享元模式,这样可以节......
  • 代理模式(Proxy)
    代理模式(Proxy)1、作用代理模式是包装一个对象,控制对它的访问,实现逻辑合实现的解耦。2、实现方式代理模式跟装饰器模式、适配器模式、外观模式都有类似的地方,都通过关联关系封装了其他类型的对象,但是使用的目的不一样。代理:包装一个对象,控制对它的访问。装饰者:包装另一个对象......
  • 策略模式(strategy)
    策略模式(Strategy)1、作用策略模式的主要目的主要是将算法的定义(strategy类)和使用分开(context类),也就是将算法的行为和环境分开,将算法的定义放在专门的策略类中,每一个策略类封装一个实现算法。而使用算法的环境中针对抽象策略编程,而不是针对实现编程,符合依赖倒置原则。2、实现方......
  • 模板模式(template)
    模板模式(Template)1、作用做一件是的方法很多,但做这件都可以归纳为几个步骤。这个时候可以使用模板模式,在模板类中,定义做事的步骤,将多种实现做事的细节延迟到子类中去实现。即:定义一个操作中的算法的骨架(模板函数),而将一些步骤延迟到子类中(基本函数)。模板方法使得子类可以不改变......
  • 外观模式(facade)
    外观模式(Facade)1、作用(1)、将各个子系统的接口汇聚在一起,定义一个统一的接口方便客户使用,满足“迪米特法则”,即客户不需要了解子系统,只需要知道Facade模式封装的类即可以使用所有子系统。(2)、隔离用户和子系统,将用户与子系统解耦,当子系统有修改是,顶多修改Facade模式封装的类,无需......
  • 桥接模式
    桥接模式1作用当类的模型有两个或多个维度的时候,如果两个变化维度用同一个类使用继承方式实现会变得很复杂(冗余代码很多),不易于维护和扩展(继承关系是一种强耦合关系),为了降低耦合关系,提高维护性和可扩展性,可以将两个变化维度的通过两个类(abstruction、implementor类)来实现,将两......
  • 韬客时代卷轴模式系统开发介绍和部分核心源码
    韬客时代是一种卷轴模式系统。什么是卷轴模式呢?新用户注册,先送你一部分积分,该积分用于兑换一个初始任务,俗称卷轴!卷轴模式的赚钱的原理是,你用积分兑换初级任务包,完成卷轴任务之后,你可以获得更多的积分,然后复投,达到一定数量后可以兑换更高级的任务包,任务包越高级每次获得的积分也就越......
  • kafka复习:(24)consume-transform-produce模式
    packagecom.cisdi.dsp.modules.metaAnalysis.rest.kafka2023;importorg.apache.kafka.clients.consumer.*;importorg.apache.kafka.clients.producer.KafkaProducer;importorg.apache.kafka.clients.producer.ProducerConfig;importorg.apache.kafka.clients.produc......
  • 区域LIS应用平台 云技术的SaaS模式
    在医疗机构内部,院内实验室主要负责本院临床科室的检验,院内LIS系统必须满足实验室日常的标本处理入库、仪器联机、检验结果处理、报告打印、报告发布、检验信息统计、检验信息报告发布、标本流程、外部医疗机构检验报告调阅等工作。 在医疗机构间,一方面在区域卫生信息平台上构建区......
  • 一文搞定,PO设计模式详解
    PO模式:全称:pageobjece,分层机制,让不同层去做不同类型的事情,让代码结构清晰,增加复⽤性。PO模式的优势:1)效率⾼:同理,PO模式的逻辑层⽅法有具体定义,情况和元素发⽣变化⼀样修改逻辑层,业务层不变。这样看来结构简单清晰,舒服更符合⼈类习惯,普通⽅式就是继续堆case。2)复⽤多收益⼤:同样......