首页 > 编程语言 >c/c++设计模式---策略模式

c/c++设计模式---策略模式

时间:2024-06-11 12:11:31浏览次数:29  
标签:Fighter 策略 ItemStrategy c++ --- new 设计模式 war prole

一个具体范例的逐步重构

Fighter.h

#ifndef __RIGHTER__
#define __RIGHTER__

////增加补充生命值道具(药品)
//enum ItemAddlife
//{
//    LF_BXD,  //补血丹
//    LF_DHD,  //大还丹
//    LF_SHD,  //守护丹
//};

class ItemStrategy;  //类前向声明

//战斗者父类
class Fighter
{
public:
    Fighter(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {}
    virtual ~Fighter() {}

public:
    /*
    void UseItem(ItemAddlife djtype) //吃药补充生命值
    {
        if (djtype == LF_BXD) //道具类型:补血丹
        {
            m_life += 200;//补充200点生命值
            //if (主角中毒)
            //{
            //    停止中毒状态,也就是主角吃药后不再中毒
            //}
            //if (主角处于狂暴状态)
            //{
            //    m_life += 400; //额外再补充400点生命值
            //    m_magic += 200; //魔法值也再补充200点
            //}
        }
        else if (djtype == LF_DHD) //道具类型:大还丹
        {
            m_life += 300;//补充300点生命值
        }
        else if (djtype == LF_SHD) //道具类型:守护丹
        {
            m_life += 500;//补充500点生命值
        }
        //.......其他的一些判断逻辑,略。。。。。。
    }
    */

public:
    void SetItemStrategy(ItemStrategy* strategy); //设置道具使用的策略
    void UseItem(); //使用道具
    int GetLife(); //获取人物生命值
    void SetLife(int life);  //设置人物生命值    

protected:
    int m_life;
    int m_magic;
    int m_attack;

    ItemStrategy* itemstrategy = nullptr; //C++11中支持这样初始化
};

//“战士”类,父类为Fighter
class F_Warrior :public Fighter
{
public:
    F_Warrior(int life, int magic, int attack) :Fighter(life, magic, attack) {}
};

//“法师”类,父类为Fighter
class F_Mage :public Fighter
{
public:
    F_Mage(int life, int magic, int attack) :Fighter(life, magic, attack) {}
};

#endif

Fighter.cpp

#include <iostream>
#include "Fighter.h"
#include "ItemStrategy.h"

using namespace std;

//设置道具使用的策略
void Fighter::SetItemStrategy(ItemStrategy* strategy)
{
    itemstrategy = strategy;
}

//使用道具(吃药)
void Fighter::UseItem()
{
    itemstrategy->UseItem(this);
}

//获取人物生命值
int Fighter::GetLife()
{
    return m_life;
}

//设置人物生命值
void Fighter::SetLife(int life)
{
    m_life = life;
}

ItemStrategy.h

#ifndef _ITEMSTRATEGY__
#define _ITEMSTRATEGY__

//道具策略类的父类
class ItemStrategy
{
public:
    virtual void UseItem(Fighter* mainobj) = 0;
     
};

//补血丹策略类
class ItemStrategy_BXD :public ItemStrategy
{
public:
    virtual void UseItem(Fighter* mainobj)
    {
        mainobj->SetLife(mainobj->GetLife() + 200);  //补充200点生命值
    }
};

//大还丹策略类
class ItemStrategy_DHD :public ItemStrategy
{
public:
    virtual void UseItem(Fighter* mainobj)
    {
        mainobj->SetLife(mainobj->GetLife() + 300);  //补充300点生命值
#include <iostream>
#include "Fighter.h"
#include "ItemStrategy.h"

#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) 

namespace _nmsp1
{    
    
}

int main()
{
/*
    Fighter* prole_war = new F_Warrior(1000, 0, 200); //这里没有采用工厂模式,如果主角很多,可以考虑采用工厂模式创建对象
    prole_war->UseItem(LF_DHD);

    delete prole_war;     
    */

    //创建主角
    Fighter* prole_war = new F_Warrior(1000, 0, 200);

    //吃一颗大还丹
    ItemStrategy* strategy = new ItemStrategy_DHD(); //创建大还丹策略
    prole_war->SetItemStrategy(strategy); //主角设置大还丹策略,准备吃大还丹
    prole_war->UseItem(); //主角吃大还丹

    //再吃一颗补血丹
    ItemStrategy* strategy2 = new ItemStrategy_BXD(); //创建补血丹策略
    prole_war->SetItemStrategy(strategy2);//主角设置补血丹策略,准备吃补血丹
    prole_war->UseItem(); //主角吃补血丹

    delete strategy;
    delete strategy2;
    delete prole_war;
    
    return 0;
}
}

 

    }
};


