zoukankan      html  css  js  c++  java
  • 【设计模式系列】行为型模式之Null Object模式

    概要
    系统中会包含很多行为,有些行为总是存在并需要被执行,而有些行为在某些场合或某种设置下就不希望被执行,通常很多人会通过一些条件对系统行为进行限制来达到目的,但是这样会给本来很简单纯粹的处理增加额外的逻辑,而通过NULL Object模式会提供一个具有代理式的空白行为的对象来解决问题。

    目的
    通过NULL Object模式提供一个具有代理式的空白行为的对象,从而隐藏一些判断逻辑。

    实例
    看这样一个例子,系统中有类Action,一些具体行为都从类Action继承来扩展,类Manager会使用Action类型的对象来处理相应的动作。类图和代码如下:
    class Action {
    public:
         virtual void Execute() = 0;
    };
    class ConcreteAction : public Action {
    public:
         virtual void Execute() {
              ......
         }
    };
    class Manager {
    public:
         Manager(Action* at) {
              mAction = at;
         }
         void DoAction() {
              mAction->Execute();
         }
    private:
         Action* mAction;
    };

    这时发现在某种情况下我们希望DoAction方法中的Action不做任何处理,怎么解决呢?
    假设这里所说的某种情况可以用外部的某个变量isAction来进行判断,当值为FALSE时不进行任何处理。很多人会这样去调整代码,首先把isAction通过构造函数传递给Manager类,然后在DoAction中通过判断,当isAction为TRUE时才执行Action:
    class Manager {
    public:
         Manager(Action* at,  bool isAction) {
              mAction = at;
              mIsAction = isAction;
         }
         void DoAction() {
              if (mAction == TRUE) {
                   mAction->Execute();
              }
         }
    private:
         Action* mAction;
         bool mIsAction;
    };

    还有人会觉得应该把isAction的判断加在Action或ConcreteAction类中,让Execute方法自己来判断是否执行。
    虽然这样做都可以解决问题,但是却让本来处理很简单职责很单一的Manager或ConcreteAction类增加了额外的逻辑,也让代码看起来不是那么美妙了。看看Null Object模式怎么解决问题吧。
    class NullAction : public Action {
    public:
         virtual void Execute() {
              // do nothing
         }
    };

    就是这样,ConcreteAction,Manager和Action类都不需要改,只是追加了NullAction类,而它的Execute方法什么都不做。实际调用的代码如下所示:
    Action* at = NULL;
    if (isAction == TRUE) {
         at = new ConcreteAction();
    } else {
         at = new NULLAction();
    }
    Manager mng(at);
    mng->DoAction();

    可见,这样就把isAction相关的逻辑跟Manager或所有Action类都隔离开来了。 

    应用
    没啥可说的,该用就用。

  • 相关阅读:
    SourceTree 3.0.17如何跳过注册进行安装? — git图形化工具(一)
    一键复制功能
    如何适配处理iphoneX底部的横条
    .gitignore文件如何编写?
    Spring事务管理——事务的传播行为
    数据库事务之声明式事务
    JVM中的内存分区简介
    SpringMVC中文件的上传(上传到服务器)和下载问题(二)--------下载
    SpringMVC中文件的上传(上传到服务器)和下载问题(一)--------上传
    HashMap和Hashtable的区别
  • 原文地址:https://www.cnblogs.com/secbook/p/2655105.html
Copyright © 2011-2022 走看看