设计模式(二) —— 策略模式

百度定义

策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

组成

1>抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
2>具体策略角色:包装了相关的算法和行为。
3>环境角色:持有一个策略类的引用,最终给客户端调用。

优缺点

优点:

1、 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。
2、 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

缺点:

1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2、 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

实例化

现假设某一爱动物人士,对功能型小动物颇有研究,开设了一家动物的展览馆,向前来观看的游客展示他们喜爱的动物的能力(哈哈哈,我这脑洞)
定义

class animal
{
public:
    virtual void behavior() = 0;
};
//杜鹃
class Cuckoo : public animal
{
    void behavior() {cout<<"I can Sing"<<endl;}
};

//小狗
class Dog : public animal 
{
    void behavior() {cout<<"I can protect the family"<<endl;}
};

//猴子

class Monkey : public animal
{
    void behavior() {cout<<"I can perform"<<endl;}
};

上诉代码给出了behavior算法的定义,基类animal是个抽象类 ,声明了behavior算法,在各子类中给出实际的实现。

环境角色

环境角色实际为触发这个behavior算法的对象,这里定义为主人(这个 爱动物人士),由游览者具体指定后,主人触发。
这里给出了 master的定义,master的定义很关键。master的实现方式直接影响了客户的使用方式,其关键在于如何指定behavior算法。

方式一 直接通过参数指定,直接传入一个behavior算法指针

//主人可以命令这些动物展示它们的能力
class Master
{
private:  
    animal *m_Animal;  
public:  
    Master(animal *animal_tmp) {m_Animal = animal_tmp;}  
    ~Master() { delete m_Animal; }  
    void Order() {m_Animal->behavior();} 
};

如果用这种方式,客户就需要知道这些behavior算法的具体定义。只能以下面这种方式使用,可以看到暴露了太多的细节。

int main() 
{
    Monkey* a_Monkey = new Monkey();
    Master* a_Master = new Master(a_Monkey);
    a_Master->Order();
    return 0;
}

方式二
也是直接通过参数指定,只不过不是传入指针,而是一个标签。这样客户只要知道behavior算法的相应标签即可,而不需要知道behavior算法的具体定义。


enum AN_TYPE
{
    BIRD = 0,
    DOG,
    MOK,
    TYPE_MAX
};

class Master 
{
private:
    animal* m_Animal;

public:  
    Master(enum AN_TYPE BIR)   
    {   
    switch (BIR) {
        case 0:
        m_Animal = new Cuckoo;
        break;
        case 1:
        m_Animal = new Dog;
        break;
        case 2:
        m_Animal = new Monkey;
        break;
        default:
        break;
    }
    }  
    ~Master() { delete m_Animal; }  
    void Order() { m_Animal->behavior(); }  

};

跟方式一比起来 方式二更加方便,其实看过我上一篇文章的不难发现,方式二其实是简单工厂模式跟策略模式的结合,算法的定义使用的是策略模式,而master的定义使用了简单工厂模式

以上,策略模式已介绍完毕

猜你喜欢

转载自blog.csdn.net/breakpoints_/article/details/80094929