//守护丹策略类
class ItemStrategy_SHD :public ItemStrategy
{
public:
    virtual void UseItem(Fighter* mainobj)
    {
        mainobj->SetLife(mainobj->GetLife() + 500);  //补充500点生命值
    }
};

#endif

myproject.cpp

 

#include <iostream>
#include "Fighter.h"
#include "ItemStrategy.h"

#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) 

namespace _nmsp1
{    
    
}

int main()
{

/*
    Fighter* prole_war = new F_Warrior(1000, 0, 200); //这里没有采用工厂模式,如果主角很多,可以考虑采用工厂模式创建对象
    prole_war->UseItem(LF_DHD);

    delete prole_war;     
    */

    //创建主角
    Fighter* prole_war = new F_Warrior(1000, 0, 200);

    //吃一颗大还丹
    ItemStrategy* strategy = new ItemStrategy_DHD(); //创建大还丹策略
    prole_war->SetItemStrategy(strategy); //主角设置大还丹策略,准备吃大还丹
    prole_war->UseItem(); //主角吃大还丹

    //再吃一颗补血丹
    ItemStrategy* strategy2 = new ItemStrategy_BXD(); //创建补血丹策略
    prole_war->SetItemStrategy(strategy2);//主角设置补血丹策略,准备吃补血丹
    prole_war->UseItem(); //主角吃补血丹

    delete strategy;
    delete strategy2;
    delete prole_war;
    
    return 0;


}
 策略(Strategy)模式     //(1)一个具体实现范例的逐步重构     //补血道具(药品):       //a:补血丹:补充200点生命值       //b:大还丹:补充300点生命值       //c:守护丹:补充500点生命值     //Fighter,F_Warrior,F_Mage     //策略  设计模式的定义:定义一系列算法(策略类),将每个算法封装起来,让它们可以相互替换。换句话说,策略模式通常把一系列算法        // 封装到一系列具体策略类中来作为抽象策略类的子类,然后根据实际需要使用这些子类。     //策略类中的三种角色     //a)Context(环境类):该类中维持着一个对抽象策略类的指针或引用。这里指Fighter类。     //b)Stategy(抽象策略类):定义所支持的算法的公共接口,是所有策略类的父类。这里指ItemStrategy类。     //c)ConcreteStrategy(具体策略类):抽象策略类的子类,实现抽象策略类中声明的接口。这里指ItemStrategy_BXD、ItemStrategy_DHD、ItemStrategy_SHD。     //策略类的优点:     //a)以扩展的方式支持对未来的变化,符合开闭原则。       //遇到大量不稳定的if条件分支 或者switch分支,就要优先考虑是否可以通过策略模式来解决。策略模式是if,switch条件分支的杀手。     //b)算法可以被复用。     //c)策略模式可以看成是类继承的一种替代方案。通过为环境类对象指定不同的策略,就可以改变环境类对象的行为。     //策略类的缺点:     //a)导致引入许多新策略类;     //b)使用策略时,调用者(main主函数)必须熟知所有策略类的功能并根据实际需要自行决定使用哪个策略类。  
#include <iostream>
#include "Fighter.h"
#include "ItemStrategy.h"

#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) 

namespace _nmsp1
{    
    class M_Undead //亡灵类怪物
    {
    public:
        void getinfo()
        {
            cout << "这是一只亡灵类怪物" << endl;
        }
        //......其他代码略
    };

    class M_Element //元素类怪物
    {
    public:
        void getinfo()
        {
            cout << "这是一只元素类怪物" << endl;
        }
        //......其他代码略
    };

    class M_Mechanic //机械类怪物
    {
    public:
        void getinfo()
        {
            cout << "这是一只机械类怪物" << endl;
        }
        //......其他代码略
    };

    //战士主角
    class F_Warrior
    {
    public:
        void attack_enemy_undead(M_Undead* pobj) //攻击亡灵类怪物
        {
            //进行攻击处理......
            pobj->getinfo(); //可以调用亡灵类怪物相关的成员函数
        }

    public:
        void attack_enemy_element(M_Element* pobj) //攻击元素类怪物
        {
            //进行攻击处理......
            pobj->getinfo(); //可以调用元素类怪物相关的成员函数
        }

