設計模式(GOF&&C++)

設計模式

1.單例模式

  • 餓漢模式(不管需不需要,初始化時直接創建實例)
class Singleton {
	//(1)構造函數私有化
private:
	Singleton(){
		m_singer = NULL;
	}
	//(2)提供全局訪問點
public:
	static Singleton *GetInstance() {
		return m_singer;
	}

	static void FreeInstatce() {
		if (m_singer) {
			delete m_singer;
			m_singer = NULL;
		}
	}
	//(3)定義一個靜態指針
private:
	static Singleton *m_singer;
};

//(4)創建實例
Singleton *Singleton::m_singer = new Singleton;

int main() {
	Singleton *s1 = Singleton::GetInstance();
	return 0;
}
  • 懶漢模式(等到需要時再創建)
  • 效率比較低
class Singleton {
	//(1)構造函數私有化
private:
	Singleton() {
		m_singer = NULL;
	}
	//(2)提供全局訪問點
public:
	static Singleton *GetInstance() {
		if (!m_singer) {    //若未創建實例
			lock();         //防止併發訪問
			if (!m_singer) {//二次判斷
				m_singer = new Singleton;
			}
			unlock();
		}
		return m_singer;
	}
private:
	static Singleton *m_singer;
};

Singleton *m_signer = NULL;

2.簡單工廠模式

創建一個工廠,根據輸入條件的不同,產生不同的類,這些類具有相同的抽象類。

//(1)定義抽象類
class Fruit {
public:
	virtual void getFruit() = 0;
};

//(2)定義具體類
class Banana:public Fruit {
public:
	void getFruit() {
		cout << "Banana!" << endl;
	}
};

class Apple :public Fruit {
public:
	void getFruit() {
		cout << "Apple!" << endl;
	}
};

//(3)定義工廠
class Factory {
public:
	static Fruit *create(const char *name) {
		Fruit *tmp = NULL;

		if (strcmp(name, "banana") == 0)
			tmp = new Banana;
		else if (strcmp(name, "apple") == 0)
			tmp = new Apple;
		else
			return NULL;

		return tmp;
	}
};

int main() {
	Fruit *b = Factory::create("banana");
	if (!b)
		cout << "Creat b err!" << endl;
	b->getFruit();

	Fruit *a = Factory::create("apple");
	if (!a)
		cout << "Creat a err!" << endl;
	a->getFruit();

	return 0;
}

3.工廠模式

與簡單工廠模式不同,核心工廠類作爲一個抽象角色,負責具體工廠子類必須實現的接口。

class Fruit {
public:
	virtual void say() {
		cout << "fruit" << endl;
	}
};

class FruitFactory {
public:
	virtual Fruit *getFruit() {
		return new Fruit;
	}
};

class Banana :public Fruit {
public:
	virtual void say() {
		cout << "banana" << endl;
	}
};

class BananaFactory :public FruitFactory {
public:
	virtual Fruit *getFruit() {
		return new Banana;
	}
};

class Apple :public Fruit {
public:
	virtual void say() {
		cout << "apple" << endl;
	}
};

class AppleFactory :public FruitFactory {
public:
	virtual Fruit *getFruit() {
		return new Apple;
	}
};

int main() {
	Fruit *f = NULL;
	FruitFactory *ff = NULL;

	ff = new BananaFactory;
	f = ff->getFruit();
	f->say();

	ff = new AppleFactory;
	f = ff->getFruit();
	f->say();

	return 0;
}

4.抽象工廠模式

工廠模式只能生產一個產品,而抽象工廠模式可以生產一個產品組。

class Fruit {
public:
	virtual void say() {
		cout << "fruit" << endl;
	}
};

class FruitFactory {
public:
	virtual Fruit *getApple() {
		return new Fruit;
	}

	virtual Fruit *getBanana() {
		return new Fruit;
	}
};

class SouthBanana :public Fruit {
public:
	virtual void say() {
		cout << "south banana" << endl;
	}
};

class SouthApple :public Fruit {
public:
	virtual void say() {
		cout << "south apple" << endl;
	}
};

class NorthBanana :public Fruit {
public:
	virtual void say() {
		cout << "north banana" << endl;
	}
};

class NorthApple :public Fruit {
public:
	virtual void say() {
		cout << "north apple" << endl;
	}
};

class SouthFactory :public FruitFactory {
	virtual Fruit *getApple() {
		return new SouthApple;
	}

