C++模式设计:Decorator 装饰模式

一、应用场景举例

需要设计圆、矩形两种形状,同时设计这两种形状的红色、蓝色版本,按照传统的思路,使用继承的方式,则如下图:
在这里插入图片描述
按这种方式,当需要的形状和颜色种类增多时,所定义的类的数量将会急剧增多,而且类之间会有很多重复的代码。如果运用装饰模式的思想,依照“组合优先于继承”原则,将“颜色”单独定义为一个“装饰类”,该类也继承自抽象基类,且拥有一个抽象基类的指针,用于操作传入的不同的形状对象。这样,在定义装饰类对象时,传入不同的形状对象,就可以实现基本形状——圆、矩形和装饰——红色、蓝色的任意组合了,如下图:
在这里插入图片描述

二、实例代码

#include <iostream>

using namespace std;

class Shape   //定义抽象基类——形状
{
public:
    virtual void draw()=0;
    virtual ~Shape(){};
};

class Circle:public Shape //定义形状的子类——圆
{
public:
    virtual void draw(){
        cout<<"draw a circle"<<endl;
    }
};

class Rectangle:public Shape//定义形状的子类——矩形
{
public:
    virtual void draw(){
        cout<<"draw a rectangle"<<endl;
    }
};

class ShapeDecorator:public Shape //定义装饰类,表示对图形的装饰
{
public:
    Shape * shape;
    ShapeDecorator(Shape *s){
        shape = s;
    }
};

class RedShape:public ShapeDecorator //继承装饰类,定义装饰——红色
{
public:
    RedShape(Shape *s):ShapeDecorator(s){}
    virtual void draw(){
        cout<<"Set red pen"<<endl; //进行装饰操作
        shape->draw();  //操作传入的形状对象
    }
};

class BlueShape:public ShapeDecorator//继承装饰类,定义装饰——蓝色
{
public:
    BlueShape(Shape* s):ShapeDecorator(s){}

    virtual void draw(){
        cout<<"Set blue pen"<<endl; //进行装饰操作
        shape->draw();//操作传入的形状对象
    }
};


int main()
{
    Shape *circle = new Circle(); //生成圆对象
    Shape *rectangle = new Rectangle();//生成矩形对象
    Shape *redCircle = new RedShape(circle);//生成红色圆
    Shape *blueCircle = new BlueShape(circle);//生成蓝色圆
    Shape *redRectangle = new RedShape(rectangle);//生成红色矩形
    Shape *blueRectabgle = new BlueShape(rectangle);//生成蓝色矩形

    //画出所有图形
    circle->draw();
    rectangle->draw();
    redCircle->draw();
    redRectangle->draw();
    blueCircle->draw();
    blueRectabgle->draw();

    return 0;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值