设计模式实现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());
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容