• strategy模式


    这次遇到它不是在项目中,但项目也有的。。今天实际上发现,在项目中23种设计模式的基本用法都作了示例。。原型也都规定好了。。

    策略模式是在读ThoughtWork文集里看到的,还提及了Null Object模式,两个都大致说下。

    The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them. 这样我们可以运行里,切换算法的实现。

    上图(from wiki):

     780px-Strategy_Pattern_Diagram_ZP.svg

    实际上,在一些情况下,我们已经不自觉的在使用这一模式了,不知道你是不是也有同感。

    再来一段示例代码:

    #include <iostream>
    using namespace std;
     
    class StrategyInterface
    {
        public:
            virtual void execute() const = 0;
    };
     
    class ConcreteStrategyA: public StrategyInterface
    {
        public:
            virtual void execute() const
            {
                cout << "Called ConcreteStrategyA execute method" << endl;
            }
    };
     
    class ConcreteStrategyB: public StrategyInterface
    {
        public:
            virtual void execute() const
            {
                cout << "Called ConcreteStrategyB execute method" << endl;
            }
    };
     
    class ConcreteStrategyC: public StrategyInterface
    {
        public:
            virtual void execute() const
            {
                cout << "Called ConcreteStrategyC execute method" << endl;
            }
    };
     
    class Context
    {
        private:
            StrategyInterface * strategy_;
     
        public:
            explicit Context(StrategyInterface *strategy):strategy_(strategy)
            {
            }
     
            void set_strategy(StrategyInterface *strategy)
            {
                strategy_ = strategy;
            }
     
            void execute() const
            {
                strategy_->execute();
            }
    };
     
    int main(int argc, char *argv[])
    {
        ConcreteStrategyA concreteStrategyA;
        ConcreteStrategyB concreteStrategyB;
        ConcreteStrategyC concreteStrategyC;
     
        Context contextA(&concreteStrategyA);
        Context contextB(&concreteStrategyB);
        Context contextC(&concreteStrategyC);
     
        contextA.execute(); // output: "Called ConcreteStrategyA execute method"
        contextB.execute(); // output: "Called ConcreteStrategyB execute method"
        contextC.execute(); // output: "Called ConcreteStrategyC execute method"
     
        contextA.set_strategy(&concreteStrategyB);
        contextA.execute(); // output: "Called ConcreteStrategyB execute method"
        contextA.set_strategy(&concreteStrategyC);
        contextA.execute(); // output: "Called ConcreteStrategyC execute method"
     
        return 0;
    }

    好,下面说Null Object模式,很容易,先上代码:

    class animal {
    public:
      virtual void make_sound() = 0;
    };
     
    class dog : public animal {
      void make_sound() { cout << "woof!" << endl; }
    };
     
    class null_animal : public animal {
      void make_sound() { }
    };

    你一定不知道这段代码有什么神奇的地方,那就听我慢慢说。

    在一些场合下,假设我们需要传一个引用参数,这没什么,但要说明这个引用可能为“空”。好,怎么表示这个空?Java中没有问题,null就搞定了;那C++这种东西呢? 当然我们可以说用指针来绕过这一问题,但你对这个答案满意么?

    好,我们看看这段代码,把null_animal这个东西认为是一个类似NULL的东西如何呢?

    这种做法不但可以解决问题,还会有一些其它的好处。

    比如,当然类型是一个数组(比如java中的list)时,我们可能要对返回值为null的情形特殊处理,但如果返回这样一个无害的对象,其iterator可以正常调用但不会产生什么实际效果,这样是不是更好呢?

    这样的用法,至少可以减少分支(if else)数,使方法的代码行数减少,结构明析。

    再一点好处,我们可以把这种对象作为桩来用--万一我们的测试还差一部分才能做,而这一部分一时半会儿完不成但我们暂时用不太到时。

  • 相关阅读:
    图标图片1
    korGE打包注意事项
    书摘1011
    ffmpeg转流rtp转udp
    ffmpeg文档
    ffmpeg http 推流服务器
    cpp笔记
    搭建shAadowsoacks 错误
    ffmpeg 开发板推流到ubuntu和pc
    gstreamer笔记
  • 原文地址:https://www.cnblogs.com/justin_s/p/1904070.html
Copyright © 2020-2023  润新知