第6章 装饰模式

把所需的功能按正确的顺序串联起来进行控制
与建造者模式对比:
建造者模式是在内部组装完毕,要求建造的过程必须是稳定的;
装饰模式建造过程是不稳定的,把所需的功能按正确的顺序串联起来进行控制。

概念:
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活

/*Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体对象,也可以给这个对象添加一些职责(属于它自己地职责)。
Decorator,装饰抽象类,继承了Component,从外类来扩展Component类地功能,但对于Component来说,是无需知道Decorator的存在的。
至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。*/

//Component类
class Component{
public:
 virtual void Operation() = 0;
};
//ConcreteComponent类
class ConcreteComponent : public Component{
public:
 void Operation(){
  //添加属于具体对象它自己该有的职责行为
  std::cout<<"具体对象的操作"<<std::endl;
 }
};

//Decorator类
class Decorator : public Component{
public:
 //设置Component
 void SetComponent(Component* component){
  this->component = component;
 }
 
 void Operation(){
  //重写Operation(),实际执行的是Component的Operation()
  component.Operation();
 }
protected:
 Component* component;
};
//ConcreteDecoratorA类
class ConcreteDecoratorA : public Decorator{
public:
 void Operation(){
  //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
  Decorator::Operation();
  std::cout<<addedState<<std::endl;
 }
 
private:
 //本类的独有功能
 std::string addedState;
};
class ConcreteDecorator : public Decorator{
public:
 void Operation(){
  //首先运行原Component的Operation(),再执行本类的功能,如AddedBehavior(),相当于对原Component进行了装饰
  Decorator::Operation();
  AddedBehavior();
 }
 
private:
 void AddedBehavior(){
  std::cout<<"本类独有功能"<<std::endl;
 }
};

//客户端代码
int main(){
 ConcreteComponent c;
 ConcreteDecorator d1;
 ConcreteDecorator d2;
 
 //装饰的方法是:首先用ConcreteComponent实例化对象c,
 //然后用ConcreteDecoratorA的实例化对象d1来包装c,
 //再用ConcreteDecoratorB的对象d2包装d1,
 //最终执行d2的Operation()
 d1.SetComponent(&d1);
 d2.SetComponent(&d2);
 
 d2.Operation();
 return 1;
}

装饰模式是利用SetComponent来对对象进行包装的。每个装饰对象的实现就和如何使用这个对象分离开了(装饰类里边不需要直接包含具体对象ConcreteComponent对象的职责了),每个装饰对象只关心自己的功能(通过调用父类Decorator::Operation,然后再添加该装饰类独有的扩充功能,实现该装饰类在原有具体对象(可能已经被其他装饰类对象装饰扩充过)的已有功能基础上继续进行功能扩充),不需要关心如何被添加到对象链当中(下一个装饰类对象通过调用SetComponent负责将本次装饰对象添加到对项链中)。
如果只有一个ConcreteComponent类(没有其他的具体类,不需要抽象)而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类(装饰类Decorator继承唯一的实体类ConcreteComponent,作为实体类的子类存在)。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类(让ConcreteDecorator类继承Component类或继承只有一个具体实体类的情况ConcreteComponent类)。

装饰模式总结:
装饰模式是为已有功能动态地添加更多功能的一种方式,什么时候使用它呢
在起初的设计中,当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。但这种做法的问题在于,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要,而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类通过SetComponent包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

之前的加减乘除类继承运算类,叫功能的扩展,装饰模式中装饰类对主类进行功能扩展也叫扩展两者的区别是什么呢
之前的加减乘除运算类继承运算基类,加减乘除等多种运算类之间逻辑上属于平级的,根据用户需要创建具体的运算类;
装饰模式是对主类或装饰后的主类(即装饰类)功能的扩充逻辑上像有层层递进的表象,通常特定装饰类用在特定的条件中(通过判断,在满足条件时使用具体的装饰类装饰主类或装饰已经装饰过主类的装饰类)使用。

装饰模式的优点:
把类中的装饰功能从类中搬移去除,这样可以简化原有的类,有效地把类的核心职责和装饰功能分开了。而且可以去除相关类中重复地装饰逻辑

保持装饰类之间彼此独立,这样它们就可以以任意地顺序进行组合了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值