C++设计模式之策略模式

概要

策略模式主要针对那种,有多种算法和可能的项目情况, 比如说一个人去旅行,然后可以有多种方式选择, 坐飞机, 坐火车, 坐轮船, 然后每一种方式又有各自的价格, 所花费的时间, 能在哪里去坐。 这时,我们又需要做出选择。

又比如另外一种情况, 公司做一款游戏, 比如说来画鸭子, 需求是鸭子声音有大的,有小的, 鸭子有飞得高的,有飞得低的,而且还需要可任意组合,这时就要求我们选择对应的策略,下面的简单例子就是针对这个的。

效果图

策略1

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Duck *duck = new Duck(new HightFly(), new HeightVoice());
 //   Duck *duck = new Duck(new LowFly(), new HeightVoice());
 //   Duck *duck = new Duck(new LowFly(), new LowVoice());
//    Duck *duck = new Duck(new HightFly(), new LowVoice());
    duck->fly();
    duck->voice();
    return a.exec();
}

这里写图片描述


策略2

//    Duck *duck = new Duck(new HightFly(), new HeightVoice());
    Duck *duck = new Duck(new LowFly(), new HeightVoice());
 //   Duck *duck = new Duck(new LowFly(), new LowVoice());
//    Duck *duck = new Duck(new HightFly(), new 
LowVoice());

这里写图片描述


策略3

//    Duck *duck = new Duck(new HightFly(), new HeightVoice());
//    Duck *duck = new Duck(new LowFly(), new HeightVoice());
    Duck *duck = new Duck(new LowFly(), new LowVoice());
//    Duck *duck = new Duck(new HightFly(), new 
LowVoice());

这里写图片描述

策略4

//    Duck *duck = new Duck(new HightFly(), new HeightVoice());
//    Duck *duck = new Duck(new LowFly(), new HeightVoice());
//    Duck *duck = new Duck(new LowFly(), new LowVoice());
    Duck *duck = new Duck(new HightFly(), new 
LowVoice());

这里写图片描述

主要代码

这里写图片描述

//duck.h

#ifndef DUCK_H
#define DUCK_H
#include "flyhavior.h"
#include "voicehavior.h"

#include "lowfly.h"
#include "heightvoice.h"

class Duck
{
public:
    Duck(FlyHavior* flyHavior, VoiceHavior* voiceHavior);
    void fly();
    void voice();

    void setFlyHavior(FlyHavior* flyHavior);
    void setVoiceHavior(VoiceHavior* voiceHavior);

private:
    FlyHavior *m_flyHavior;
    VoiceHavior *m_voiceHavior;
};

#endif // DUCK_H

//duck.cpp

#include "duck.h"

Duck::Duck(FlyHavior* flyHavior, VoiceHavior* voiceHavior)
    :m_flyHavior(flyHavior),
     m_voiceHavior(voiceHavior)
{
}

void Duck::fly()
{
    m_flyHavior->fly();
}

void Duck::voice()
{
    m_voiceHavior->voice();
}

void Duck::setFlyHavior(FlyHavior* flyHavior)
{
    m_flyHavior = flyHavior;
}

void Duck::setVoiceHavior(VoiceHavior* voiceHavior)
{
    m_voiceHavior = voiceHavior;
}

//flyhavior.h

#ifndef FLYHAVIOR_H
#define FLYHAVIOR_H
#include <iostream>
using namespace::std;

class FlyHavior
{
public:
    FlyHavior();

    virtual ~FlyHavior();

    virtual void fly();
};

#endif // FLYHAVIOR_H

//flyhavior.cpp

#include "flyhavior.h"

FlyHavior::FlyHavior()
{
}

FlyHavior::~FlyHavior()
{

}

void FlyHavior::fly()
{

}

//voicehavior.h

#ifndef VOICEHAVIOR_H
#define VOICEHAVIOR_H
#include <iostream>
using namespace::std;

class VoiceHavior
{
public:
    VoiceHavior();
    virtual ~VoiceHavior();
    virtual void voice();
};

#endif // VOICEHAVIOR_H

//voicehavior.cpp

#include "voicehavior.h"

VoiceHavior::VoiceHavior()
{
}

VoiceHavior::~VoiceHavior()
{

}

void VoiceHavior::voice()
{

}

//lowfly.h

#ifndef LOWFLY_H
#define LOWFLY_H

#include "flyhavior.h"

class LowFly : public FlyHavior
{
public:
    LowFly();
    void fly();
};

#endif // LOWFLY_H

//lowfly.cpp

#include "lowfly.h"

LowFly::LowFly()
{
}

void LowFly::fly()
{
    cout << "LowFly::LowFly()" << endl;
}

//hightfly.h

#ifndef HIGHTFLY_H
#define HIGHTFLY_H

#include "flyhavior.h"

class HightFly : public FlyHavior
{
public:
    HightFly();
    void fly();
};

#endif // HIGHTFLY_H

//hightfly.cpp

#include "hightfly.h"

HightFly::HightFly()
{
}

void HightFly::fly()
{
    cout << "HightFly::HightFly()" << endl;
}

部分解析

上面的主要代码是把鸭子duck作为客户端,在初始化对象时,可以进行属性的选择,如main函数里面的:

    Duck *duck = new Duck(new HightFly(), new HeightVoice());
//    Duck *duck = new Duck(new LowFly(), new HeightVoice());
//    Duck *duck = new Duck(new LowFly(), new LowVoice());
//    Duck *duck = new Duck(new HightFly(), new 
LowVoice());

而duck的初始化函数为:

Duck::Duck(FlyHavior* flyHavior, VoiceHavior* voiceHavior)
    :m_flyHavior(flyHavior),
     m_voiceHavior(voiceHavior)
{
}

FlyHavior 是飞得高或低的父类,HightFly, LowFly 这两个类都继承于FlyHavior

VoiceHavior 是声音大还是小的父类, HeightVoice, LowVoice这两个类都继承于VoiceHavior

在两个父类中, 它们的析构函数都为虚函数,这样是为了防止内存泄漏。

比如这么一种情况:
VoiceHavior *voiceHavior = new HeightVoice();
delete voiceHavior;
如果VoiceHavior的构造函数不为虚函数,则会出现只进行父类的析构,而不进行子类的析构, 但如果VoiceHavior 构造函数为虚函数,则父类与子类同时析构。

再来看,我们把飞得高低的属性和声音大小的属性抽象了两个属性
VoiceHavior , FlyHavior ,需要增加其它的策略则直接继承于它们,这样就减少了条件语句的判断。

在进行属性设置时,采用了上下转型的方式把子类的对象进行父类的向上转型,这样就可以达到简单方便地切换各个属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小K小Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值