C++設計模式精簡實踐

設計模式簡介

面向對象設計原則

  • 依賴倒置原則(DIP)
    1. 高層模塊(穩定)不應該依賴於底層模塊(變化),二者都應該依賴於抽象(穩定)
    2. 抽象(穩定)不應該依賴於實現細節(變化),實現細節應該依賴於抽象(穩定)
  • 開放封閉原則(OCP)
    1. 對擴展開放,對更改封閉
    2. 類模塊應該是可擴展的,但是不可修改
  • 單一職責原則(SRP)
    1. 一個類應該僅有一個引起它變化的原因
    2. 變化的方向隱含着類的責任
  • 替換原則(LSP)
    1. 子類必須能夠替換他們的基類(IS-A)
    2. 繼承表達類型抽象
  • 接口隔離原則(ISP)
    1. 不應該強迫客戶程序依賴他們不用的方法
    2. 接口應該小而完備
  • 優先使用對象組合,而非類繼承
    1. 類繼承通常爲“白箱複用”,對象組合通常爲“黑箱複用”
    2. 繼承在某種程度上破壞了封裝性,子類父類耦合度高
    3. 而對象組合則只要求被組合的對象具有良好定義的接口,耦合度低
  • 封裝變化點
    1. 使用封裝來創建對象之間的分界層,讓設計者可以在分界層的一側進行修改,而不會對另一側產生不良的影響,從而實現層次間的松耦合
  • 針對接口編程,而非針對實現編程
    1. 不將變量類型聲明爲某個特定的具體類,而是聲明爲某個接口
    2. 客戶程序無需獲知對象的具體類型,只需要知道對象所具有的接口
    3. 減少系統中各部分的依賴關係,從而實現“高內聚、松耦合”的類型設計方案

重構關鍵技法

  • 靜態 ~> 動態
  • 早綁定 ~> 晚綁定
  • 繼承 ~> 組合
  • 編譯時依賴 ~> 運行時依賴
  • 緊耦合 ~> 松耦合

設計模式

組件協作

TemplateMethod(模板方法模式)

#include <iostream>
#include <string>
using namespace std;

//lib developer
class Library{
public:
	virtual ~Library(){}

	void Run(){
		Step1();
        
		if (Step2()){
			Step3();
		}
	}

protected:
	void Step1(){
        cout << "Step1" << endl;
	}

	void Step3(){
        cout << "Step3" << endl;
	}

	virtual bool Step2() = 0;
};

class App : public Library{
public:
	App(){}
	virtual ~App(){}

protected:
	virtual bool Step2(){ 
        cout << "Step2" << endl;
		return true;
	}
};

int main(int argc, char* argv[])
{
    cout << "template method" << endl;
    
	Library* lib = new App;
	lib->Run();
	delete lib;
	system("pause");
	return 0;
}

Strategy(策略模式)

#include <iostream>
#include <string>
using namespace std;

class IStrategy
{
public:
	virtual int DoOperation(int num1, int num2) = 0;
};

class AddOperation : public IStrategy
{
public:
	virtual int DoOperation(int num1, int num2) override
	{
		return num1 + num2;
	}
};

class SubstractOperation : public IStrategy
{
public:
	virtual int DoOperation(int num1, int num2) override
	{
		return num1 - num2;
	}
};

class Context
{
public:
	Context(IStrategy* InStrategy)
		: Strategy(InStrategy)
	{
	}

	int exec(int num1, int num2)
	{
		return Strategy->DoOperation(num1, num2);
	}
private:
	IStrategy* Strategy;
};

int main(int argc, char* argv[])
{
	cout << "strategy" << endl;

	Context* cxt = new Context(new AddOperation);
	cout << "1+2=" << cxt->exec(1, 2) << endl;

	cxt = new Context(new SubstractOperation);
	cout << "1-2=" << cxt->exec(1, 2) << endl;

	system("pause");
	return 0;
}

Observer(觀察者模式)

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <list>
using namespace std;

class IProgressObject
{
public:
	virtual void DoProgress(float value) = 0;
	virtual ~IProgressObject(){};
};

class NumNotifier :public IProgressObject
{
public:
	virtual void DoProgress(float value){
		cout << setiosflags(ios::fixed) << setprecision(1) << value << endl;
	}
};

class PointNotifier : public IProgressObject
{
public:
	virtual void DoProgress(float value){
		cout << "#"<< endl;
	}
};

class Reader
{
public:
	Reader(const vector<string>& InStrings)
		: stringList(InStrings)
	{}

	void addProgress(IProgressObject* InProgressObject){
		progressObjectList.push_back(InProgressObject);
	}

	void removeProgress(IProgressObject* InProgressObject){
		progressObjectList.remove(InProgressObject);
	}

	void start(){
		for (unsigned int i = 0; i < stringList.size(); i++){
			float progressValue = (float)(i + 1) / stringList.size();
			cout << stringList[i] << endl;
			onProgress(progressValue);
		}
	}

protected:
	virtual void onProgress(float value){
		for (list<IProgressObject*>::iterator iter = progressObjectList.begin(); iter != progressObjectList.end(); iter++){
			(*iter)->DoProgress(value);
		}
	}

protected:
	vector<string> stringList;
	list<IProgressObject*> progressObjectList;
};

