设计模式实现C++

//1.简单工厂,工厂提供一个返回基类指针的函数
enum sportball {
    football = 0,
    basketball = 1
};
class abstractsportball {
public:
    virtual void play() = 0;
};
class football:public abstractsportball {
public:
    void play() {
        cout << "footballplay" << endl;
    }
};
class basketball:public abstractsportball {
public:
    void play() {
        cout << "basketballplay" << endl;
    }
};
class simplefactory {
public:
    abstractsportball* create(sportball s) {
        abstractsportball * a;
        switch (s) {
            case sportball::football:a = new football(); break;
            case sportball::basketball:a = new basketball(); break;
            default:a = nullptr;
        }
        return a;
    }
};
void testsimplefactory() {
    abstractsportball* ab;
    simplefactory sf;
    ab = sf.create(sportball:: basketball);
    ab->play();
    ab = sf.create(sportball::football);
    ab->play();
}

例如要实现一个活动功能,这个模块下除了主面板还有具体每个活动的面板,(mvc)数据存在model中,model向view或者control提供activityInfo,这时就可以实现一个activityInfoFactory为不同的活动提供不同的activityInfo

//2.策略模式,使用者context拥有抽象策略,set函数可以设置
class AbstractStrategy {
public:
    virtual void Excute() = 0;
};
class ConcreteStrategy:public AbstractStrategy {
public:
    void Excute() { cout << "执行策略1" << endl; }
};
class ConcreteStragtegy2 :public AbstractStrategy {
public:
    void Excute() { cout << "执行策略2" << endl; }
};
class Context {
private:
    AbstractStrategy* ab;
public:
    void SetStrategy(AbstractStrategy* nab) {
        ab = nab;
    }
    void ExcuteStrategy() {
        ab->Excute();
    }
};
void TestStrategy() {
    Context c;
    ConcreteStrategy cs1;
    ConcreteStragtegy2 cs2;
    c.SetStrategy(&cs1);
    c.ExcuteStrategy();
    c.SetStrategy(&cs2);
    c.ExcuteStrategy();
}

AI的策略可以根据不同难度的模式进行选择

//3.装饰模式,Hero继承Person,装备了某个装备的Hero认识一个装备之前的Hero
class Person {
public:
    virtual void Show() { cout << "my name is yasuo" << endl; }
};
class Hero :public Person {
protected:
    Person* p;
public:
    void SetP(Person* np) { p = np; }
    virtual void Show() { p->Show(); }
};
class 装了盾的Hero:public Hero {
public:
    virtual void Show() { p->Show(); cout << "防御+1" << endl; }
};
class 装了剑的Hero :public Hero {
public:
    virtual void Show() { p->Show(); cout << "攻击+1" << endl; }
};
void TestDecorator() {
    Person p;
    Hero h1;
    h1.SetP(&p);
    装了盾的Hero h2;
    h2.SetP(&h1);
    装了剑的Hero h3;
    h3.SetP(&h2);
    h3.Show();

}
//4.工厂设计模式,每个工厂对应一个品类的某个具体产品
class SportBall {
public:
    virtual void Play() = 0;
};
class FootBall :public SportBall {
public:
    void Play() {
        cout << "play footBall!" << endl;
    }
};
class BasketBall :public SportBall {
public:
    void Play() {
        cout << "Play BasketBall!" << endl;
    }
};
class ABSportFactory {
public:
    virtual SportBall* Create() = 0;
};
class FootBallFactory :public ABSportFactory {
public:
    SportBall* Create() {
        return new FootBall();
    }
};
class BasketFactory :public ABSportFactory {
public:
    SportBall* Create() {
        return new BasketBall();
    }
};
void TestFactory() {
    ABSportFactory* absf;
    absf = new FootBallFactory();
    SportBall* sb;
    sb = absf->Create();
    sb->Play();
    absf = new BasketFactory();
    sb = absf->Create();
    sb->Play();
}
//5.代理模式,proxy,作用:为复杂对象建立一个临时简单对象,为远程对象建立本地对象,为对象建立访问权限保护
class Subject {
public:
    virtual void Method() = 0;
};
class RealSubject :Subject {
public:
    void Method() { cout << "访问" << endl; }
};
class Proxy :public Subject {
private:
    RealSubject * rs;
public:
    void PreMethod() { cout << "访问时间是..." << endl; }
    void Method() { PreMethod(); rs = new RealSubject(); rs->Method(); }
};
void TestProxy() {
    Subject* s = new Proxy();
    s->Method();
}

