C++设计模式之装饰器模式

目的

了解装饰器模式动机、相应的情景,所拥有的角色以主要思路。

装饰模式

动态的给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更加灵活。对象结构型模式。

动机

在不改变对象本身功能前提下给对象本身增加额外的新行为,它是一种用于替代继承的技术。引入装饰类,在装饰类中既可以调用带装饰的原有类方法,还可以增加新的方法,以扩充原有类的功能。

分类

  1. 透明式
  2. 半透明式

类图

在这里插入图片描述
在这里我其实有个疑问,抽象装饰者为啥要与抽象组件类成为组合关系(关联关系)后,还要继承抽象组件类。这个疑问后面慢慢解答。

  1. 透明式,客户端完全针对抽象编程,客户不需要知道具体的组件类与具体的装饰者类。
    抽象组件
#ifndef COMPONENT_H
#define COMPONENT_H

#include <QObject>

class Component : public QObject
{
    Q_OBJECT
public:
    explicit Component(QObject *parent = 0);
    virtual void display()=0;
signals:
public slots:
};
#endif // COMPONENT_H

#include "component.h"
Component::Component(QObject *parent)
    : QObject(parent)
{

}

具体组件

#ifndef WINDOWCOMPONENT_H
#define WINDOWCOMPONENT_H

#include <QObject>
#include "component.h"
class WindowComponent : public Component
{
public:
    explicit WindowComponent(Component* parent = nullptr);
protected:
    virtual void display();
};

#endif // WINDOWCOMPONENT_H
#include "windowcomponent.h"
#include <iostream>
using namespace std;

WindowComponent::WindowComponent(Component *parent)
    :Component(parent)
{

}

void WindowComponent::display()
{
    cout << "this is window!" << endl;
}

装饰父类----也是继承于抽象组件

#ifndef COMPONENTDECORATOR_H
#define COMPONENTDECORATOR_H

#include <QObject>
#include "component.h"
class ComponentDecorator : public Component
{
public:
    explicit ComponentDecorator(Component* parent = nullptr);
protected:
    virtual void display();
private:
    Component* m_component = nullptr;
};

#endif // COMPONENTDECORATOR_H
#include "componentdecorator.h"

ComponentDecorator::ComponentDecorator(Component* parent)
    :Component(parent)
{
    this->m_component = parent;
}

void ComponentDecorator::display()
{
    m_component->display();
}

具体装饰者类一--------------------黑色边框

#ifndef BLACKBORDERDECORATOR_H
#define BLACKBORDERDECORATOR_H

#include <QObject>
#include "componentdecorator.h"
#include "component.h"

class BlackBorderDecorator : public ComponentDecorator
{
public:
    explicit BlackBorderDecorator(Component* component = nullptr);
    void setBlackBorder();
protected:
    virtual void display();
};

#endif // BLACKBORDERDECORATOR_H
#include "blackborderdecorator.h"
#include <iostream>
using namespace std;

BlackBorderDecorator::BlackBorderDecorator(Component* component)
    :ComponentDecorator(component)
{

}

void BlackBorderDecorator::setBlackBorder()
{
    cout << "add BlackBorder for component" << endl;
}

void BlackBorderDecorator::display()
{
    setBlackBorder();
    ComponentDecorator::display();
}

具体装饰者类二--------------------滑动条

#ifndef SCROLLBARDECORATOR_H
#define SCROLLBARDECORATOR_H

#include <QObject>
#include "componentdecorator.h"
#include "component.h"

class ScrollBarDecorator : public ComponentDecorator
{
public:
    explicit ScrollBarDecorator(Component* component = nullptr);
    void setScrollBar();
protected:
    virtual void display();


};

#endif // SCROLLBARDECORATOR_H
#include "scrollbardecorator.h"
#include <iostream>
using namespace std;

ScrollBarDecorator::ScrollBarDecorator(Component* component)
    :ComponentDecorator(component)
{

}

void ScrollBarDecorator::setScrollBar()
{
    cout << "add scrollbar for component" << endl;
}

void ScrollBarDecorator::display()
{
    setScrollBar();
    ComponentDecorator::display();
}

main.cpp

  Component* com1, *combb, *comsb;
    com1 = new WindowComponent();
    combb = new BlackBorderDecorator(com1);
    combb->display();
    comsb = new ScrollBarDecorator(combb);
    comsb->display();
    return b.exec();

截图:

在这里插入图片描述
关于半透明模式 就不上细细说明。

总结

之所以将装饰者父类也继承于抽象组件,方便于装饰者能够之间装饰。

对于透明模式下,用户可以透明的使用装饰之前与装饰之后对象,无需要关心他们区别。要求就是,具体装饰者类中方法必须要覆盖抽象装饰者类的方法。

半透明模式下,则不一样,用户可能需要单独添加新增的业务方法,为了能调用得到的新增的方法,必须要使用具体装饰者类定义的对象。此时,客户端对于具体组件类型是透明的,对于具体装饰者类必须要指明,则是不透明的。

与代理模式区别

虽然与代理模式类图有点相同,但是主要区分还是不一样的。代理模式用于在对真实角色进行代理或者引用,代理角色通过引用真实角色,去操作真正的业务。装饰器模式则通过装饰者角色去给具体组件实现装饰,不会影响具体组件功能,在其基础上添加新的功能。不同的装饰者通过继承于抽象组件能实现对不同的装饰者进行装饰。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

not so perfect

无聊,打赏求刺激而已

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值