zoukankan      html  css  js  c++  java
  • 装饰者模式及C++实现

    装饰者模式

    时常会遇到这样一种情况,我已经设计好了一个接口,并且也有几个实现类,但是这时我发现我设计的时候疏忽了,忘记了一些功能,或者后来需求变动要求加入一些功能,最简单的做法就是修改接口,添加函数,然后继承类中都相应的添加实现,这样做倒也没什么问题,但是如果这种变化来个好几次或者继承类非常多,那工作量可就大了。

    这时大神们就发明了装饰者模式,在不修改现在有接口和实现类的基础上实现功能或者状态的添加。

    从类图上看,ConcreteComponent是Component原有的继承类,而Decorator装饰者类也继承与Component,这样的是让Decorator的子类也可以方便的添加Component,而不用每个子类里面都去包含一次Component。(我的理解)

    这样客户端使用的时候只需要知道ConcreteDecorator就可以直接调用Decorator的operation方法了,至于operation方法是怎么实现的以及使用的Component的哪一个子类是不需要关心的,而且添加的方法addBehavior也可以直接使用。

    客户端就无法依赖于抽象了,如果addBehavior的实现方法要变了,比较好的是添加新的ConcreteDecorator子类,或者继承这个ConcreteDecorator重新实现addBehavior。

    image

    常用的情况

    如果需要添加新功能,但又不想修改定义好的接口或者抽象类,那么这时候就比较适合装饰模式,例如很多图形系统中的组件,就可以使用装饰模式,来让新的组件在继承现在功能的基础上添加新的功能。

    装饰模式一般是针对接口或者抽象类的变化,如果是具体实现类的变化,则要考虑适用哪种模式。

    优点

    1.可以不用修改原有的接口,就可以实现新功能的添加。

    2.装饰者可以很方便的转换原有接口中的实现,可以给装饰者指定不同的ConcreteComponent实现不同的功能。

    缺点

    1.复杂性增加,装饰者模式会导致许多小类的产生。

    C++代码实现

     1 #ifndef _COMPONENT_H_
     2 #define _COMPONENT_H_
     3 
     4 
     5 class Component
     6 {
     7 public:
     8     Component();
     9     virtual ~Component();
    10 
    11     virtual void operation() = 0;
    12 };
    13 
    14 
    15 class ConcreteComponent: public Component
    16 {
    17 public:
    18     ConcreteComponent();
    19     ~ConcreteComponent();
    20 
    21     void operation();
    22 };
    23 
    24 
    25 #endif
     1 #include "Component.h"
     2 #include <stdio.h>
     3 
     4 
     5 
     6 Component::Component()
     7 {
     8 
     9 }
    10 
    11 
    12 Component::~Component()
    13 {
    14 
    15 }
    16 
    17 
    18 ConcreteComponent::ConcreteComponent()
    19 {
    20 
    21 }
    22 
    23 
    24 
    25 ConcreteComponent::~ConcreteComponent()
    26 {
    27 
    28 }
    29 
    30 
    31 void ConcreteComponent::operation()
    32 {
    33     fprintf(stderr, "ConcreteComponent's operation!
    ");
    34 }
     1 #ifndef _DECORATOR_H_
     2 #define _DECORATOR_H_
     3 
     4 #include "Component.h"
     5 
     6 class Decorator: public Component
     7 {
     8 public:
     9     Decorator();
    10     virtual ~Decorator();
    11 
    12     virtual void operation();
    13     virtual void setComponent(Component* pComponent);
    14 
    15 protected:
    16     Component* mComponent;
    17 };
    18 
    19 
    20 class ConcreteDecorator: public Decorator
    21 {
    22 public:
    23     ConcreteDecorator();
    24     virtual ~ConcreteDecorator();
    25 
    26     virtual void addBehavior();
    27 };
    28 
    29 
    30 #endif
    Decorator.h
     1 #include "Decorator.h"
     2 #include <stdio.h>
     3 
     4 
     5 Decorator::Decorator()
     6 {
     7 
     8 }
     9 
    10 
    11 Decorator::~Decorator()
    12 {
    13 
    14 }
    15 
    16 
    17 void Decorator::operation()
    18 {
    19     mComponent->operation();
    20 }
    21 
    22 
    23 void Decorator::setComponent(Component* pComponent)
    24 {
    25     this->mComponent = pComponent;
    26 }
    27 
    28 
    29 ConcreteDecorator::ConcreteDecorator()
    30 {
    31 
    32 }
    33 
    34 
    35 ConcreteDecorator::~ConcreteDecorator()
    36 {
    37 
    38 }
    39 
    40 
    41 
    42 void ConcreteDecorator::addBehavior()
    43 {
    44     fprintf(stderr, "ConcreteDecorator's addBehavior!
    ");
    45 }
    Decorator.cpp
     1 #include "Decorator.h"
     2 
     3 
     4 
     5 int main()
     6 {
     7     Component* pComponent = new ConcreteComponent();
     8     ConcreteDecorator* pConDecorator = new ConcreteDecorator();
     9     pConDecorator->setComponent(pComponent);
    10     pConDecorator->operation();
    11     pConDecorator->addBehavior();
    12     return 0;
    13 }
    client.cpp
    1 g++ -o client client.cpp Component.cpp Decorator.cpp

    运行结果

    image

  • 相关阅读:
    ubuntu14.0 服务器webmin安装
    python如何简单的处理图片(1):打开显示
    如何在YouTube上下载视频
    Ubuntu下下载使用sublime
    IndentationError: unexpected indent
    Linux下vim显示行数
    Linux下tree的使用介绍
    Mac利用分屏spliter
    redis开机自启动脚本(linux)
    java 反射应用
  • 原文地址:https://www.cnblogs.com/cxjchen/p/3161686.html
Copyright © 2011-2022 走看看