//6.模板模式,基类中定义一个模板函数非虚,模板函数由类的其他函数构成,子类自定义这些其他函数的实现。
class PlayGame {
public:
    virtual void Open() = 0;
    virtual void Play() = 0;
    virtual void Close() = 0;
    void Procedure() {
        Open();
        Play();
        Close();
    }
};
class PlayLOL :public PlayGame {
public:
    void Open() { cout << "打开LOL" << endl; }
    void Play() { cout << "玩LOL" << endl; }
    void Close() { cout << "关闭LOL" << endl; }
};
void TestTemplate() {
    PlayGame* pg;
    pg = new PlayLOL();
    pg->Procedure();
}
//7.外观模式,封闭多个子系统,向外边提供简单的外观类
class 程序 {
public:
    void WriteLua() { cout << "写lua代码" << endl; }
    void WriteC() { cout << "写C++代码" << endl; }
};
class 美术 {
public:
    void DesignModel() {
        cout << "设计模型" << endl;
    }
    void DesignTex() {
        cout << "设计纹理" << endl;
    }
};
class 游戏捏脸系统 {
private:
    程序* c;
    美术* m;
public:
    游戏捏脸系统() {
        c = new 程序();
        m = new 美术();
    }
    void Do() {
        c->WriteC();
        c->WriteLua();
        m->DesignModel();
        m->DesignTex();
    }
};
void TestFacade() {
    游戏捏脸系统 g;
    g.Do();
}

mvc:单个module里有很多类实现了内部的各种功能,但是还是由mudule类跟外界交流。

//8.建造模式+抽象工厂(每个工厂提供多个品类),模板模式是类里有个模板函数规定了行为的步骤,建造模式是有个蓝图类规定了有哪几个部分,再由建造者来创造具体的,下面的厨师就是抽象工厂(建造者),每个工厂提供多个不同品类的制造
//套餐是建造模式中的蓝图
class 荤菜 {
public:
    virtual void Show() = 0;
};
class 鱼香肉丝:public 荤菜 {
public:
    void Show() {cout<<"鱼香肉丝"<<endl;}
};
class 青椒肉丝 :public 荤菜{
public:
    void Show() { cout << "青椒肉丝" << endl; }
};
class 素菜 {
public:
    virtual void Show() = 0;
};
class 麻婆豆腐 :public 素菜 {
public:
    void Show() { cout << "麻婆豆腐" << endl; }
};
class 炒青菜 :public 素菜 {
public:
    void Show() { cout << "炒青菜" << endl; }
};
class 厨师 {
public:
    virtual 荤菜* 做荤菜() = 0;
    virtual 素菜* 做素菜() = 0;
};
class 厨师A:public 厨师 {
public:
    荤菜* 做荤菜() { return new 鱼香肉丝; }
    素菜* 做素菜() { return new 麻婆豆腐; }
};
class 厨师B :public 厨师 {
public:
    荤菜* 做荤菜() { return new 青椒肉丝; }
    素菜* 做素菜() { return new 炒青菜; }
};

