《C++新经典设计模式》之第4章 策略模式
 
  
 
 
策略模式.cpp
 
#include <iostream>
#include <memory>
using namespace std;
namespace ns0
{
    enum ItemAddlife 
    {
        LF_BXD, 
        LF_DHD, 
        LF_SHD, 
    };
    class Fighter
    {
    protected:
        int m_life; 
        int m_magic;
        int m_attack;
    public:
        Fighter(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
        virtual ~Fighter() {}
    public:
        void UseItem(ItemAddlife djtype) 
        {
            switch (djtype) 
            {
            case LF_BXD:       
                m_life += 200; 
                
                
                
                
                
                {
                    m_life += 400;  
                    m_magic += 200; 
                }
                break;
            case LF_DHD:       
                m_life += 300; 
                break;
            case LF_SHD:       
                m_life += 500; 
                break;
            }
        }
    };
    class F_Warrior : public Fighter 
    {
    public:
        F_Warrior(int life, int magic, int attack) : Fighter(life, magic, attack) {}
    };
    class F_Mage : public Fighter 
    {
    public:
        F_Mage(int life, int magic, int attack) : Fighter(life, magic, attack) {}
    };
}
namespace ns1
{
    class Fighter;
    class ItemStrategy 
    {
    public:
        virtual ~ItemStrategy() {}
        virtual void UseItem(Fighter *const mainobj) = 0;
    };
    
    class Fighter
    {
        shared_ptr<ItemStrategy> itemstrategy;
    protected:
        int m_life; 
        int m_magic;
        int m_attack;
    public:
        Fighter(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
        virtual ~Fighter() {}
    public:
        void SetItemStrategy(const shared_ptr<ItemStrategy> &strategy) { itemstrategy = strategy; } 
        void UseItem() { itemstrategy->UseItem(this); }                                             
        int GetLife() const { return m_life; }
        void SetLife(int life) { m_life = life; }
    };
    class F_Warrior : public Fighter 
    {
    public:
        F_Warrior(int life, int magic, int attack) : Fighter(life, magic, attack) {}
    };
    class F_Mage : public Fighter 
    {
    public:
        F_Mage(int life, int magic, int attack) : Fighter(life, magic, attack) {}
    };
    class ItemStrategy_BXD : public ItemStrategy 
    {
    public:
        void UseItem(Fighter *const mainobj) override { mainobj->SetLife(mainobj->GetLife() + 200); }
    };
    class ItemStrategy_DHD : public ItemStrategy 
    {
    public:
        void UseItem(Fighter *const mainobj) override { mainobj->SetLife(mainobj->GetLife() + 300); }
    };
    class ItemStrategy_SHD : public ItemStrategy 
    {
    public:
        void UseItem(Fighter *const mainobj) override { mainobj->SetLife(mainobj->GetLife() + 500); }
    };
}
namespace ns2
{
    class M_Undead 
    {
    public:
        void getinfo() const { cout << "M_Undead" << endl; }
    };
    class M_Element 
    {
    public:
        void getinfo() const { cout << "M_Element" << endl; }
    };
    class M_Mechanic 
    {
    public:
        void getinfo() const { cout << "M_Mechanic" << endl; }
    };
    class F_Warrior 
    {
    public:
        void attack_enemy_undead(const shared_ptr<M_Undead> &pobj) 
        {
            pobj->getinfo(); 
        }
    public:
        void attack_enemy_element(const shared_ptr<M_Element> &pobj) 
        {
            pobj->getinfo(); 
        }
    };
}
namespace ns3
{
    class Monster 
    {
    public:
        virtual ~Monster() {}
        virtual void getinfo() const = 0; 
    };
    class M_Undead : public Monster 
    {
    public:
        void getinfo() const override { cout << "M_Undead" << endl; }
    };
    class M_Element : public Monster 
    {
    public:
        void getinfo() const override { cout << "M_Element" << endl; }
    };
    class M_Mechanic : public Monster 
    {
    public:
        void getinfo() const override { cout << "M_Mechanic" << endl; }
    };
    class F_Warrior 
    {
    public:
        void attack_enemy(const shared_ptr<Monster> &pobj) 
        {
            pobj->getinfo(); 
        }
    };
}
int main()
{
#if 0
    using namespace ns0;
    shared_ptr<Fighter> prole_war(new F_Warrior(1000, 0, 200)); 
    prole_war->UseItem(LF_DHD);
#endif
#if 0
    using namespace ns1;
    
    shared_ptr<Fighter> prole_war(new F_Warrior(1000, 0, 200));
    
    prole_war->SetItemStrategy(make_shared<ItemStrategy_DHD>()); 
    prole_war->UseItem();                                        
    
    shared_ptr<ItemStrategy> strateby2(new ItemStrategy_BXD()); 
    prole_war->SetItemStrategy(strateby2);                      
    prole_war->UseItem();                                       
#endif
#if 0
    using namespace ns2;
    shared_ptr<F_Warrior> pobjwar(new F_Warrior());
    pobjwar->attack_enemy_undead(make_shared<M_Undead>()); 
    shared_ptr<M_Element> pobjelm(new M_Element());
    pobjwar->attack_enemy_element(pobjelm); 
#endif
#if 1
    using namespace ns3;
    shared_ptr<F_Warrior> pobjwar(new F_Warrior());
    pobjwar->attack_enemy(make_shared<M_Undead>()); 
    shared_ptr<Monster> pobjelm(new M_Element());
    pobjwar->attack_enemy(pobjelm); 
#endif
    return 0;
}