int main(int agrc, char* argv[])
{
	cout << "observer" << endl;

	NumNotifier nn;
	PointNotifier pn;

	vector<string> strings{"A","B","C","D","E","F","G","H","I","J"};
	Reader reader(strings);
	reader.addProgress(&nn);
	reader.addProgress(&pn);
	reader.start();
	system("pause");
	return 0;
}

單一職責

Decorator(裝飾模式)

#include <iostream>
#include <string>
using namespace std;

class Stream
{
public:
	virtual ~Stream(){};

	virtual char Read(int num) = 0;
	virtual void Seek(int pos) = 0;
	virtual void Write(char data) = 0;
};

class FileStream : public Stream
{
public:
	virtual char Read(int num) override
	{
		//讀文件流
		return 'r';
	}

	virtual void Seek(int pos) override
	{
		//定位文件流
	}

	virtual void Write(char data) override
	{
		//寫文件流
	}
};

class NetworkStream : public Stream
{
public:
	virtual char Read(int num) override
	{
		//讀文件流
		return 'r';
	}

	virtual void Seek(int pos) override
	{
		//定位文件流
	}

	virtual void Write(char data) override
	{
		//寫文件流
	}
};

class DecoratorStream : public Stream
{
protected:
	DecoratorStream(Stream* InStream)
		:stream(InStream)
	{}

	Stream* stream;
};

class CryptoStream : public DecoratorStream
{
public:
	CryptoStream(Stream* InStream)
		: DecoratorStream(InStream)
	{}

	virtual char Read(int num) override
	{
		//加密操作
		//......
		//讀文件流
		return stream->Read(num);
	}

	virtual void Seek(int pos) override
	{
		//加密操作
		//......
		//定位文件流
		stream->Seek(pos);
	}

	virtual void Write(char data) override
	{
		//加密操作
		//......
		//寫文件流
		stream->Write(data);
	}
};

class BufferStream : public DecoratorStream
{
public:
	BufferStream(Stream* InStream)
		: DecoratorStream(InStream)
	{}

	virtual char Read(int num) override
	{
		//緩存操作
		//......
		//讀文件流
		return stream->Read(num);
	}

	virtual void Seek(int pos) override
	{
		//緩存操作
		//......
		//定位文件流
		stream->Seek(pos);
	}

	virtual void Write(char data) override
	{
		//緩存操作
		//......
		//寫文件流
		stream->Write(data);
	}
};

int main(int argc, char* argv[])
{
	cout << "decorator" << endl;

	FileStream* fs = new FileStream();
	CryptoStream* cs = new CryptoStream(fs);
	BufferStream* bs = new BufferStream(cs);

	delete bs;
	delete cs;
	delete fs;
	system("pause");
	return 0;
}

Bridge(橋接模式)

#include <iostream>
#include <string>
using namespace std;

//輪胎基類
class ITyre
{
public:
	virtual void DealSomething() = 0;
};

//子午線輪胎
class RadialTyre : public ITyre
{
public:
	virtual void DealSomething() override
	{
		cout << "RadialTyre" << endl;
	}
};

//斜交輪胎
class BiasTyre : public ITyre
{
public:
	virtual void DealSomething() override
	{
		cout << "BiasTyre" << endl;
	}
};

//汽車基類
class ICar
{
public:
	ICar(ITyre* InTyre)
		: Tyre(InTyre)
	{}

	virtual void DoSomething(){};
protected:
	ITyre* Tyre;
};

//轎車
class SedanCar : public ICar
{
public:
	SedanCar(ITyre* InTyre)
		: ICar(InTyre)
	{}

	virtual void DoSomething() override
	{
		cout << "SedanCar" << endl;
		Tyre->DealSomething();
	}
};

//SUV 
class SuvCar : public ICar
{
public:
	SuvCar(ITyre* InTyre)
		: ICar(InTyre)
	{}

	virtual void DoSomething() override
	{
		cout << "SuvCar" << endl;
		Tyre->DealSomething();
	}
};

int main(int argc, char* argv[])
{
	cout << "bridge" << endl;

	ICar* Car = new SuvCar(new RadialTyre());
	Car->DoSomething();
	Car = new SedanCar(new BiasTyre());
	Car->DoSomething();
	system("pause");
	return 0;
}

對象創建

Factory Method(工廠方法)

#include <iostream>
#include <string>
using namespace std;

class IShape
{
public:
	virtual ~IShape(){}
	virtual void Draw() = 0;
};

class Rectangle : public IShape
{
public:
	virtual void Draw() override
	{
		cout << "rectangle" << endl;
	}
};

class Circle : public IShape
{
public:
	virtual void Draw() override
	{
		cout << "circle" << endl;
	}
};

class ShapeFactory
{
public:
	virtual ~ShapeFactory(){}
	virtual IShape* CreateShape() = 0;
};

class RectangleFactory : public ShapeFactory
{
public:
	virtual IShape* CreateShape() override
	{
		return new Rectangle;
	}
};

class CircleFactory : public ShapeFactory
{
public:
	virtual IShape* CreateShape() override
	{
		return new Circle;
	}
};

class Test
{
public:
	Test(ShapeFactory* InFactory)
		: Factory(InFactory)
	{}

	IShape* CreateShape(){
		return Factory->CreateShape();
	}
private:
	ShapeFactory* Factory;
};

int main(int argc, char* argv[])
{
	cout << "factory method" << endl;

	Test t(new CircleFactory);
	IShape* s = t.CreateShape();
	s->Draw();

	system("pause");
	return 0;
}

Abstract Factory(抽象工廠模式)

