模式——策略模式(Duck例子) C++实现"/>
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 nothingcout << "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 mutemallard->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;
}
输出:
角色:小精灵
使用武器:枪
更换武器
使用武器:刀
更多推荐
Head First设计模式——策略模式(Duck例子) C++实现
发布评论