        //其他代码略......
    };
}
namespace _nmsp2
{
    class Monster //作为所有怪物类的父类(抽象层)
    {
    public:
        virtual void getinfo() = 0; //纯虚函数
        virtual ~Monster() {} //做父类时析构函数应该为虚函数
    };
    class M_Undead :public Monster//亡灵类怪物
    {
    public:
        virtual void getinfo()
        {
            cout << "这是一只亡灵类怪物" << endl;
        }
        //......其他代码略
    };

    class M_Element :public Monster//元素类怪物
    {
    public:
        virtual void getinfo()
        {
            cout << "这是一只元素类怪物" << endl;
        }
        //......其他代码略
    };

    class M_Mechanic :public Monster//机械类怪物
    {
    public:
        virtual void getinfo()
        {
            cout << "这是一只机械类怪物" << endl;
        }
        //......其他代码略
    };

    //战士主角
    class F_Warrior
    {
    public:
        void attack_enemy(Monster* pobj) //攻击怪物
        {
            //进行攻击处理......
            pobj->getinfo(); //可以调用怪物相关的成员函数
        }
        //其他代码略......
    };
}

int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口
        
    //第4章 策略(Strategy)模式
    //(1)一个具体实现范例的逐步重构
    //补血道具(药品):
      //a:补血丹:补充200点生命值
      //b:大还丹:补充300点生命值
      //c:守护丹:补充500点生命值
    //Fighter,F_Warrior,F_Mage
    //策略  设计模式的定义:定义一系列算法(策略类),将每个算法封装起来,让它们可以相互替换。换句话说,策略模式通常把一系列算法
       // 封装到一系列具体策略类中来作为抽象策略类的子类,然后根据实际需要使用这些子类。
    //策略类中的三种角色
    //a)Context(环境类):该类中维持着一个对抽象策略类的指针或引用。这里指Fighter类。
    //b)Stategy(抽象策略类):定义所支持的算法的公共接口,是所有策略类的父类。这里指ItemStrategy类。
    //c)ConcreteStrategy(具体策略类):抽象策略类的子类,实现抽象策略类中声明的接口。这里指ItemStrategy_BXD、ItemStrategy_DHD、ItemStrategy_SHD。
    //策略类的优点:
    //a)以扩展的方式支持对未来的变化,符合开闭原则。
      //遇到大量不稳定的if条件分支 或者switch分支,就要优先考虑是否可以通过策略模式来解决。策略模式是if,switch条件分支的杀手。
    //b)算法可以被复用。
    //c)策略模式可以看成是类继承的一种替代方案。通过为环境类对象指定不同的策略,就可以改变环境类对象的行为。
    //策略类的缺点:
    //a)导致引入许多新策略类;
    //b)使用策略时,调用者(main主函数)必须熟知所有策略类的功能并根据实际需要自行决定使用哪个策略类。

    //(2)依赖倒置原则:Dependency Inversion Principle,简称DIP
     //是面向独享设计的主要实现方法,同时 也是实现开闭原则的重要实现途径。
    //解释:高层组件不应该依赖于低层(具体实现类),两者都应该依赖于抽象层。
    //范例:工厂模式时,亡灵类M_Undead,元素类M_Element,机械类M_Mechanic。








    /*
    Fighter* prole_war = new F_Warrior(1000, 0, 200); //这里没有采用工厂模式,如果主角很多,可以考虑采用工厂模式创建对象
    prole_war->UseItem(LF_DHD);

    delete prole_war;     
    */

    /*
    //创建主角
    Fighter* prole_war = new F_Warrior(1000, 0, 200);

    //吃一颗大还丹
    ItemStrategy* strategy = new ItemStrategy_DHD(); //创建大还丹策略
    prole_war->SetItemStrategy(strategy); //主角设置大还丹策略,准备吃大还丹
    prole_war->UseItem(); //主角吃大还丹

    //再吃一颗补血丹
    ItemStrategy* strategy2 = new ItemStrategy_BXD(); //创建补血丹策略
    prole_war->SetItemStrategy(strategy2);//主角设置补血丹策略,准备吃补血丹
    prole_war->UseItem(); //主角吃补血丹

    delete strategy;
    delete strategy2;
    delete prole_war;
    */

    /*
    _nmsp1::M_Undead* pobjud = new _nmsp1::M_Undead();
    _nmsp1::F_Warrior* pobjwar = new _nmsp1::F_Warrior();
    pobjwar->attack_enemy_undead(pobjud); //攻击一只亡灵类怪物

    _nmsp1::M_Element* pobjelm = new _nmsp1::M_Element();
    pobjwar->attack_enemy_element(pobjelm); //攻击一只元素类怪物

    //资源释放
    delete pobjwar;
    delete pobjud;
    delete pobjelm;*/

    _nmsp2::Monster* pobjud = new _nmsp2::M_Undead();
    _nmsp2::F_Warrior* pobjwar = new _nmsp2::F_Warrior();
    pobjwar->attack_enemy(pobjud); //攻击一只亡灵类怪物

    _nmsp2::Monster* pobjelm = new _nmsp2::M_Element();
    pobjwar->attack_enemy(pobjelm); //攻击一只元素类怪物

    //资源释放
    delete pobjwar;
    delete pobjud;
    delete pobjelm;
    
    return 0;
}

     

 

 

 

 