#include <iostream>
#include <string>
using namespace std;

class IMouse
{
public:
	virtual ~IMouse(){}
	virtual void Produce() = 0;
};

class LenovoMouse : public IMouse
{
public:
	virtual void Produce() override
	{
		cout << "Lenovo Mouse" << endl;
	}
};

class MacMouse : public IMouse
{
public:
	virtual void Produce() override
	{
		cout << "Mac Mouse" << endl;
	}
};

class IKeyboard
{
public:
	virtual ~IKeyboard(){}
	virtual void Produce() = 0;
};

class LenovoKeyboard : public IKeyboard
{
public:
	virtual void Produce() override
	{
		cout << "Lenovo Keyboard" << endl;
	}
};

class MacKeyboard : public IKeyboard
{
public:
	virtual void Produce() override
	{
		cout << "Mac Keyboard" << endl;
	}
};

class ComputerFactory
{
public:
	virtual IMouse* ProduceMouse() = 0;
	virtual IKeyboard* ProduceKeyboard() = 0;
};

class LenovoFactory :public ComputerFactory
{
public:
	virtual IMouse* ProduceMouse() override
	{
		return new LenovoMouse;
	}

	virtual IKeyboard* ProduceKeyboard() override
	{
		return new LenovoKeyboard;
	}
};

class MacFactory :public ComputerFactory
{
public:
	virtual IMouse* ProduceMouse() override
	{
		return new MacMouse;
	}

	virtual IKeyboard* ProduceKeyboard() override
	{
		return new MacKeyboard;
	}
};

class Test
{
public:
	Test(ComputerFactory* InFactory)
		: Factory(InFactory)
	{}

	IMouse* ProduceMouse()
	{
		return Factory->ProduceMouse();
	}

	IKeyboard* ProduceKeyboard()
	{
		return Factory->ProduceKeyboard();
	}
private:
	ComputerFactory* Factory;
};

int main(int argc, char* argv[])
{
	cout << "abstract factory" << endl;

	Test lf(new LenovoFactory);
	lf.ProduceMouse()->Produce();
	lf.ProduceKeyboard()->Produce();

	Test mf = new MacFactory;
	mf.ProduceMouse()->Produce();
	mf.ProduceKeyboard()->Produce();

	system("pause");
	return 0;
}

Prototype(原型模式)

#include <iostream>
#include <string>
using namespace std;

class IShape
{
public:
	virtual ~IShape(){};
	virtual void Draw() = 0;
	virtual IShape* Clone() = 0;
};

class Rectangle : public IShape
{
public:
	virtual void Draw() override
	{
		cout << "Rectangle" << endl;
	}

	virtual IShape* Clone() override
	{
		return new Rectangle(*this);
	}
};

class Circle : public IShape
{
public:
	virtual void Draw() override
	{
		cout << "Circle" << endl;
	}

	virtual IShape* Clone() override
	{
		return new Circle(*this);
	}
};

class Test
{
public:
	Test(IShape* InShape)
		: Shape(InShape)
	{}

	IShape* CreateShape()
	{
		return Shape->Clone();
	}

private:
	IShape* Shape;
};

int main(int argc, char* argv[])
{
	cout << "prototype" << endl;

	IShape* prototype = new Circle;
	Test t(prototype);
	t.CreateShape()->Draw();

	system("pause");
	return 0;
}

Builder(構建器)

#include <iostream>
#include <string>
using namespace std;

class Computer
{
public:
	Computer(){}
	virtual ~Computer(){};

	void SetMouse(const string& InMouse)
	{
		mMouse = InMouse;
	}

	void SetKeyboard(const string& InKeyboard)
	{
		mKeyboard = InKeyboard;
	}

	void SetDisplay(const string& InDisplay)
	{
		mDisplay = InDisplay;
	}

	void Show()
	{
		cout << "Mouse:" << mMouse << endl;
		cout << "Keyboard:" << mKeyboard << endl;
		cout << "Display:" << mDisplay << endl;
	}
protected:
	string mMouse;
	string mKeyboard;
	string mDisplay;
};

class Builder
{
public:
	Builder(){}
	virtual ~Builder(){}

	virtual void BuildMouse(const string& InMouse) = 0;
	virtual void BuildKeyboard(const string& InKeyboard) = 0;
	virtual void BuildDisplay(const string& InDisplay) = 0;
	virtual void CreateProduct() = 0;
	virtual Computer* GetProduct() = 0;
};

class ComputerBuilder : public Builder
{
public:
	ComputerBuilder()
		: mComputer(NULL)
	{}

	virtual void BuildMouse(const string& InMouse) override
	{
		mComputer->SetMouse(InMouse);
	}

	virtual void BuildKeyboard(const string& InKeyboard) override
	{
		mComputer->SetKeyboard(InKeyboard);
	}

	virtual void BuildDisplay(const string& InDisplay) override
	{
		mComputer->SetDisplay(InDisplay);
	}

	virtual void CreateProduct() override
	{
		mComputer = new Computer();
	}

	virtual Computer* GetProduct() override
	{
		return mComputer;
	}
private:
	Computer* mComputer;
};

class Director
{
public:
	Director(Builder* InBuild)
		: mBuilder(InBuild)
	{}

	void Construct(const string& InMouse, const string& InKeyboard, const string& InDisplay)
	{
		if (!mBuilder) return;

		mBuilder->CreateProduct();
		mBuilder->BuildMouse(InMouse);
		mBuilder->BuildKeyboard(InKeyboard);
		mBuilder->BuildDisplay(InDisplay);
	}

private:
	Builder* mBuilder;
};