class 套餐 {
protected:
    荤菜* h;
    素菜* s;
    厨师* c;
protected://禁止实例化
    套餐() {}
public:
    //void Set(厨师* nc) { c = nc; }
    void Make() { h = c->做荤菜(); s = c->做素菜(); };
    void Show() { h->Show(); s->Show(); };
};
class 套餐A :public 套餐 {
public:
    套餐A() { c = new 厨师A(); }
};
class 套餐B :public 套餐 {
public:
    套餐B() { c = new 厨师B(); }
};
void TestConstructor() {
    套餐* t = new 套餐A();
    t->Make();
    t->Show();
    t = new 套餐B();
    t->Make();
    t->Show();
}

抽象工厂,游戏中的语言选择,不同的语言需要提供不同的语言文字类不同的语音类,可以设计一个工厂专门针对中文创建语言类,语音类,另一个针对英文。

//9.观察者模式,AI,Music实现被通知的接口,通知者状态改变时通知
class ResponseObject {
public:
    virtual void Response() = 0;
};
class AI :public ResponseObject {
public:
    void Response() {
        cout << "AI开始寻路" << endl;
    }
};
class Music :public ResponseObject {
public:
    void Response() {
        cout << "战斗动画响起" << endl;
    }
};
class 通知者 {
private:
    map<string, ResponseObject*> m;
public:
    void Add(string name, ResponseObject* ro) {
        m.insert(pair<string, ResponseObject*>(name, ro));
    }
    void Remove(string name) {
        m.erase(name);
    }
    void Notify() {
        cout << "玩家进入视线" << endl;
        for (auto i : m) {
            i.second->Response();
        }
    }
};
void TestObserver() {
    AI a;
    Music m;
    通知者 s;
    s.Add("ai", &a);
    s.Add("music", &m);
    s.Notify();

}

游戏里的事件系统,mvc中各个模块解耦也是通过事件系统来相互交流

//10.状态模式,状态和状态转换分散到各个类
class State;
class Walk;
class Idle;
class Run;
class Character;
class State {
public:
    virtual void Do(Character * c) = 0;
};
class Character {
private:
    State* s;
public:
    float speed;
public:
    Character(State* ns, float nspeed) :s(ns), speed(nspeed) {}
    void SetState(State* ns) { s = ns; }
    void play() { s->Do(this); }
};
class Idle :public State {
public:
    Idle() { cout << "Idle" << endl; }
    void Do(Character* c);
};
class Walk :public State {
public:
    Walk() { cout << "Walk" << endl; }
    void Do(Character* c);
};
class Run :public State {
public:
    Run() { cout << "Run" << endl; }
    void Do(Character* c);
};
void Idle::Do(Character* c) {
    if (c->speed <= 0) return;
    else if (c->speed > 0 && c->speed <= 3) {
        c->SetState(new Walk());
    }
    else
        c->SetState(new Run);
}
void Walk::Do(Character* c) {
    if (c->speed <= 0) c->SetState(new Idle);
    else if (c->speed > 0 && c->speed <= 3) {
        return;
    }
    else
        c->SetState(new Run);
}
void Run::Do(Character* c) {
    if (c->speed <= 0) c->SetState(new Idle);
    else if (c->speed > 0 && c->speed <= 3) {
        c->SetState(new Walk);
    }
    else
        return;
}
void TestState() {
    Character* c = new Character(new Idle(),0);
    c->play();
    c->speed = 2;
    c->play();
    c->speed = 4;
    c->play();
    c->speed = 0;
    c->play();
}

状态机,游戏流程管理

//适配器模式,适配器用与把某个不符合接口的类封装起来满足接口
class Monster {
public:
    void Walk() { cout << "MonsterWalk" << endl; }
};
//移动接口
class IMove {
public:
    virtual void Move() = 0;
};
class Scene {
    IMove* im;
public:
    Scene(IMove* nim) :im(nim) {}
    void Show() { im->Move(); }
};
class MonsterAdpter:public IMove {
private:
    Monster* m;
public:

