Head First设计模式——策略模式(Duck例子) C++实现

1. 使用将fly、quack行为从类中提取出来,作为interface

思路:将fly、quack行为从类中提取出来,作为interface,有相关功能的子类去实现对应的接口。
#include<iostream>
using namespace std;

// super class :Duck类
class Duck
{
private:
    /* data:一些鸭子的属性 */
    string kind; //种类 eg.

public:
    Duck(string kind)
    {
        this->kind = kind;
    }
    ~Duck(){}

    virtual void display(){}
    void swim() {
        cout << "游泳"<< endl;
    }

    // 虚函数,子类不要求一定实现
    virtual void quack(){};
    virtual void fly(){};
};


// 子类:MallardDuck
class MallardDuck : public Duck
{
private:
    /* data */
public:
    MallardDuck(string kind):Duck(kind){}
    ~MallardDuck(){}

    void display(){
        cout<<"种类:MallardDuck"<<endl;
    }

    // 实现
    void quack(){
        cout << "嘎嘎嘎" << endl;
    }
};

//子类2
class ThomdDuck : public Duck
{
private:
    /* data */
public:
    ThomdDuck(string kind):Duck(kind){}
    ~ThomdDuck(){}

    void display(){
        cout<<"种类:ThomdDuck"<<endl;
    }

    // 实现
    void quack(){
        cout << "嘎嘎嘎" << endl;
    }
    void fly(){
        cout << "飞行" << endl;
    }
};

//封装一下
void DuckDisplay(Duck* d){
    d->display();
    d->fly();
    d->quack();
    d->swim();
}

int main(){
    MallardDuck md("Mallard");
    md.display();
    md.fly();
    md.quack();
    md.swim();
    ThomdDuck td("Thomd");
    DuckDisplay(&td); //封装一下display方法吧

    cout << endl;
    //或者使用多态
    Duck* d = new MallardDuck("Mallard");
    d->display();
    d->fly();
    d->quack();
    d->swim();
    d = new ThomdDuck("Thomd");
    DuckDisplay(d); //封装一下吧

	if(d!=NULL){
        delete d;
    }

    return 0;
}
输出:
种类:MallardDuck
嘎嘎嘎
游泳
种类:ThomdDuck
飞行
嘎嘎嘎
游泳

种类:MallardDuck
嘎嘎嘎
游泳
种类:ThomdDuck
飞行
嘎嘎嘎
游泳
使用这种方式的利弊书中有具体讲解,这里就不再重复了,再看策略模式的实现。

2.策略模式的实现

#ifndef _V2DUCK_H
#define _V2DUCK_H

#include<iostream>
using namespace std;


//C++没有接口的定义,使用虚函数来实现接口功能
class FlyBehavior
{
public:
    FlyBehavior(/* args */){}
    ~FlyBehavior(){}

    //飞行行为列表
    virtual void fly(){};
};

class FlyWithWings:public FlyBehavior
{
private:
    /* data */
public:
    FlyWithWings(/* args */){}
    ~FlyWithWings(){}

    // 实现用翅膀飞行
    void fly(){
        cout << "用翅膀飞行"<<endl;
    }
};

class FlyNoWay:public FlyBehavior
{
private:
    /* data */
public:
    FlyNoWay(/* args */){}
    ~FlyNoWay(){}

    void fly(){
        // do nothing
        cout << "cannot fly"<<endl;
    }
};

//增加飞行类,借助火箭飞行
class FlyRocketPowered:public FlyBehavior
{
private:
    /* data */
public:
    FlyRocketPowered(/* args */){}
    ~FlyRocketPowered(){}

    void fly(){
        cout << "借助火箭推力飞行"<<endl;
    }
};



class QuackBehavior
{
private:
    /* data */
public:
    QuackBehavior(/* args */){}
    ~QuackBehavior(){}

    virtual void quack() {};
};

class Quack:public QuackBehavior
{
private:
    /* data */
public:
    Quack(/* args */){}
    ~Quack(){}

    void quack(){
        cout<<"嘎嘎嘎的叫声"<<endl;
    }
};

class SQuack:public QuackBehavior
{
private:
    /* data */
public:
    SQuack(/* args */){}
    ~SQuack(){}

    void quack(){
        cout<<"吱吱吱的叫声"<<endl;
    }
};

class MuteQuack :public QuackBehavior
{
private:
    /* data */
public:
    MuteQuack(/* args */){}
    ~MuteQuack(){}

    void quack(){
        cout<<"没有叫声"<<endl;
    }
};

class Duck
{
private:
    /* data */

public:
    string kind;
    FlyBehavior* fly_behavior;       //使用组合的方式,而不是继承
    QuackBehavior* quack_behavior;

public:
    Duck(string kind){
        // cout<<"品种:"<<kind<<endl;
    }
    ~Duck(){}

    void performFly(){
        // this->fly_behavior.fly();
        this->fly_behavior->fly();
    }
    void performQuack(){
        // this->quack_behavior.quack();
        this->quack_behavior->quack();
    }

    virtual void display(){
        cout<<"这是鸭子基类"<<endl;
    }
    void swim(){
        cout<<"all ducks can swim"<<endl;
    }