int main(int argc, char* argv[])
{
	cout << "builder" << endl;

	Builder* b = new ComputerBuilder;
	Director* d = new Director(b);
	d->Construct("sb","jp","xsq");
	Computer* c = b->GetProduct();
	c->Show();

	system("pause");
	return 0;
}

對象性能

Singleton(單例模式)

#include <iostream>
#include <string>
using namespace std;

class Singleton
{
public:
	static Singleton& GetInstance()
	{
		static Singleton mInstance;
		return mInstance;
	}

	void Show(){
		cout << "singleton instance" << endl;
	}

private:
	Singleton(){}
	Singleton(Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
};

int main(int argc, char* argv[])
{
	cout << "singleton" << endl;

	Singleton::GetInstance().Show();

	system("pause");
	return 0;
}

Flyweight(享元模式)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Character
{
public:
	virtual ~Character(){}

	//外部狀態應用
	virtual void Display(int InWidth, int InHeight, int InColor) = 0;

	//獲取內部狀態
	virtual char GetSymbol() = 0;

protected:
	Character(char c)
		: symbol(c)
	{}

protected:
	//內部狀態
	char symbol;

	//外部狀態
	int width;
	int height;
	int color;
};

class ConcreteCharacter : public Character
{
public:
	ConcreteCharacter(char c)
		: Character(c)
	{}

	virtual void Display(int InWidth, int InHeight, int InColor) override
	{
		width = InWidth;
		height = InHeight;
		color = InColor;
		
		cout << width << " " << height << " " << color << endl;
	}

	virtual char GetSymbol() override
	{
		return symbol;
	}
};

class CharacterFactory
{
public:
	CharacterFactory(){};

	Character* GetCharacter(char c)
	{
		for (vector<Character*>::iterator iter = mCharacters.begin(); iter != mCharacters.end(); iter++)
		{
			if ((*iter)->GetSymbol() == c)
			{
				return *iter;
			}
		}
		Character* newc = new ConcreteCharacter(c);
		mCharacters.push_back(newc);
		return newc;
	}

	vector<Character*>::size_type GetCount()
	{
		return mCharacters.size();
	}
private:
	vector<Character*> mCharacters;
};

int main(int argc, char* argv[])
{
	cout << "flyweight" << endl;

	int param = 0;

	string test = "ABBCCCDDDDEF";
	CharacterFactory* cf = new CharacterFactory;
	for (string::iterator iter = test.begin(); iter != test.end(); iter++)
	{
		param += 10;
		Character* c = cf->GetCharacter(*iter);
		cout << c->GetSymbol() << endl;
		c->Display(param, param, param);
	}
	cout << "Object Count = " << cf->GetCount() << endl;

	delete cf;
	system("pause");
	return 0;
}

接口隔離

Facade(外觀模式)

#include <iostream>
#include <string>
using namespace std;

enum LawsuitType
{
	CRIMINAL,
	CIVIL,
	ECONOMIC,
	ADMINISTRATION
};

class IBaseLawsuit
{
public:
	virtual void Receive() = 0;
};

//刑事訴訟
class Criminal : public IBaseLawsuit
{
public:
	virtual void Receive() override
	{
		cout << "Criminal Received" << endl;
	}

	void CriminalProcess()
	{
		cout << "Cirminal Process" << endl;
	}
};

//民事訴訟
class Civil : public IBaseLawsuit
{
public:
	virtual void Receive() override
	{
		cout << "Civil Received" << endl;
	}

	void CivilProcess()
	{
		cout << "Civil Process" << endl;
	}
};

//經濟訴訟
class Economic : public IBaseLawsuit
{
public:
	virtual void Receive() override
	{
		cout << "Economic Received" << endl;
	}

	void EconomicProcess()
	{
		cout << "Economic Process" << endl;
	}
};

//行政訴訟
class Administration : public IBaseLawsuit
{
public:
	virtual void Receive() override
	{
		cout << "Administration Received" << endl;
	}

	void AdministrationProcess()
	{
		cout << "Administration Process" << endl;
	}
};

//律師事務所
class LawFirm
{
public:
	LawFirm()
	{
		mCirminal = new Criminal;
		mCivil = new Civil;
		mEconomic = new Economic;
		mAdmin = new Administration;
	}

	void Receive(LawsuitType InType)
	{
		cout << "LawFirm Received" << endl;
		switch (InType)
		{
		case CRIMINAL:
			mCirminal->Receive();
			mCirminal->CriminalProcess();
			break;
		case CIVIL:
			mCivil->Receive();
			mCivil->CivilProcess();
			break;
		case ECONOMIC:
			mEconomic->Receive();
			mEconomic->EconomicProcess();
			break;
		case ADMINISTRATION:
			mAdmin->Receive();
			mAdmin->AdministrationProcess();
			break;
		default:
			break;
		}
	}

private:
	Criminal* mCirminal;
	Civil* mCivil;
	Economic* mEconomic;
	Administration* mAdmin;
};

int main(int argc, char* argv[])
{
	cout << "facade" << endl;

	LawFirm lf;
	lf.Receive(LawsuitType::CIVIL);

	system("pause");
	return 0;
}

Proxy(代理模式)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

//武者
class IKungfuMaster
{
public:
	IKungfuMaster(const string& InId)
		: id(InId)
	{}
	virtual ~IKungfuMaster(){};
	virtual void Show() = 0;
	virtual void DisplayIdentity() = 0;

protected:
	string id;
};

class RealStar : public IKungfuMaster
{
public:
	RealStar()
		: IKungfuMaster("real star")
	{}