	virtual Fruit *getBanana() {
		return new SouthBanana;
	}
};

class NorthFactory :public FruitFactory {
	virtual Fruit *getApple() {
		return new NorthApple;
	}

	virtual Fruit *getBanana() {
		return new NorthBanana;
	}
};

int main() {
	Fruit *f = NULL;
	FruitFactory *ff = NULL;

	ff = new SouthFactory;
	f = ff->getApple();
	f->say();
	f = ff->getBanana();
	f->say();

	ff = new NorthFactory;
	f = ff->getApple();
	f->say();
	f = ff->getBanana();
	f->say();

	return 0;
}

5.建造者模式

一個對象的構建比較複雜,將一個對象的構建和對象的表示進行分離。

class House {
public:
	void setFloor(string floor)
	{
		this->m_floor = floor;
	}

	void setDoor(string door) {
		this->m_door = door;
	}

	void setWall(string wall) {
		this->m_wall = wall;
	}

	string getFloor() {
		return this->m_floor;
	}

	string getDoor() {
		return this->m_door;
	}

	string getWall() {
		return this->m_wall;
	}
private:
	string m_floor;
	string m_door;
	string m_wall;
};

class Builder {
public:
	virtual void makeFloor() = 0;
	virtual void makeDoor() = 0;
	virtual void makeWall() = 0;
	virtual House *getHouse() = 0;
};

class FlatBuild :public Builder {
public:
	FlatBuild() {
		this->m_house = new House;
	}

	virtual void makeFloor() {
		m_house->setFloor("Flat Floor");
	}

	virtual void makeDoor() {
		m_house->setDoor("Flat Door");
	}

	virtual void makeWall() {
		m_house->setWall("Flat Floor");
	}

	virtual House *getHouse() {
		return m_house;
	}

private:
	House * m_house;
};

class VillaBuild :public Builder {
public:
	VillaBuild() {
		this->m_house = new House;
	}

	virtual void makeFloor() {
		m_house->setFloor("Villa Floor");
	}

	virtual void makeDoor() {
		m_house->setDoor("Villa Door");
	}

	virtual void makeWall() {
		m_house->setWall("Villa Floor");
	}

	virtual House *getHouse() {
		return m_house;
	}

private:
	House * m_house;
};

class Director {
public:
	void construct(Builder *b)
	{
		b->makeFloor();
		b->makeDoor();
		b->makeWall();
	}
};

int main() {
	House *h = NULL;
	Builder *b = NULL;
	Director *d = NULL;
	d = new Director;

	b = new FlatBuild;
	d->construct(b);
	h = b->getHouse();
	cout << h->getDoor() <<endl ;
	cout << h->getFloor() << endl;
	cout << h->getWall() << endl;

	b = new VillaBuild;
	d->construct(b);
	h = b->getHouse();
	cout << h->getDoor() << endl;
	cout << h->getFloor() << endl;
	cout << h->getWall() << endl;


	return 0;
}

6.原型模式

一個複雜對象具有自我複製功能,統一一套接口。採用複製原型對象的方法來創建對象的實例。

class Person {
public:
	virtual Person *clone() = 0;
	virtual void say() = 0;
};

class CppProgrammer:public Person {
public:
	CppProgrammer() {
		this->m_name = "";
		this->m_age = 0;
		this->m_resume = NULL;
	}

	CppProgrammer(string name, int age) {
		this->m_name = name;
		this->m_age = age;
		this->m_resume = NULL;
	}

	~CppProgrammer() {
		if (this->m_resume)
		{
			delete this->m_resume;
			this->m_resume = NULL;
		}
	}

	virtual void say() {
		cout << this->m_name << " ," << this->m_age << " ," << this->m_resume << "!" << endl;
	}

	void setResume(const char *s) {
		this->m_resume = new char[strlen(s)+1];
		memcpy(this->m_resume, s, strlen(s)+1);
	}

	virtual Person *clone() {
		CppProgrammer *p = new CppProgrammer;
		*p = *this; //淺拷貝
		p->setResume(this->m_resume);//深拷貝

		return p;
	}
private:
	string m_name;
	int m_age;
	char *m_resume;
};

int main() {

	CppProgrammer *p1= new CppProgrammer("jack", 18);
	p1->setResume("I'm a Cpp programmer!");
	p1->say();
	
	Person *p2 = p1->clone();
	delete p1;
	p2->say();

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