    //进阶:动态设定行为
    void setFlyBehavior(FlyBehavior* fb){
        this->fly_behavior = fb;
    }

    void setQuackBehavior(QuackBehavior* qb){
        this->quack_behavior = qb;
    }
};
//头文件内容
#endif
#include "v2duck.hpp"


//MallardDuck
class MallardDuck:public Duck
{
private:
    /* data */
public:
    MallardDuck():Duck("MallardDuck"){
        fly_behavior =new FlyWithWings();
        quack_behavior =new Quack();
    }
    ~MallardDuck(){}

    void display(){
        cout<<"品种:MallardDuck"<<endl;
    }
};



int main(){
    Duck* mallard = new MallardDuck();
    mallard->display();
    mallard->performFly();
    mallard->performQuack();

    //动态设置:make mallard flyByRocket,and quack mute
    mallard->setFlyBehavior(new FlyRocketPowered());
    mallard->setQuackBehavior(new MuteQuack());
    mallard->performFly();
    mallard->performQuack();
	
	if(mallard!=NULL){
        delete mallard;
    }

    return 0;
}
输出:
品种:MallardDuck
用翅膀飞行
嘎嘎嘎的叫声
借助火箭推力飞行
没有叫声

3.游戏思考题

其实和2.基本一致。
#ifndef _GAME_H
#define _GAME_H

#include<iostream>
using namespace std;

//武器行为类
class WeaponBehavior
{
private:
    /* data */
public:
    WeaponBehavior(/* args */){}
    ~WeaponBehavior(){}

    virtual void useWeapon(){}
};

//武器1:枪
class Gun:public WeaponBehavior
{
private:
    /* data */
public:
    Gun(/* args */){}
    ~Gun(){}

    void useWeapon(){
        cout<<"使用武器:枪"<<endl;
    }
};

//武器2:刀
class Knife:public WeaponBehavior
{
private:
    /* data */
public:
    Knife(/* args */){}
    ~Knife(){}

    void useWeapon(){
        cout<<"使用武器:刀"<<endl;
    }
};


//游戏角色类
class GameRole
{
private:
    /* data */
public:
    string role_name;
    WeaponBehavior* weaponBh;

    GameRole(string role_name){
        this->role_name = role_name;
    }
    ~GameRole(){}

    void useWeapon(){
        this->weaponBh->useWeapon();
    }
    //更换武器
    void setWeapon(WeaponBehavior* new_weapon){
        this->weaponBh = new_weapon;
        cout<<"更换武器"<<endl;  // 如果这里想有更换武器的 名称,应该可以在对应的行为类里加一个武器名称,然后在这里读出来。
    }

    virtual void display(){
        cout << "这是角色基类,请选择具体角色"<<endl;
    }
};

#endif
#include "game.hpp"

//具体角色:小精灵
class Spirit:public GameRole
{
private:
    /* data */
public:
    Spirit():GameRole("小精灵"){
        weaponBh = new Gun();
    }
    ~Spirit(){}

    void display(){
        cout <<"角色:小精灵"<<endl;
    }
};



int main(){
    GameRole* spirit = new Spirit();
    spirit->display();
    spirit->useWeapon();//使用当前的武器
    spirit->setWeapon(new Knife()); //更换武器为 刀
    spirit->useWeapon();//使用武器

    return 0;
}
输出:
角色:小精灵
使用武器:枪
更换武器
使用武器:刀
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在TypeScript中,可以使用类和多态性来实现策略模式。 以下是一个使用TypeScript实现策略模式的示例: ```typescript // 定义一个策略接口 interface FlyStrategy { fly(): void; } // 实现具体的飞行策略类 class FlyWithWings implements FlyStrategy { fly() { console.log("用翅膀飞行"); } } class FlyNoWay implements FlyStrategy { fly() { console.log("无法飞行"); } } // 定义一个鸭子类 class Duck { private flyStrategy: FlyStrategy; constructor(flyStrategy: FlyStrategy) { this.flyStrategy = flyStrategy; } // 设置飞行策略 setFlyStrategy(flyStrategy: FlyStrategy) { this.flyStrategy = flyStrategy; } // 执行飞行 performFly() { this.flyStrategy.fly(); } } // 使用策略模式 const duck = new Duck(new FlyWithWings()); duck.performFly(); // 输出:用翅膀飞行 duck.setFlyStrategy(new FlyNoWay()); duck.performFly(); // 输出:无法飞行 ``` 在上面的示例中,我们定义了一个`FlyStrategy`接口,它包含一个`fly`方法。然后,我们实现了两个具体的飞行策略类`FlyWithWings`和`FlyNoWay`,它们分别实现了`FlyStrategy`接口。接下来,我们定义了一个`Duck`类,它包含一个`flyStrategy`属性,用于存储当前的飞行策略。`Duck`类还包含了`setFlyStrategy`和`performFly`方法,用于设置和执行飞行策略。 通过使用策略模式,我们可以在运行时选择不同的飞行策略,而不需要修改`Duck`类的代码。这样,我们可以实现算法的变化独立于使用算法的客户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值