	virtual void Show() override
	{
		cout << id << " is acting" << endl;
	}

	virtual void DisplayIdentity()
	{
		cout << "i am " << id << endl;
	}
};

class StarProxy : public IKungfuMaster
{
public:
	StarProxy()
		: IKungfuMaster("star proxy")
		, rs(new RealStar)
	{}

	virtual void Show() override
	{
		rs->Show();
	}

	virtual void DisplayIdentity()
	{
		cout << "i am " << id << endl;
	}

private:
	RealStar* rs;
};

int main(int argc, char* argv[])
{
	cout << "proxy" << endl;

	IKungfuMaster* master = new StarProxy;
	master->Show();
	master->DisplayIdentity();

	system("pause");
	return 0;
}

Mediator(中介者模式)

#include <iostream>
#include <string>
using namespace std;

class IMediator;

//客戶
class ICustomer
{
public:
	virtual void SetMediator(IMediator* InMediator) = 0;
	virtual void SendMessage(const string& InMessage) = 0;
	virtual void GetMessage(const string& InMessage) = 0;

protected:
	IMediator* mMediator;
};

//中介
class IMediator
{
public:
	virtual void SetRenter(ICustomer* InRenter) = 0;
	virtual void SetLandlord(ICustomer* InLandlord) = 0;
	virtual void PassOnMessage(const string& InMessage, ICustomer* InSender) = 0;
};

//房東
class Landlord : public ICustomer
{
public:
	Landlord(){}

	virtual void SetMediator(IMediator* InMediator)
	{
		mMediator = InMediator;
	}

	virtual void SendMessage(const string& InMessage)
	{
		if (mMediator)
		{
			mMediator->PassOnMessage(InMessage, this);
		}
	}
	virtual void GetMessage(const string& message)
	{
		cout << "landlord received a message:" << message << endl;
	}
};

//租客
class Renter : public ICustomer
{
public:
	Renter(){}

	virtual void SetMediator(IMediator* InMediator) override
	{
		mMediator = InMediator;
	}

	virtual void SendMessage(const string& InMessage)
	{
		if (mMediator)
		{
			mMediator->PassOnMessage(InMessage, this);
		}
	}

	virtual void GetMessage(const string& InMessage)
	{
		cout << "renter received a message:" << InMessage << endl;
	}
};

//房地產中介
class Realtor : public IMediator
{
public:
	Realtor()
		: mRenter(nullptr)
		, mLandlord(nullptr)
	{}

	virtual void SetRenter(ICustomer* InRenter)
	{
		mRenter = InRenter;
	}
	virtual void SetLandlord(ICustomer* InLandlord)
	{
		mLandlord = InLandlord;
	}
	virtual void PassOnMessage(const string& InMessage, ICustomer* InSender)
	{
		if (InSender == mRenter)
		{
			mLandlord->GetMessage(InMessage);
		}
		else if (InSender == mLandlord)
		{
			mRenter->GetMessage(InMessage);
		}
	}
protected:
	ICustomer* mRenter;
	ICustomer* mLandlord;
};


int main(int argc, char* argv[])
{
	cout << "mediator" << endl;

	//創建對象
	Realtor* realtor = new Realtor;
	Renter* renter = new Renter;
	Landlord* landlord = new Landlord;

	//設置對象關係
	renter->SetMediator(realtor);
	landlord->SetMediator(realtor);
	realtor->SetRenter(renter);
	realtor->SetLandlord(landlord);

	//
	renter->SendMessage("can i see the room?");
	landlord->SendMessage("yes, of course!");

	system("pause");
	return 0;
}

Adapter(適配器模式)

#include <iostream>
#include <string>
using namespace std;

class IDataLine
{
public:
	IDataLine(string InType)
		: Type(InType)
	{}

	virtual string ConnectorType() = 0;
	virtual void Connect() = 0;

protected:
	string Type;
};

class DataLineVGA : public IDataLine
{
public:
	DataLineVGA()
		: IDataLine("VGA")
	{}

	virtual string ConnectorType() override
	{
		return Type;
	}

	virtual void Connect() override
	{
		cout << "signal transmission" << endl;
	}
};

//舊接口
class VGAConnector
{
public :
	VGAConnector(IDataLine* InVGA);

	virtual void ConnectorType()
	{
		mDataLine->ConnectorType();
	}

	virtual void ConnectVGA()
	{
		mDataLine->Connect();
	}

protected:
	IDataLine* mDataLine;
};

//新接口
class HDMIConnector
{
public:
	virtual void ConnectorType() = 0;
	virtual void ConnectHDMI() = 0;
};

class Adapter : public HDMIConnector
{
public:
	Adapter(IDataLine* InVGA)
		: mDataLineVGA(InVGA)
	{}

	virtual void ConnectorType()
	{
		cout << "HDMI" << endl;
	}

