設計模式23種
- 創建型
- 抽象工廠模式
- 工廠模式
- 生成器模式
- 原型模式
- 單例模式
- 結構型
- 適配器模式
- 橋接模式
- 組合模式
- 裝飾模式
- 外觀模式
- 享元模式
- 代理模式
- 行為型
- 責任鏈模式
- 命令模式
- 解釋器模式
- 迭代器模式
- 中介者模式
- 備忘錄模式
- 觀察者模式
- 狀態模式
- 策略模式
- 模版方法模式
- 訪問者模式
創建型
與對象的創建有關
抽象工廠模式
提供一個創建一系列相關或相互依賴的對象的接口
//來1張1費卡 1張2費卡 一系列相關
class Card {
public:virtual void out() = 0;
};
//還可以定義更多的卡牌
class CardCost1:public Card {
public:virtual void out() {cout << "我是1費卡" << endl;}
};class CardCost2 :public Card {
public:virtual void out() {cout << "我是2費卡" << endl;}
};class Factory {
public:virtual Card* CreateCost1() = 0;virtual Card* CreateCost2() = 0;
};
//還可以定義更多的工廠來組合
class CardFactory:public Factory {
public:Card* CreateCost1() {//來一張1費卡return new CardCost1();}Card* CreateCost2() {//來一張2費卡return new CardCost2();}
};
class CardFamaly
int main() {CardFactory *fac = new CardFactory();Card* cost1 = fac->CreateCost1();Card* cost2 = fac->CreateCost2();cost1->out();cost2->out();delete cost1;delete cost2;delete fac;return 0;
}
工廠模式
定義一個用于創建對象的接口,讓子類決定實例化哪個類
//和抽象工廠區別是 1個和多個?
class Card {
public:virtual void out() = 0;
};class CardCost1:public Card {
public:virtual void out() {cout << "我是1費卡" << endl;}
};class CardCost2 :public Card {
public:virtual void out() {cout << "我是2費卡" << endl;}
};
class Factory {
public:virtual Card* Create() = 0;
};class CardCost1Factory:public Factory {
public:Card* Create() {return new CardCost1();}
};class CardCost2Factory :public Factory {
public:Card* Create() {return new CardCost2();}
};
int main() {CardCost1Factory* fac1 = new CardCost1Factory();CardCost2Factory* fac2 = new CardCost2Factory();Card* cost1 = fac1->Create();Card* cost2 = fac2->Create();cost1->out();cost2->out();delete cost1;delete cost2;delete fac1;delete fac2;return 0;
}
生成器模式
在某些情況下,一個對象的創建過程非常復雜,涉及多個步驟,每個步驟都可能有不同的實現方式。如果將所有創建邏輯放在一個類中,會導致該類變得龐大且難以維護。此外,如果需要創建不同的變體對象,就需要在該類中添加更多的邏輯,使得代碼變得混亂。
原型模式
克隆
單例模式
就是單例
結構型
適配器模式
將一個類的接口轉變為另外一個希望的接口
template<typename Type>
void permutation(Type first, int len) {int val = 1;for (int i = 0; i < len; i++) {*first = val;val++;first++;}
}int main() {vector<int> a;//本來vector 不能用 = int 賦值 ++//把vector =>back_insert_iterator(重載++ = ) 調用vector push_backpermutation(back_inserter(a), 10);int b[20];permutation(b, 10);return 0;
}
橋接模式
將抽象部分和其實現部分分離,使它們都可以獨立的變化
//羈絆
class Jiban {
public:virtual void out() = 0;
};class Family :public Jiban {
public:virtual void out() {cout << " 家人 " << endl;}
};class ZhenMan :public Jiban {
public:virtual void out() {cout << " 鐵血屈服者 " << endl;}
};
//英雄
class Hero {
public:virtual void out() = 0;virtual void SetJiban(Jiban* jb) = 0;Jiban* m_jb = nullptr;
};class BaoBao:public Hero {
public:virtual void out() {cout << " 爆爆 ";m_jb->out();}virtual void SetJiban(Jiban* jb) {m_jb = jb;}};class JieSi :public Hero {
public:virtual void out() {cout << " 杰斯 ";m_jb->out();}virtual void SetJiban(Jiban* jb) {m_jb = jb;}
};int main() {Family* family = new Family;ZhenMan* zm = new ZhenMan;JieSi* js = new JieSi();BaoBao* bb = new BaoBao();js->SetJiban(zm);bb->SetJiban(family);js->out();bb->out();return 0;}
組合模式
將對象組合成樹型結構以表示整體與部分的層次結構
文件系統
裝飾模式
動態的給一個對象添加一些額外的職責
class Water {
public:virtual int cost() = 0;virtual void out() = 0;
};class Wahaha :public Water {
public:virtual int cost() {return 2;}virtual void out() {cout << "娃哈哈";}
};class WaterDecorator :public Water {
public:WaterDecorator(Water* self) {m_self = self;}virtual int cost() {return m_self->cost();}virtual void out() {m_self->out();}Water* m_self;
};
//加冰
class IceDecorator :public WaterDecorator {
public:IceDecorator(Water* self) :WaterDecorator(self) {}virtual int cost() {return 1 + m_self->cost();}virtual void out() {m_self->out();cout << " 加冰 ";}
};
//加糖
class SugarDecorator :public WaterDecorator {
public:SugarDecorator(Water* self) :WaterDecorator(self) {}virtual int cost() {return 1 + m_self->cost();}virtual void out() {m_self->out();cout << " 加糖 ";}
};int main() {Wahaha* whh = new Wahaha();{IceDecorator* d = new IceDecorator(whh);SugarDecorator* d2 = new SugarDecorator(d);d2->out();cout << d2->cost() << endl;}return 0;
}
外觀模式
為子系統中一組接口提供一個一致的界面
class Computer {
public:void turnOn() {cout << " 開電腦 ";}void turnOff() {cout << " 關電腦 ";}
};
class Light {
public:void turnOn() {cout << " 開燈 ";}void turnOff() {cout << " 關燈 ";}
};class MyLife {Computer computer;Light light;
public:void play() {computer.turnOn();light.turnOn();cout << endl;}void sleep() {computer.turnOff();light.turnOff();cout << endl;}
};int main() {MyLife* mf = new MyLife;mf->play();mf->sleep();return 0;
}
享元模式
運用共享技術有效的支持大量細粒度的對象
struct Base {
public:string name;int gongji;//攻擊int fangyu;//防御
};class BaoBao{
public:BaoBao(Base *base) {m_base = base;x = y = 0;}Base* m_base;int x, y;//坐標
};class BaoBaoFactory {public:BaoBao* GetHero() {Base* base = nullptr;if (mmp.count("爆爆"))base = mmp["爆爆"];else {base = new Base;base->name = "爆爆";base->gongji = 999;base->fangyu = 999;mmp[base->name] = base;}return new BaoBao(base);}unordered_map<string, Base *> mmp;
};int main() {BaoBaoFactory* fac = new BaoBaoFactory();vector<BaoBao* > all;for (int i = 0; i < 100; i++) {all.push_back(fac->GetHero());}return 0;
}
代理模式
行為型
行為模式涉及算法和對象間職責的分配。行為模式不僅描述對象或類的模式,還描述它們之間的通信模式
責任鏈模式
使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關系。將這些對象連成一條鏈,并沿著這條鏈傳遞改請求,直到有一個對象處理它為止。
class Request {
public:Request(int m, string i) :money(m), info(i) {}int money;string info;
};class RequestHandler {
public:virtual void DoHandle(Request* req) = 0;void SetHandler(RequestHandler* handler) {m_handler = handler;}RequestHandler* m_handler = nullptr;
};class Father :public RequestHandler {
public:virtual void DoHandle(Request* req) {if (req->money <= 20) {cout << "Father Handler,give money = " << req->money << endl;}else if (m_handler) {req->money += 1000;m_handler->DoHandle(req);}}
};class Mother :public RequestHandler {
public:virtual void DoHandle(Request* req) {if (req->money <= 5000) {cout << "Mother Handler,give money = " << req->money << endl;}else if (m_handler) {m_handler->DoHandle(req);}}
};int main() {Request* r = new Request(500, "補課費");Father* f = new Father();Mother* m = new Mother();f->SetHandler(m);f->DoHandle(r);return 0;
}
命令模式
將一個請求封裝為一個對象,從而使得可以用不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支持可撤銷操作。
class Light {
public:void TurnOn() {cout << "light TurnOn" << endl;}void TurnOff() {cout << "light TurnOff" << endl;}
};class Command {
public:virtual void exe() = 0;
};class OpenCommand :public Command {
public:void setLight(Light* light) {m_light = light;}virtual void exe() {m_light->TurnOn();}Light* m_light;
};class CloseCommand :public Command {
public:void setLight(Light* light) {m_light = light;}virtual void exe() {m_light->TurnOff();}Light* m_light;
};int main() {Light* light = new Light;OpenCommand* open = new OpenCommand;CloseCommand* close = new CloseCommand;open->setLight(light);close->setLight(light);open->exe();close->exe();return 0;
}
解釋器模式
給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
迭代器模式
提供一種順序訪問一個聚合對象中的各個元素,且不需要暴露該對象的內部表示。
中介者模式
用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立的改變它們之間的交互。
class User;
class middleman {
public:virtual void sendMessage(string &msg, User* sender) = 0;virtual void addUser(User* user) = 0;
};class User {
public:User(string name, middleman* middleman):m_name(name),m_middleman(middleman){middleman->addUser(this);}void sendMessage(string &msg) {cout << m_name << ":Say " << msg << endl;m_middleman->sendMessage(msg,this);}void recvMessage(string& msg) {cout << m_name << ":Recv " << msg << endl;}string m_name;middleman* m_middleman;
};class ChatRoom :public middleman {vector<User*> m_all;
public:virtual void sendMessage(string &msg,User * sender) {for (auto user : m_all) {if (user == sender)continue;user->recvMessage(msg);}}virtual void addUser(User* user) {m_all.push_back(user);}
};int main() {ChatRoom* room = new ChatRoom();User* user1 = new User("小明", room);User* user2 = new User("小花", room);User* user3 = new User("康康", room);string msg = "How are you";user3->sendMessage(msg);return 0;
}
備忘錄模式
在不破壞封裝性的前提下捕獲一個對象的內部狀態,并在對象之外保存這個狀態。這樣以后就可以將對象恢復原先保存的狀態。
觀察者模式
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并自動更新。
和中介者模式區別 1對多 和 多對多 樹和圖?
//觀察者
class Observer {
public:virtual void update(int state) = 0;
};class ActObserver:public Observer {
public:ActObserver(string name, int state) :m_name(name), m_state(state) {}virtual void update(int state) {m_state = state;cout << m_name << ":update state = " << m_state << endl;}
private:string m_name;int m_state;
};//主題
class Subject {
public:virtual void addObserver(Observer *observer) = 0;virtual void removeObserver(Observer* observer) = 0;virtual void notify() = 0;
};class ActSubject {
public:virtual void addObserver(Observer* observer) {m_all.insert(observer);}virtual void removeObserver(Observer* observer) {m_all.erase(observer);}virtual void notify() {for (auto ob : m_all) {ob->update(m_state);}}
public:void setState(int state) { m_state = state;notify();}
private:set<Observer*> m_all;int m_state;
};int main() {ActObserver* aob = new ActObserver("小美", 0);ActObserver* aob2 = new ActObserver("小帥", 0);ActSubject* sub = new ActSubject();sub->addObserver(aob);sub->addObserver(aob2);sub->setState(2);sub->removeObserver(aob);sub->setState(1);return 0;
}
狀態模式
允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。
把一堆if else 放到一個一個單獨的類中處理
class State;
class Context {
public:virtual void SetState(State* state) = 0;
};class State {
public:virtual void handle(Context* context) = 0;Context *m_context = nullptr;
};class StateA :public State {
public:virtual void handle(Context* context) {cout << "StateA" << endl;//本來 if else 一坨 把每個狀態拆在一個單獨的類中處理 context->SetState(this);}
};class StateB :public State {
public:virtual void handle(Context* context) {cout << "StateB" << endl;context->SetState(this);}
};class ContextA :public Context {
public:ContextA() {m_state = new StateA();}virtual void SetState(State* state) {m_state = state;}void ChangeState(State* state) {state->handle(this);}State* m_state;
};int main() {StateA* A = new StateA();StateB* B = new StateB();ContextA* C = new ContextA();C->ChangeState(A);C->ChangeState(B);C->ChangeState(A);return 0;
}
策略模式
定義一系列的算法,把它們一個個封裝起來,并且使它們可以相互替換。此模式使得算法可以獨立于使用它們的客戶而變化。
class MathOperation {
public:virtual int DoOperation(int a, int b) = 0;
};
class Add :public MathOperation {
public:virtual int DoOperation(int a, int b) {//a^2 + breturn a * a + b;}
};class Sub :public MathOperation {
public:virtual int DoOperation(int a, int b) {//a - b^2return a - b * b;}
};class Calc {
public:void SetOperation(MathOperation* op) { m_op = op; }int DoIt(int a, int b) {return m_op->DoOperation(a, b);}
private:MathOperation* m_op;
};int main() {Add* add = new Add();Sub* sub = new Sub();Calc* calc = new Calc();calc->SetOperation(add);cout << "DoIt = " << calc->DoIt(1,2) << endl;calc->SetOperation(sub);cout << "DoIt = " << calc->DoIt(3, 4) << endl;return 0;
}
模版方法模式
定義一個操作中的算法骨架,而將一些步驟延遲到子類中。
class Hero {
public:virtual int getHurt() {//傷害計算算法return getPhysicsHurt() + getMagicHurt();}
public:virtual int getPhysicsHurt() = 0;//物理傷害virtual int getMagicHurt() = 0;//魔法傷害virtual string getName() = 0;};
//爆爆
class BaoBao:public Hero {
public:BaoBao(string name) :m_name(name) {}virtual int getPhysicsHurt() {return 50;}virtual int getMagicHurt() {return 100;}virtual string getName() {return m_name;}string m_name;
};//杰斯
class JieSi :public Hero {
public:JieSi(string name) :m_name(name) {}virtual int getPhysicsHurt() {return 200;}virtual int getMagicHurt() {return 20;}virtual string getName() {return m_name;}string m_name;
};int main() {BaoBao* bb = new BaoBao("爆爆");JieSi* js = new JieSi("杰斯");cout << bb->getName() << " Hart = " << bb->getHurt() << endl;cout << js->getName() << " Hart = " << js->getHurt() << endl;return 0;
}
訪問者模式
表示一個作用于某對象結構中的元素的操作。它允許在不改變各元素的類的前提下定義作用于這些元素的新操作。
英雄帶裝備
class Hero {
public:virtual int getPhysicsHurt() = 0;//物理傷害virtual int getMagicHurt() = 0;//魔法傷害virtual string getName() = 0;
};
//爆爆
class BaoBao:public Hero {
public:BaoBao(string name) :m_name(name) {}virtual int getPhysicsHurt() {return 50;}virtual int getMagicHurt() {return 100;}virtual string getName() {return m_name;}string m_name;
};//杰斯
class JieSi :public Hero {
public:JieSi(string name) :m_name(name) {}virtual int getPhysicsHurt() {return 200;}virtual int getMagicHurt() {return 20;}virtual string getName() {return m_name;}string m_name;
};class Equipment {
public:virtual int getHurt(Hero* hero) = 0;
};
//帽子
class Maozi :public Equipment {
public:Maozi() {m_name = "帽子";dPhysicsRate = 1.1;dMagicRate = 2.0;}virtual int getHurt(Hero* hero) {int ans = hero->getPhysicsHurt()* dPhysicsRate + hero->getMagicHurt() * dMagicRate;cout << m_name << " " << hero->getName() << ":" << ans << endl;return ans;}
private:double dPhysicsRate;double dMagicRate;string m_name;
};int main() {BaoBao* bb = new BaoBao("爆爆");JieSi* js = new JieSi("杰斯");Maozi* mz = new Maozi();mz->getHurt(bb);mz->getHurt(js);return 0;
}