【设计模式】Head First 设计模式——策略模式 C++实现

设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。

设计思想

将行为想象为一族算法,定义算法族,分别封装起来,让他们之间可以互相替换,使得算法的变化独立于使用算法的客户。

业务场景

假定现在让你设计一个鸭子类,模仿这个世界上所有的鸭子,你会怎么做?

你可能会说使用继承,先定义一个Duck父类,然后写一些函数:display表现鸭子的模样,fly表现鸭子的飞行动作,quack表现鸭子的叫声...然后再写一些类去继承这个父类,一个一个重写父类的函数,模仿每种鸭子不同的长相,飞行行为和叫声。

如果你是一个初学者,你能想出这些并不奇怪,问题也确确实实解决了,但却并不是最佳方法。这种设计会造成大量的函数重复:比如世界上现在有10种鸭子,有4种鸭子的模样一模一样,另外3种一模一样,剩下的一模一样,而你却要一个一个去重复写display函数;这种设计也并不利于未来的业务发展:比如现在你用继承完成了所有的鸭子设计,某一天,科学家又宣布新发现10种鸭子,而你还是要继续改动你的代码,不断的重写,不断的继承。很快,你就会发现,继承并不是一个好办法。

刚开始出现继承这种机制的时候,很多程序员便很喜欢用这种方法解决问题。因为这很符合我们以往的认知习惯:某某人的儿子可以使用父亲手中的资源,这种使用似乎"理所应当",很顺其自然的一件事。但是,写代码的时候你就会发现继承能做的事情,往往组合也能实现,并且有时候会比用继承更好。

我们写程序的一个目标叫软件复用,如果你的代码里出现很多一模一样的函数,显然并不是一份很好的设计。而正如世界一样,我们的代码也需要与时俱进,否则就会死亡。一份程序在刚写好的时候仅仅是开始,后期花在维护,改进,更新上的时间要远远多于刚开始开发的时间,这些就是所谓的"change",正是这些变化才造成了你不断的加班,正如前面让你设计鸭子类一样,某天新发现10种鸭子,而你为了完成设计,可能就要被迫加班。

那么应该采取什么样的设计才能有效的抵御变化,少加班呢?

我们有一个设计原则叫做:找出应用中可能需要变化之处,把他们独立出来,不要和稳定的代码混在一起。

换句话说,如果每次新的需求依赖,都会使某些方面的代码发生变化,那么你就可以确定,这部分的代码需要被抽离,和其他稳定的代码有所区分。也就是说把会变化的部分取出并封装起来,以便以后可以轻易地改动以扩充此部分而不影响其它部分。

这个概念很简单,几乎是每个设计模式背后的精神所在。所有的设计模式都提供了一套方法让"系统中的某部分改变不会影响其它部分"。

策略模式代码案例

封装飞行行为;

C++ 复制代码
class FlyBehavior
{
public:
    virtual void fly() = 0;
};

class FlyWithWings : public FlyBehavior
{
public:
    void fly()
    {
        cout << "Fly with Wings..." << endl;
    }
};

class FlyNoway : public FlyBehavior
{
public:
    void fly()
    {
        cout << "i can not fly..." << endl;
    }
};

class FlyWithRockets : public FlyBehavior
{
public:
    void fly()
    {
        cout << "Fly with Rockets..." << endl;
    }
};

封装叫声行为;

c++ 复制代码
class FlyBehavior
{
public:
    virtual void fly() = 0;
};

class FlyWithWings : public FlyBehavior
{
public:
    void fly()
    {
        cout << "Fly with Wings..." << endl;
    }
};

class FlyNoway : public FlyBehavior
{
public:
    void fly()
    {
        cout << "i can not fly..." << endl;
    }
};

class FlyWithRockets : public FlyBehavior
{
public:
    void fly()
    {
        cout << "Fly with Rockets..." << endl;
    }
};

duck类委托飞行行为与叫声行为:

C++ 复制代码
class Duck
{
public:
    FlyBehavior*   flyBehavior;
    QuackBehavior* quackBehavior;

    void speak()
    {
        flyBehavior->fly();
        quackBehavior->quack();
    }

    Duck(FlyBehavior* fly, QuackBehavior* quack)
    {
        this->flyBehavior   = fly;
        this->quackBehavior = quack;
    }
};

实现具体的鸭子:

C++ 复制代码
class Duck1 : public Duck
{
public:
    Duck1(FlyBehavior* fly, QuackBehavior* quack) : Duck(fly, quack) {}
};
相关推荐
白茶等风121382 分钟前
Unity 设计模式-单例模式(Singleton)详解
单例模式·设计模式
请叫我啸鹏4 分钟前
C++学习 - 03(单例模式)
c++·学习·单例模式
无空念9 分钟前
C++ STL - vector/list讲解及迭代器失效
开发语言·c++
雪的期许10 分钟前
Python/GoLang/Java 多环境管理工具 pyenv/goenv/jenv
开发语言·python·策略模式
白落微尘41 分钟前
string(11.23)
c++·算法
离歌漠1 小时前
C#调用C++ DLL方法之C++/CLI(托管C++)
c++·c#·clr
午言若1 小时前
C++ 中的模板特化和偏特化
c++
yyycqupt2 小时前
数据库连接池(二)
linux·数据库·c++·后端·单例模式
苏言の狗2 小时前
CCF认证202406-01 | 矩阵重塑(其一)
c语言·数据结构·c++·算法·矩阵
唐僧洗头爱飘柔95273 小时前
(Java并发编程——JUC)常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!文章全程笔记干货!!
java·设计模式·并发编程·juc·reentrantlock·顺序控制·生产者与消费者