	virtual void ConnectHDMI() override
	{
		ConnectorType();
		mDataLineVGA->Connect();
	}

protected:
	IDataLine* mDataLineVGA;
};

int main(int argc, char* argv[])
{
	cout << "adapter" << endl;

	Adapter* a = new Adapter(new DataLineVGA);
	a->ConnectHDMI();
	delete a;

	system("pause");
	return 0;
}

狀態變化

Memento(備忘錄模式)

#include <iostream>
#include <string>
using namespace std;

class Memento
{
	friend class Originator;
private:
	Memento(const string& InState)
		: mState(InState)
	{}
	~Memento(){}

	void SetState(const string& InState)
	{
		mState = InState;
	}

	string GetState()
	{
		return mState;
	}
private:
	string mState;
};

//負責創建Memento,恢復內部數據
class Originator
{
public:
	Originator(){}
	Originator(const string& InState)
		: mState(InState)
	{}

	~Originator(){}
	Memento* CreateMemento()
	{
		return new Memento(mState);
	}
	
	void RestoreTo(Memento* InMemento)
	{
		mState = InMemento->GetState();
	}

	void SetState(const string& InState)
	{
		mState = InState;
	}

	void Print()
	{
		cout << "state:" << mState << endl;
	}

private:
	string mState;

};

int main(int argc, char* argv[])
{
	cout << "memento" << endl;

	Originator* o = new Originator("expire");
	o->Print();

	Memento* m = o->CreateMemento();

	o->SetState("new");
	o->Print();

	o->RestoreTo(m);
	o->Print();

	system("pause");
	return 0;
}

State(狀態模式)

#include <iostream>
#include <string>
using namespace std;

class LightState
{
public:
	virtual ~LightState(){}
	virtual void Action() = 0;
	virtual LightState* NextState() = 0;
};

class OpenState : public LightState
{
public:
	virtual void Action() override
	{
		cout << "Open State" << endl;
	}

	virtual LightState* NextState() override;

	static LightState* GetInstance()
	{
		if (Instance == nullptr)
		{
			Instance = new OpenState;
		}
		return Instance;
	}

private:
	static LightState* Instance;
};

class CloseState : public LightState
{
public:
	virtual void Action() override
	{
		cout << "Close State" << endl;
	}
	
	virtual LightState* NextState() override
	{
		return OpenState::GetInstance();
	}

	static LightState* GetInstance()
	{
		if (Instance == nullptr)
		{
			Instance = new CloseState;
		}
		return Instance;
	}

private:
	static LightState* Instance;
};

LightState* OpenState::Instance = nullptr;
LightState* CloseState::Instance = nullptr;

LightState* OpenState::NextState()
{
	return CloseState::GetInstance();
}

class Light
{
public:
	Light()
		: State(OpenState::GetInstance())
	{}

	void Action()
	{
		State->Action();
		State = State->NextState();
	}
private:
	LightState* State;
};


int main(int argc, char* argv[])
{
	cout << "state" << endl;

	Light l;
	l.Action();
	l.Action();

	system("pause");
	return 0;
}

數據結構

Composite(組合模式)

#include <iostream>
#include <string>
#include <list>
using namespace std;

class TreeNode
{
public:
	TreeNode(const string& InNodeName)
		: NodeName(InNodeName)
	{}

	void Show()
	{
		cout << "Name:" << NodeName << endl;
		for (list<TreeNode*>::iterator iter = Children.begin(); iter != Children.end(); iter++)
		{
			cout << "	" << (*iter)->NodeName << endl;
		}
	}

	void AddNode(TreeNode* InNode)
	{
		Children.push_back(InNode);
	}

	void RemoveNode(TreeNode* InNode)
	{
		Children.remove(InNode);
	}

private:
	string NodeName;
	list<TreeNode*> Children;
};

int main(int argc, char* argv[])
{
	cout << "composite" << endl;

	TreeNode* n = new TreeNode("RootNode");

	TreeNode* cn = nullptr;
	for (int i = 0; i < 10; i++)
	{
		string name = "LeafNode" + to_string(i);
		cn = new TreeNode(name);
		n->AddNode(cn);
	}
	n->Show();

	system("pause");
	return 0;
}

Iterator(迭代器模式)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

template<typename T>
class Iterator {
public:
	virtual ~Iterator() {
	}
	virtual void First() = 0;
	virtual void Next() = 0;
	virtual bool IsDone() = 0;
	virtual bool CurrentItem(T& OutItem) = 0;
};

template<typename T>
class Container
{
public:
	virtual ~Container(){}
	virtual void AddItem(T InItem) = 0;
	virtual Iterator<T>* CreateIterator() = 0;
	virtual int GetSize() = 0;
	virtual bool GetItem(int Index, T& OutItem) = 0;
};

template<typename T>
class ConcreteIterator : public Iterator<T>
{
public:
	ConcreteIterator(Container<T>* InContainer)
		: mContainer(InContainer)
		, CurIndex(0)
	{}

	virtual void First() override
	{
		CurIndex = 0;
	}

	virtual void Next() override
	{
		if (CurIndex < mContainer->GetSize())
		{
			CurIndex++;
		}
	}

	virtual bool IsDone() override
	{
		if (CurIndex > mContainer->GetSize() - 1)
		{
			return true;
		}
		return false;
	}

	virtual bool CurrentItem(T& OutItem) override
	{
		return mContainer->GetItem(CurIndex, OutItem);
	}

private:
	Container<T>* mContainer;
	int CurIndex;
};

template<typename T>
class ConcreteContainer : public Container<T>
{
public:
	ConcreteContainer()
		: mSize(0)
	{}

	virtual void AddItem(T InItem) override
	{
		mData.push_back(InItem);
		mSize++;
	}