    MonsterAdpter(Monster* nm):m(nm) {}
public:
    void Move() {
        m->Walk();
    }
};
void TestAdapter() {
    Monster m;
    IMove* im = new MonsterAdpter(&m);
    Scene s(im);
    s.Show();
}
//备忘录模式
class CunDang {
private:
    float health;
    float attackValue;
    float attackFreq;
public:
    CunDang(float h,float a,float af):health(h),attackValue(a),attackFreq(af) {}
    friend class Player;
};
class Player {
private:
    float health;
    float attachValue;
    float attachFreq;//攻击频率
public:
    Player(float h, float a, float af) :health(h), attachValue(a), attachFreq(af) {}
    void Change(float h, float a, float af) { health = h; attachValue = a, attachFreq; }
    void Show() { cout << health<<" " << attachValue <<" "<< attachFreq << endl; }
    CunDang* CreateCunDang() {
        return new CunDang(health, attachValue, attachFreq);
    }
    void SetFromCunDang(CunDang* cd) {
        this->health = cd->health;
        this->attachFreq = cd->attackFreq;
        this->attachValue = cd->attackValue;
    }
};
class CunDangTable {
private:
    map<string, CunDang*>  cunDangTable;
public:
    void AddCunDang(string name,CunDang* cd) { cunDangTable.insert(pair<string, CunDang*>(name, cd)); }
    CunDang* getCunDang(string name) { 
        if (cunDangTable.find(name) != cunDangTable.end())
            return cunDangTable[name];
        assert(1);
        
    }
};
void TestMemento(){
    Player p(100, 20, 0.1f);
    p.Show();
    CunDangTable cdt;
    cdt.AddCunDang("player", p.CreateCunDang());
    p.Change(80, 20, 0.1f);
    p.Show();
    p.SetFromCunDang(cdt.getCunDang("player"));
    p.Show();
}

游戏中的序列化,例如UE4的UObject提供了序列化功能

//懒汉
class Singleton {
private:
    Singleton() {}
    static Singleton* instance;
public:
    static Singleton* GetInstance() {
        if (instance != nullptr)
            return instance;
        instance = new Singleton;
        return instance;
    };
    //处理单例的回收
    class Destroy {
    public:
        ~Destroy(){
            delete Singleton::instance;
        }
    };
    static Destroy d;
};

Singleton* Singleton::instance = nullptr;
Singleton::Destroy Singleton::d;
void TestSingleton(){
    Singleton* pp = Singleton::GetInstance();
    Singleton* ppp = Singleton::GetInstance();
    cout << (pp == ppp) << endl;
}
//饿汉
class Singleton2 {
private:
    Singleton2() {}
    static Singleton2* instance;
public:
    static Singleton2* GetInstance() {
        return instance;
    }
};

Singleton2* Singleton2::instance=new Singleton2;
void TestSingleton2() {
    Singleton2* s = Singleton2::GetInstance();
}
//test
class A {
protected:
    A() {}
};
class B :public A {
public:
    B() {}
};
//访问者
class State {
public:
    virtual void GetManSpeed() = 0;
    virtual void GetWomanSpeed() = 0;
};
class Walk:public State {
public:
    void GetManSpeed() { cout << "speed:100" << endl; }
    void GetWomanSpeed() { cout << "speed:80" << endl; }
};
class Run:public State {
public:
    void GetManSpeed() { cout << "speed:200" << endl; }
    void GetWomanSpeed() { cout << "speed:180" << endl; }
};
class Person {
public:
    virtual void GetSpeed(State* s) = 0;
};
class Man :public Person {
public:
    virtual void GetSpeed(State* s) {
        s->GetManSpeed();
    }
};
class Woman :public Person {
public:
    virtual void GetSpeed(State* s) {
        s->GetWomanSpeed();
    }
};
void TestVisitor(){
    Man m;
    m.GetSpeed(new Run());
    m.GetSpeed(new Walk());
    Woman w;
    w.GetSpeed(new Run());
    w.GetSpeed(new Walk());
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容