欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式之策略模式

程序员文章站 2022-06-13 12:52:03
...

转载自 zsh’s 颓废史 www.404notfind.xyz

查看目录请点人家 ˙ω˙

模拟鸭子

Joe上班的公司做了一套相当成功的模拟鸭子游戏:SimDuck。游戏中会出各种鸭子。用OO的方式设计,会游泳,呱叫。
设计模式之策略模式

现在我们得让鸭子能飞

Joe直接在父类中添加了fly()方法
设计模式之策略模式

但是问题出现

出现了一只会叫的橡皮鸭RubberDuck
设计模式之策略模式
因为橡皮鸭继承父类,所以就自带fly()方法,但这是不合理的
可能,可以将fly()设置为虚函数,这样在子类中重写fly就可以了
但是,这样重复的代码会变得很多,可能每出现一个新子类都要覆盖一下这个方法。(可能头发都是这么秃的哈哈)

so?应该怎么做才好

分开变化和不变的部分(这里先只把fly当作变化的部分,偷懒嘿嘿)
关键思路,将飞行fly动作委托(delegate)给其它人处理
设计模式之策略模式
新建了一个FlyBehavior的接口(抽象基类),并在Duck中使用;
注意抽象基类无法实例化,只能声明成指针;
下面代码阐述了主要思想(我偷懒没有写析构,注意new出来的要delete,我为了代码长度没写,其实是懒QAQ)
setfly()方法可以更换飞行方式

#include<iostream>
using namespace std;
//---------------------------------------------
#include<iostream>
using namespace std;
//---------------------------------------------
class FlyBehavior{//飞行接口/抽象基类
public:
    virtual void fly()=0;
};
class FlyWithWings:public FlyBehavior{
public:
    virtual void fly(){
        cout<<"FlyWithWings"<<endl;
    }
};
class FlyNoWay:public FlyBehavior{
public:
    virtual void fly(){
        cout<<"i can't fly"<<endl;
    }
};
//----------------------------------------------
class Duck{//鸭子的抽象基类/父类
public:
    FlyBehavior * flyBehavior;//注意这里是指针哦
    virtual void performfly()=0;
    virtual void setfly(FlyBehavior * wht)=0;

};
class ADuck:public Duck{
public:
    ADuck(){
        flyBehavior = new FlyWithWings();
    }
    virtual void performfly(){
        flyBehavior->fly();
    }
    virtual void setfly(FlyBehavior * wht){
        flyBehavior = wht;
    }

};
//---------------------------------------------
int main(){
    Duck * yazi;
    yazi = new ADuck();
    yazi->performfly();
    yazi->setfly(new FlyNoWay());
    yazi->performfly();
    return 0;
}
/*out
FlyWithWings
i can't fly
*/

策略模式——定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。