	virtual Iterator<T>* CreateIterator() override
	{
		return new ConcreteIterator<T>(this);
	}

	virtual int GetSize() override
	{
		return mSize;
	}

	virtual bool GetItem(int Index, T& OutItem) override
	{
		if (Index < 0 || Index >= mSize)
		{
			return false;
		}
		OutItem = mData[Index];
		return true;
	}

private:
	int mSize;
	vector<T> mData;
};

int main(int argc, char* argv[])
{
	cout << "iterator" << endl;

	Container<int>* c = new ConcreteContainer<int>();
	c->AddItem(1);
	c->AddItem(2);
	c->AddItem(3);
	Iterator<int>* iter = c->CreateIterator();

	for (iter->First(); !iter->IsDone(); iter->Next())
	{
		int value = 0;
		bool bSuccess = iter->CurrentItem(value);
		cout << "value:" << value << endl;
	}

	system("pause");
	return 0;
}

Chain of Chain of Responsibility(責任鏈模式)

#include <iostream>
#include <string>
using namespace std;

class Request
{
public:
	Request()
		: mLevel(0)
	{}

	void SetLevel(int InLevel)
	{
		mLevel = InLevel;
	}

	int GetLevel() const
	{
		return mLevel;
	}

private:
	int mLevel;
};

class ChainHandler
{
public:
	ChainHandler(int InLevel)
		: mLevel(InLevel)
		, mNextHandler(nullptr)
	{}

	void Process(const Request& InRequest)
	{
		if (CanHandleRequest(InRequest))
		{
			HandleRequest(InRequest);
		}
		else
		{
			PassToNextHandler(InRequest);
		}
	}

	void SetNextHandler(ChainHandler* InHandler)
	{
		mNextHandler = InHandler;
	}

	int GetLevel() const
	{
		return mLevel;
	}
protected:
	virtual bool CanHandleRequest(const Request& InRequest) = 0;
	virtual void HandleRequest(const Request& InRequest) = 0;

	void PassToNextHandler(const Request& InRequest)
	{
		if (mNextHandler != nullptr)
		{
			mNextHandler->HandleRequest(InRequest);
		}
	}

protected:
	int mLevel;
	ChainHandler* mNextHandler;
};

class HandlerLevel : public ChainHandler
{
public:
	HandlerLevel(int InLevel)
		: ChainHandler(InLevel)
	{}

protected:
	virtual bool CanHandleRequest(const Request& InRequest) override
	{
		return InRequest.GetLevel() == GetLevel();
	}

	virtual void HandleRequest(const Request& InRequest) override
	{
		cout << "Handler Level:" << GetLevel() << endl;
		cout << "Request Level:" << InRequest.GetLevel() << endl;
	}
};

int main(int argc, char* argv[])
{
	cout << "chain of responsibility" << endl;

	ChainHandler* ch1 = new HandlerLevel(1);
	ChainHandler* ch2 = new HandlerLevel(2);
	ChainHandler* ch3 = new HandlerLevel(3);
	ch1->SetNextHandler(ch2);
	ch2->SetNextHandler(ch3);

	Request q;
	q.SetLevel(1);

	ch1->Process(q);

	q.SetLevel(2);
	ch1->Process(q);

	system("pause");
	return 0;
}

行爲變化

Command(命令模式)

#include <iostream>
#include <string>
#include <list>
using namespace std;

class ICommand
{
public:
	virtual void Execute() = 0;
};

class ConcreteCommand : public ICommand
{
public:
	ConcreteCommand(string InArgs)
		: mArgs(InArgs)
	{}

	virtual void Execute() override
	{
		cout << "Execute, Args:" << mArgs << endl;
	}

private:
	string mArgs;
};

class ListCommand : public ICommand
{
public:
	ListCommand(){}
	void AddCommand(ICommand* InCommand)
	{
		mCommands.push_back(InCommand);
	}

	virtual void Execute() override
	{
		while (mCommands.size())
		{
			ICommand* c = *mCommands.begin();
			mCommands.pop_front();
			c->Execute();
		}
	}
private:
	list<ICommand*> mCommands;
};

int main(int argc, char* argv[])
{
	cout << "command" << endl;

	ICommand* c1 = new ConcreteCommand("print1");
	ICommand* c2 = new ConcreteCommand("print2");
	ListCommand lc;
	lc.AddCommand(c1);
	lc.AddCommand(c2);
	lc.Execute();

	system("pause");
	return 0;
}

Visitor(訪問者模式)

#include <iostream>
#include <string>
using namespace std;

//假設固定一張試卷3個問題
//兩個考生做題
class Question1;
class Question2;
class Question3;

class IVisitor
{
public:
	virtual ~IVisitor(){};
	virtual void Visit(Question1* InQuestion) = 0;
	virtual void Visit(Question2* InQuestion) = 0;
	virtual void Visit(Question3* InQuestion) = 0;
};

class ZhangSanVisitor : public IVisitor
{
public:
	virtual void Visit(Question1* InQuestion) override
	{
		cout << "ZhangSan Answer Question1" << endl;
	}

	virtual void Visit(Question2* InQuestion) override
	{
		cout << "ZhangSan Answer Question2" << endl;
	}

	virtual void Visit(Question3* InQuestion) override
	{
		cout << "ZhangSan Answer Question3" << endl;
	}
};

class LiSiVisitor : public IVisitor
{
public:
	virtual void Visit(Question1* InQuestion) override
	{
		cout << "LiSi Answer Question1" << endl;
	}

