設(shè)計模式實現(xiàn)C++

//1.簡單工廠,工廠提供一個返回基類指針的函數(shù)
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();
}

例如要實現(xiàn)一個活動功能盐欺,這個模塊下除了主面板還有具體每個活動的面板根穷,(mvc)數(shù)據(jù)存在model中柏靶,model向view或者control提供activityInfo,這時就可以實現(xiàn)一個activityInfoFactory為不同的活動提供不同的activityInfo

//2.策略模式溜哮,使用者context擁有抽象策略滔金,set函數(shù)可以設(shè)置
class AbstractStrategy {
public:
    virtual void Excute() = 0;
};
class ConcreteStrategy:public AbstractStrategy {
public:
    void Excute() { cout << "執(zhí)行策略1" << endl; }
};
class ConcreteStragtegy2 :public AbstractStrategy {
public:
    void Excute() { cout << "執(zhí)行策略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的策略可以根據(jù)不同難度的模式進行選擇

//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.工廠設(shè)計模式茂嗓,每個工廠對應(yīng)一個品類的某個具體產(chǎn)品
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,作用:為復(fù)雜對象建立一個臨時簡單對象述吸,為遠程對象建立本地對象忿族,為對象建立訪問權(quán)限保護
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.模板模式,基類中定義一個模板函數(shù)非虛蝌矛,模板函數(shù)由類的其他函數(shù)構(gòu)成道批,子類自定義這些其他函數(shù)的實現(xiàn)。
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 << "關(guān)閉LOL" << endl; }
};
void TestTemplate() {
    PlayGame* pg;
    pg = new PlayLOL();
    pg->Procedure();
}
//7.外觀模式入撒,封閉多個子系統(tǒng)隆豹,向外邊提供簡單的外觀類
class 程序 {
public:
    void WriteLua() { cout << "寫lua代碼" << endl; }
    void WriteC() { cout << "寫C++代碼" << endl; }
};
class 美術(shù) {
public:
    void DesignModel() {
        cout << "設(shè)計模型" << endl;
    }
    void DesignTex() {
        cout << "設(shè)計紋理" << endl;
    }
};
class 游戲捏臉系統(tǒng) {
private:
    程序* c;
    美術(shù)* m;
public:
    游戲捏臉系統(tǒng)() {
        c = new 程序();
        m = new 美術(shù)();
    }
    void Do() {
        c->WriteC();
        c->WriteLua();
        m->DesignModel();
        m->DesignTex();
    }
};
void TestFacade() {
    游戲捏臉系統(tǒng) g;
    g.Do();
}

mvc:單個module里有很多類實現(xiàn)了內(nèi)部的各種功能,但是還是由mudule類跟外界交流茅逮。

//8.建造模式+抽象工廠(每個工廠提供多個品類)璃赡,模板模式是類里有個模板函數(shù)規(guī)定了行為的步驟簿煌,建造模式是有個藍圖類規(guī)定了有哪幾個部分,再由建造者來創(chuàng)造具體的,下面的廚師就是抽象工廠(建造者)鉴吹,每個工廠提供多個不同品類的制造
//套餐是建造模式中的藍圖
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();
}

抽象工廠姨伟,游戲中的語言選擇,不同的語言需要提供不同的語言文字類不同的語音類豆励,可以設(shè)計一個工廠專門針對中文創(chuàng)建語言類夺荒,語音類,另一個針對英文良蒸。

//9.觀察者模式,AI,Music實現(xiàn)被通知的接口技扼,通知者狀態(tài)改變時通知
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 << "戰(zhàn)斗動畫響起" << 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();

}

游戲里的事件系統(tǒng),mvc中各個模塊解耦也是通過事件系統(tǒng)來相互交流

//10.狀態(tài)模式嫩痰,狀態(tài)和狀態(tài)轉(zhuǎn)換分散到各個類
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();
}

狀態(tài)機剿吻,游戲流程管理

//適配器模式,適配器用與把某個不符合接口的類封裝起來滿足接口
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());
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丽旅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纺棺,更是在濱河造成了極大的恐慌榄笙,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祷蝌,死亡現(xiàn)場離奇詭異茅撞,居然都是意外死亡,警方通過查閱死者的電腦和手機巨朦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門米丘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人糊啡,你說我怎么就攤上這事拄查。” “怎么了悔橄?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵靶累,是天一觀的道長。 經(jīng)常有香客問我癣疟,道長挣柬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任睛挚,我火速辦了婚禮邪蛔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扎狱。我一直安慰自己侧到,他們只是感情好勃教,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著匠抗,像睡著了一般故源。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汞贸,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天绳军,我揣著相機與錄音,去河邊找鬼矢腻。 笑死门驾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的多柑。 我是一名探鬼主播奶是,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼竣灌!你這毒婦竟也來了聂沙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤帐偎,失蹤者是張志新(化名)和其女友劉穎逐纬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體削樊,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年兔毒,在試婚紗的時候發(fā)現(xiàn)自己被綠了漫贞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡育叁,死狀恐怖迅脐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情豪嗽,我是刑警寧澤谴蔑,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站龟梦,受9級特大地震影響隐锭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜计贰,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一钦睡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躁倒,春花似錦荞怒、人聲如沸洒琢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衰抑。三九已至,卻和暖如春荧嵌,著一層夾襖步出監(jiān)牢的瞬間呛踊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工完丽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恋技,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓逻族,卻偏偏與公主長得像蜻底,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子聘鳞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容