装饰者模式

比特踏浪鹤
• 阅读 1225

简介

装饰者模式可以动态地给一个对象添加行为,相对通过继承来扩展功能,它是一个灵活的选择。装饰者模式也使用了继承,只是为了统一接口,如果去除CDecorator和CComponent的继承关系,就有些像桥接模式了。主要区别是装饰者不需要动态的改变被装饰的对象,而桥接模式是多个维度独立的变化。

UML类图

装饰者模式

示例

陈奕迅有一首歌,last order,其中有句歌词,“麻烦你 加冰威士忌 对不起 来个DOUBLE的”。在这里我们假定威士忌是已经实现的类,不能再改动了。那就需要装饰者登场了。这里实现了加冰威士忌,也实现了来个double的。

装饰类,decorator.h

#include <iostream>
using namespace std;

class CWine
{
public:
    virtual string GetName() = 0;
    virtual double GetCost() = 0;
};

class CWhisky:public CWine
{
public:
    string GetName()
    {
        return "Whisky";
    }
    double GetCost()
    {
        return 60.0;
    }
};

class CWineDecorator:public CWine
{
public:
    CWineDecorator(CWine* pWine):m_pWine(pWine){};
    string GetName()
    {
        return m_pWine->GetName();
    }
    double GetCost()
    {
        return m_pWine->GetCost();
    }
public:
    CWine* m_pWine;
};

class CIceDecorator:public CWineDecorator
{
public:
    CIceDecorator(CWine* pWine):CWineDecorator(pWine){}
    string GetName()
    {
        return m_pWine->GetName().append("+Ice");
    }
    double GetCost()
    {
        return m_pWine->GetCost() + 10;
    }
};

客户端调用,main.cpp

#include "decorator.h"

#define SAFE_DELETE(p) if(p){delete (p); (p) = NULL;}
int main(int argc, char* argv[])
{
    CWine* pWhisky = new CWhisky;
    CWine* pIceWhisky = new CIceDecorator(pWhisky);
    std::cout<<"Name:"<<pIceWhisky->GetName().c_str()<<endl;
    std::cout<<"Price:"<<pIceWhisky->GetCost()<<endl;

    CWine* pDoubleIceWhisky = new CIceDecorator(pIceWhisky);
    std::cout<<"Name:"<<pDoubleIceWhisky->GetName().c_str()<<endl;
    std::cout<<"Price:"<<pDoubleIceWhisky->GetCost()<<endl;

    SAFE_DELETE(pDoubleIceWhisky);
    SAFE_DELETE(pWhisky);
    SAFE_DELETE(pIceWhisky);
    return 0;
}

输出结果如下:

Name:Whisky+Ice
Price:70
Name:Whisky+Ice+Ice
Price:80
点赞
收藏
评论区
推荐文章
观察者模式在spring中的应用
作者:王子源1观察者模式简介1.1定义指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布订阅模式、模型视图模式,它是对象行为型模式。
3A网络 3A网络
2年前
Golang 常见设计模式之单例模式
之前我们已经看过了Golang常见设计模式中的装饰和选项模式,今天要看的是Golang设计模式里最简单的单例模式。单例模式的作用是确保无论对象被实例化多少次,全局都只有一个实例存在。根据这一特性,我们可以将其应用到全局唯一性配置、数据库连接对象、文件访问对象等。Go语言实现单例模式的方法有很多种,下面我们就一起来看一下。饿汉式饿汉式实现单例模式非
Wesley13 Wesley13
3年前
JavaWeb实现文件上传与下载
1\.增强HttpServletResponse对象  1.实现一个增强的HttpServletResponse类,需要继承javax.servlet.http.HttpServletRequestWrapper类,通过重写自己需要增强的方法来实现(这种模式就叫做装饰者模式),使用该增强类在
Stella981 Stella981
3年前
Category 特性在 iOS 组件化中的应用与管控
背景iOSCategory功能简介Category是ObjectiveC2.0之后添加的语言特性。Category就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法。在ObjectiveC(iOS的开发语言,下文用OC代替)中的具体体现为:实例(类)方法、属性和协
Wesley13 Wesley13
3年前
Java中23种设计模式详解
Java中23种设计模式1\.设计模式31.1创建型模式41.1.1工厂方法41.1.2抽象工厂61.1.3建造者模式101.1.4单态模式131.1.5原型模式151.2结构型模式171.2.1适配器模式171.2.2桥接模式191.2.3组合
Wesley13 Wesley13
3年前
Java Design Patterns
java的设计模式大体上分为三大类:创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模
Stella981 Stella981
3年前
Python 装饰器(Decorator)
Python 装饰器(Decorator)装饰模式有很多经典的使用场景,例如插入日志、性能测试、事务处理等等,有了装饰器,就可以提取大量函数中与本身功能无关的类似代码,从而达到代码重用的目的。下面就一步步看看Python中的装饰器。装饰器本身是一个Python函数,他可以让其他函数在不需要做任何代码变动
Stella981 Stella981
3年前
MediatorPattern中介者模式
中介者模式1.定义使用一个中介对象封装一系列的对象交互,中介者使用对象不需要显式的相互作用,从而实降现低耦合度,且可以独立改变被封装的一些列对象之间的交互。中介者模式也叫做调停者模式:对象之间的依赖就像战争,很混乱,加入一个中心,所有对象都和中心交流,接受中心的调停处理。中介者模式通常有4个角色Abstrac
Wesley13 Wesley13
3年前
JavaWeb之动态代理解决request请求编码问题
动态代理解决编码问题1.设计模式出现原因:软件开发过程中,遇到相似问题,将问题的解决方法抽取模型(套路)常见设计模式:单例,工厂,适配器,装饰者,动态代理。2.装饰者模式简单介绍谷歌汽车开发场景1.Java定义了汽车开发约定interfaceICar{s
Wesley13 Wesley13
3年前
ES6设计模式之装饰者模式
就是不修改原来的对象的情况下,对对象的功能进行扩充的一种方法。遵循的是开放封闭原则,类可以扩充但是不可以修改。各种粥里面有不同的调料,不同的调料可以加不同的量,最后粥的价钱不等。下面是es实现://注意粥里面可以加入不同的调料,调料不一样价钱不一样。classPorridge{constructor(){this.ary\_season
3A网络 3A网络
2年前
Golang 常见设计模式之装饰模式
Golang常见设计模式之装饰模式想必只要是熟悉Python的同学对装饰模式一定不会陌生,这类Python从语法上原生支持的装饰器,大大提高了装饰模式在Python中的应用。尽管Go语言中装饰模式没有Python中应用的那么广泛,但是它也有其独到的地方。接下来就一起看下装饰模式在Go语言中的应用。简单装饰器我们通过一个简单的例子来