	virtual void Visit(Question2* InQuestion) override
	{
		cout << "LiSi Answer Question2" << endl;
	}

	virtual void Visit(Question3* InQuestion) override
	{
		cout << "LiSi Answer Question3" << endl;
	}
};

class IQuestion
{
public:
	virtual ~IQuestion(){}
	virtual void Answer(IVisitor* InVisitor) = 0;
};

class Question1 : public IQuestion
{
public:
	virtual void Answer(IVisitor* InVisitor) override
	{
		InVisitor->Visit(this);
	}
};

class Question2 : public IQuestion
{
public:
	virtual void Answer(IVisitor* InVisitor) override
	{
		InVisitor->Visit(this);
	}
};

class Question3 : public IQuestion
{
public:
	virtual void Answer(IVisitor* InVisitor) override
	{
		InVisitor->Visit(this);
	}
};


int main(int argc, char* argv[])
{
	cout << "visitor" << endl;

	Question1 q1;
	Question2 q2;
	Question3 q3;

	IVisitor* v = new ZhangSanVisitor;
	q1.Answer(v);
	q2.Answer(v);
	q3.Answer(v);

	v = new LiSiVisitor;
	q1.Answer(v);
	q2.Answer(v);
	q3.Answer(v);

	system("pause");
	return 0;
}

領域問題

Interpreter(解析器模式)

#include <iostream>
#include <string>
#include <map>
#include <stack>
using namespace std;

class Expression
{
public:
	virtual int Interpreter(map<string, int>& InVar) = 0;
	virtual ~Expression(){}
};

//終結符表達式(整數)
class VarExpression : public Expression
{
public:
	VarExpression(string InKey)
		: mKey(InKey)
	{}

	virtual int Interpreter(map<string, int>& InVar) override
	{
		return InVar[mKey];
	}
private:
	string mKey;
};

//符號表達式
class SymbolExpression : public Expression
{
public:
	SymbolExpression(Expression* InLeft, Expression* InRight)
	{
		mLeft = InLeft;
		mRight = InRight;
	}

	Expression* GetLeft()
	{
		return mLeft;
	}

	Expression* GetRight()
	{
		return mRight;
	}
protected:
	Expression* mLeft;
	Expression* mRight;
};

class AddExpression : public SymbolExpression
{
public:
	AddExpression(Expression* InLeft, Expression* InRight)
		: SymbolExpression(InLeft, InRight)
	{}

	virtual int Interpreter(map<string, int>& InVar) override
	{
		return mLeft->Interpreter(InVar) + mRight->Interpreter(InVar);
	}
};

class SubExpression : public SymbolExpression
{
public:
	SubExpression(Expression* InLeft, Expression* InRight)
		: SymbolExpression(InLeft, InRight)
	{}

	virtual int Interpreter(map<string, int>& InVar) override
	{
		return mLeft->Interpreter(InVar) - mRight->Interpreter(InVar);
	}
};

class Calculator
{
public:
	Calculator(string InExpStr)
	{
		mExp = nullptr;

		stack<Expression*> ExpStack;

		Expression* Left = nullptr;
		Expression* Right = nullptr;

		/*從左到向分析表達式(如:a+b-c),最終的語法樹如下:
		*           -
		*         /   \
		*       +     c
		*     /   \
		*    a     b
		*/

		for (unsigned int i = 0; i < InExpStr.length(); i++)
		{
			switch (InExpStr[i])
			{
			case '+':
			{
				//從棧頂取出左表達式
				Left = ExpStack.top();
				ExpStack.pop();
				//從表達式中取出+後面的右表達式
				Right = new VarExpression(InExpStr.substr(++i, 1));
				ExpStack.push(new AddExpression(Left, Right));
				break;
			}
			case '-':
			{
				//從棧頂取出左表達式
				Left = ExpStack.top();
				ExpStack.pop();
				//從表達式中取出+後面的右表達式
				Right = new VarExpression(InExpStr.substr(++i, 1));
				ExpStack.push(new SubExpression(Left, Right));
				break;
			}
			default:
				ExpStack.push(new VarExpression(InExpStr.substr(i, 1)));
				break;
			}
		}

		if (!ExpStack.empty())
		{
			mExp = ExpStack.top();
			ExpStack.pop();
		}
	}

	~Calculator()
	{
		DelExpTree(mExp);
		mExp = nullptr;
	}

	int Run(map<string, int>& InVar)
	{
		return (mExp == nullptr) ? 0 : mExp->Interpreter(InVar);
	}

private:
	void DelExpTree(Expression* InExp)
	{
		SymbolExpression* branch = dynamic_cast<SymbolExpression*>(InExp);
		//葉子結點
		if (branch == NULL)
		{
			delete InExp;
		}
		else  //分支結點
		{
			//左子樹
			DelExpTree(branch->GetLeft());

			//右子樹
			DelExpTree(branch->GetRight());

			//結點
			delete InExp;
		}
	}


private:
	Expression* mExp;
};

int main(int argc, char* argv[])
{
	cout << "interpreter" << endl;

	string ExpStr = "a+b-c";
	map<string, int> var;
	var["a"] = 200;
	var["b"] = 300;
	var["c"] = 100;
	Calculator c(ExpStr);
	cout << ExpStr << "=" << c.Run(var) << endl;

	system("pause");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章