标签:Fighter,策略,ItemStrategy,c++,---,new,设计模式,war,prole
From: https://www.cnblogs.com/bwbfight/p/18241827

相关文章

  • VsCode中snippets --- vue自定义代码片段
    vue自定义代码片段Vue2代码片段1、点击文件→首选项→选择配置用户代码片段2、在弹出这个窗口中选择新建全局代码片段文件3、选择后在此处输入文件名后按‘Enter’键确定4、点击确定后会生成以下文件5、替换成以下vue2代码片段6、使用代码片段Vue3代码片段使用defineC......
  • 3G2A5-ID218 Input Module
    变频器电源变频器电源主要用于交流电机的变频调速,其在电气传动系统中占据的地位日趋重要,已获得巨大的节能效果。变频器电源主电路均采用交流-直流-交流方案。工频电源通过整流器变成固定的直流电压,然后由大功率晶体管或IGBT组成的PWM高频变换器, 将直流电压逆变成电压、频......
  • 《DSP开发》TMS320F28XX-ADC模块
    1.1、特征1.2、功能框图2.1、ADC模块配置1、ADC时钟使能。ADC时钟没有使能的话,后续对ADC相关寄存器的配置值虽然被写入,但实际不会生效。2、校准ADC参考、DAC偏移和内部振荡器。Device_cal();3、配置ADC模块转换误差、参考模式、参考基准、时钟分频、ADC中断触发时刻,最......
  • 伺服电机A06B-0115-B075
    伺服电机A06B-0115-B075数字控制系统简称数控系统,英文名称为Numerical Control System,早期是与计算机并行发展演化的,用于控制自动化加工设备的,由电子管和继电器等硬件构成具有计算能力的专用控制器的称为硬件数控(Hard NC)。20世纪70年代以后,分离的硬件电子元件逐步由集成度......
  • Java实现定时任务的几种方式 ---------内附源码
      在我们日常项目开发过程中,经常用到定时任务,如果使用不当甚至会造成资源损毁,定时任务使用不当,会导致发出大量重复操作,可能会造成巨大的后果。  所以,系统的学习一下定时任务,是非常有必要的。这篇文章就带大家整体梳理学习一下Java领域中常见的几种定时任务实现。 ......
  • Python实现简单的图形化界面 -----Qt GUI
    一、Qt简介以及安装简单介绍Qt以及响应的环境安装Qt简介Qt是一个跨平台的C++开发库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序,当然也可以开发不带界面的命令行(CommandUserInterface,CUI)程序。支持通用操作系统Windows、Linux、Unix,智能手机系统Andro......
  • 《DX12龙书》-第一个例程出现的报错:error: 应用程序请求的操作依赖于已缺失或不匹配的
    《DX12龙书》|《Introductionto3DGameProgrammingwithDirectX12》|《DirectX123D游戏开发实践》个人电脑环境Window11;VisualStudio2022出现问题主要原因:书中代码的环境是:Windows10;VS2015,在不同环境上运行难免会出现一些错误。问题一:C2102&要求左值错......
  • c/c++设计模式---状态模式
    一个基本的状态转换范例monster.h#ifndef_MONSTER__#define_MONSTER__classMonsterStatus;//类前向声明//怪物类classMonster{public:Monster(intlife);~Monster();public:intGetLife()//获取怪物血量{returnm_life;}......
  • C++11 运算符的优先级分组和结合性
    本文汇总了C++11中的运算符的含义、优先级分组及其结合性。如果两个运算符用于同一个操作数,首先应用优先极高的。如果两个运算符优先级相同,按结合性规则决定应用那个运算符。同一组中的运算符优先级和结合性相同,无论先左后右(L-R),还是先右后左(R-L)。运算符含义优先级分组......
  • Zgo - maps
     packagemainimport("fmt""maps")funcdelete(kstring,vint)bool{returnv%2!=0}funcequal(v1int,v2float64)bool{returnfloat64(v1)==v2}funcmain(){m:=map[string]int{"one......