设计模式1—创建型模式

模式

在一定环境中解决某一问题的方案,包括三个基本元素--问题,解决方案和环境。

大白话:在一定环境下,用固定套路解决问题。

设计模式(Design pattern)

是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

设计模式的分类(Gang of Four的“DesignPatterns: Elements of Resualbel Software”书将设计模式归纳为三大类型,共23种)

创建型模式 :  通常和对象的创建有关,涉及到对象实例化的方式。(共5种模式)

结构型模式: 描述的是如何组合类和对象以获得更大的结构。(共7种模式)

行为型模式: 用来对类或对象怎样交互和怎样分配职责进行描述。(共11种模式)

创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:

1: 单例模式(Singleton Pattern)是保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2: 工厂模式(Factory Method Pattern)的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

3: 抽象工厂模式(Abstract Factory Pattern)的意图是提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。

4: 建造者模式(Builder Pattern)的意图是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

5: 原型模式(Prototype Pattern)是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

1.单例模式

代码1:

#include <iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////////
//单例模式就是把“构造函数私有化”,就不能在类外构造对象了,只能在类里面调用构造函数,创建对象,让后通静态变量返回对象

//------------单例模式(懒汉式)--------------------
/*所谓的懒汉式:就是在需要的使用对象的时候再创建对象的实例。就是当调用函数时,才创建类的对象。*/
class Singleton_lazy
{
private:
	Singleton_lazy()
	{
		cout << "Singleton_lazy 构造函数" << endl;
	}
public:
	static Singleton_lazy* getInstance()
	{
		//判断是否为空,用来限制创建单个实例(就是在此处限制只能产生单个实例)
		if (m_pSingleton == NULL)
		{
			//如果不为空,开辟空间,返回指针(使用new时,会自动调用构造函数)
			m_pSingleton = new Singleton_lazy; //创建类的对象
		}
		return m_pSingleton;
	}
	static void freeInstance()
	{
		if (m_pSingleton != NULL)
		{
			//“指针变量”和指针所“指向的内存空间”是两个不同的概念
			delete m_pSingleton; //释放所指向的内存空间
			m_pSingleton = NULL; //让指指向NULL
		}
	}
private:
	static Singleton_lazy *m_pSingleton;
	int temp;
};
int globleVar = 10;
//静态成员的初始化
Singleton_lazy* Singleton_lazy::m_pSingleton = NULL;

//////////////////////////////////////////////////////////////////////////
//------------单例模式(饿汉式)--------------------
class Singleton_hungry
{
private:
	Singleton_hungry()
	{
		cout << "Singleton_hungry 构造函数" << endl;
	}
public:
	static Singleton_hungry* getInstance()
	{
		return m_pSingleton_h;
	}
	static void freeInstance()
	{
		if (m_pSingleton_h != NULL)
		{
			delete m_pSingleton_h;
			m_pSingleton_h = NULL;
		}
	}
private:
	static Singleton_hungry* m_pSingleton_h;
	int temp;
};

/*☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
全局变量优先于main函数,所以输出结果是先显示“pSingleton1和pSingleton2是一个实例”
这也是饿汉模式的原理:就是静态变量在类外面初始化,并且在类的声明的下面。
在编译的时候,先给类开辟空间,然后给全局变量开辟空间,并给全局变量初始化。
全局变量调用类的构造,构造一个对象,然后开始进入main函数,执行main函数体。
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆*/

//饿汉式和懒汉式不同的地方。就是静态变量先new 一个对象,全局变量的初始化优先于main函数执行。所以先显示“pSingleton1和pSingleton2是一个实例”
Singleton_hungry* Singleton_hungry::m_pSingleton_h = new Singleton_hungry;

int main()
{
	//------------------------懒汉式--------------------------------
	Singleton_lazy *pSingleton1 = Singleton_lazy::getInstance();
	Singleton_lazy *pSingleton2 = Singleton_lazy::getInstance();
	if (pSingleton1 == pSingleton2)
	{
		cout << "pSingleton1和pSingleton2是一个实例" << endl;
	}
	else
	{
		cout << "pSingleton1和pSingleton2不是同一个实例" << endl;
	}
	Singleton_lazy::freeInstance();

	//-------------------------饿汉式------------------------------------
	Singleton_hungry *pSingleton_h1 = Singleton_hungry::getInstance();
	Singleton_hungry *pSingleton_h2 = Singleton_hungry::getInstance();
	if (pSingleton_h1 == pSingleton_h2)
	{
		cout << "pSingleton_h1和pSingleton_h2是同一个实例" << endl;
	}
	else
	{
		cout << "pSingleton_h1和pSingleton_h2不是同一个实例" << endl;
	}
	Singleton_hungry::freeInstance();

	system("pause");
}

懒汉式单实例和多线程问题

代码2:

<span style="font-size:14px;">#include "stdafx.h"
#include "windows.h"
#include "winbase.h"
#include "afxmt.h"
#include <process.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

/*☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
	懒汉模式和多线程结合时,当在构造函数中Sleep 时,当一个线程创建对象并进入构造函数时,
	会先把线程挂起,然后下一个线程再次创建对象并进入构造函数时,也会挂起线程,此时,
	每个线程判定m_p_t都是NULL,这样会导致创建多个对象。也就是每个线程都会创建一个类的对象,
	这就变成多实例,而不是单实例,同时还会出现资源共享的情况,可能出现资源锁。
	也就是抢占资源,会造成程序的输出不确定的结果。这就是线程间的同步问题。
	为了保证线程的同步,可以使用临界区技术。(还可以使用互斥量、信号量)
	就是把线程共享的部分锁定,保证相同的部分每次都只有一个线程进行操作。

	    临界区(Critical Section)。临界区对象通过提供一个进程内所有线程必须
	共享的对象来控制线程。只有拥有那个对象的线程可以访问保护资源。在另一个线
	程可以访问该资源之前,前一个线程必须释放临界区对象,以便新的线程可以索取
	对象的访问权。
	    互斥量(Mutex Semaphore)。互斥量的工作方式非常类似于临界区,只是
	互斥量不仅保护一个进程内为多个线程使用的共享资源,而且还可以保护系统中两
	个或多个进程之间的的共享资源。
	    信号量(Semaphore)。信号量可以允许一个或有限个线程访问共享资源。
	它是通过计数器来实现的,初始化时赋予计数器以可用资源数,当将信号量提供给
	一个线程时,计数器的值减1,当一个线程释放它时,计数器值加1。当计数器值小
	于等于0时,相应线程必须等待。信号量是Windows98同步系统的核心。从本质上
	讲,互斥量是信号量的一种特殊形式。
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆*/

class Singleton_lazy_thread
{
private:
	Singleton_lazy_thread()
	{
		cout << "Singleton_lazy_thread() 构造函数begin\n";
		Sleep(1000);
		cout << "Singleton_lazy_thread() 构造函数end\n";
	}
public:
	static Singleton_lazy_thread* getInstance()
	{
		if (m_p_t == NULL)
		{
			count++;
			m_p_t=new Singleton_lazy_thread;
		}
		return m_p_t;
	}
	static void freeInstance()
	{
		if (m_p_t != NULL)
		{
			delete m_p_t;
			m_p_t = NULL;
		}
	}
	static void printS() //测试函数
	{
		cout << "Singleton_lazy_thread printS test" << endl;
	}
private:
	static Singleton_lazy_thread* m_p_t;
	static int count;
	int temp;
};

Singleton_lazy_thread* Singleton_lazy_thread::m_p_t = NULL;
int Singleton_lazy_thread::count = 0;
void MyThreadFunc(void *)
{
	//cout << "我是线程体 ...." << endl;
	cout << "我是线程体 ....\n";
	Singleton_lazy_thread::getInstance()->printS();
}

//////////////////////////////////////////////////////////////////////////
/*--------------------------使用临界区技术(锁定线程公共操作部分)-----------------------------*/
// 线程同步问题
//临界区
//类CCriticalSection的对象表示一个“临界区”,它是一个用于同步的对象,
//同一时刻只允许一个线程存取资源或代码区。
//临界区在控制一次只有一个线程修改数据或其它的控制资源时非常有用。
//使用时必须包含头文件#include "afxmt.h"
static CCriticalSection cs;

class Singleton_lazy_thread_Sync
{
private:
	Singleton_lazy_thread_Sync()
	{
		//TRACE()宏一般是用在mfc中的,用于将调试信息输出到vs的输出窗口中(这是关键),
		//这在使用vs作为开发工具的时候,是非常方便的。
		//TRACE("Singleton begin\n");
		m_count++;
		cout << "Singleton_lazy_thread_Sync() 构造函数begin\n";
		Sleep(1000);
		cout << "Singleton_lazy_thread_Sync() 构造函数end\n";
		//TRACE("Singleton end\n");
	}
	Singleton_lazy_thread_Sync(const Singleton_lazy_thread_Sync&);
	Singleton_lazy_thread_Sync& operator=(const Singleton_lazy_thread_Sync&);
public:
	static Singleton_lazy_thread_Sync* getInstance()
	{
		if (m_p_t_Sync == NULL) //第一次检查看实例有没有被创建
		{
			cs.Lock(); //只有当pInstance等于null时,才开始使用枷锁机制 二次检查
			//第二个线程在创建时不知道第一个线程已经创建了,
			//所以在临界区检查,防止被多次创建(著名的二次检查)
			if (m_p_t_Sync == NULL) //double check 。第二次检查,
			{
				m_count++;
				m_p_t_Sync = new Singleton_lazy_thread_Sync;
			}
			cs.Unlock();
		}
		return m_p_t_Sync;
	}
	static void freeInstance()
	{
		if (m_p_t_Sync != NULL)
		{
			delete m_p_t_Sync;
			m_p_t_Sync = NULL;
		}
	}
	static void printS() //测试函数
	{
		cout << "Singleton_lazy_thread_Sync printS test" << endl;
	}
	static void printV()
	{
		//TRACE("printV..m_count:%d \n", m_count);
		cout << "printV..m_count:" << m_count << endl;
	}
private:
	static Singleton_lazy_thread_Sync* m_p_t_Sync;
	static int m_count;
	int temp;
};
Singleton_lazy_thread_Sync & Singleton_lazy_thread_Sync::operator=(const Singleton_lazy_thread_Sync &)
{
	// TODO: 在此处插入 return 语句
}
Singleton_lazy_thread_Sync* Singleton_lazy_thread_Sync::m_p_t_Sync = NULL;
int Singleton_lazy_thread_Sync::m_count = 0;
void MyThreadFuncSync(void *)
{
	//cout << "我是线程体 ...." << endl;
	cout << "我是线程体 ....\n";
	Singleton_lazy_thread_Sync::getInstance()->printV();
}

int main()
{
	HANDLE hThread1[10];
	for (int i = 0; i < 3;i++)
	{
		hThread1[i] = (HANDLE)_beginthread(MyThreadFunc, 0, NULL);
	}
	for (int i = 0; i < 3;i++)
	{
		WaitForSingleObject(hThread1[i], INFINITE);
	}
	cout << "hello word" << endl;
	//////////////////////////////////////////////////////////////////////////
	cout << "---------------线程同步问题---------------" << endl;
	int i = 0;
	DWORD dwThreadId[201], dwThrdParam = 1;
	HANDLE hThread[201];
	int threadnum = 3;
	for (i = 0; i < threadnum; i++)
	{
		//hThread[i] = (HANDLE)_beginthreadex( NULL, 0, &threadfunc, NULL, 0,&dwThreadId[i] );
		hThread[i] = (HANDLE)_beginthread(&MyThreadFuncSync, 0, 0);
		if (hThread[i] == NULL)
		{
			//TRACE("begin thread %d error!!!\n", i);
			printf("begin thread %d error!!!\n", i);
			break;
		}
	}
	for (i = 0; i < threadnum; i++)
	{
		WaitForSingleObject(hThread[i], INFINITE);
	}
	system("pause");
	return 0;
}

2.工厂模式

#include <iostream>
#include <stdlib.h>
using namespace std;

class Fruit
{
public:
	virtual void getFruit() = 0;
protected:
private:
};

class Banana:public Fruit
{
public:
	virtual void getFruit()
	{
		cout << "我是香蕉" << endl;
	}
protected:
private:
};

class Apple :public Fruit
{
public:
	virtual void getFruit()
	{
		cout << "我是苹果" << endl;
	}
protected:
private:
};

class Pear :public Fruit
{
public:
	virtual void getFruit()
	{
		cout << "我是梨" << endl;
	}
protected:
private:
};

//--------------------------简单工厂模式。------------------------
//也就是所有的操作都是在类里面完成的,不符合设计模式的设计规则
//所以可以进行改进。
class Factory_Simple
{
public:
	Fruit* produceFruit(char* p)
	{
		if (strcmp(p, "banana") == 0)
		{
			return new Banana;
		}
		if (strcmp(p, "apple") == 0)
		{
			return new Apple;
		}
		if (strcmp(p, "pear") == 0)
		{
			return new Pear;
		}
		else
		{
			printf("不支持\n");
			return NULL;
		}
	}
protected:
private:
};

//////////////////////////////////////////////////////////////////////////
/*
         改进后的工厂模式
为每个对象都产生一个单独的工厂,专门生产一种产品。
*/
class Factory
{
public:
	virtual Fruit* produceFruit() = 0;
protected:
private:
};

class BananaFactory:public Factory
{
public:
	//函数的返回值是一个父类的指针
	virtual Fruit* produceFruit()
	{
		//函数体里面返回的是一个子类的指针
		//通过父类的指针或者引用来调用子类的函数,实现多态
		return new Banana;
	}
protected:
private:
};

class AppleFactory:public Factory
{
public:
	virtual Fruit* produceFruit()
	{
		return new Apple;
	}
protected:
private:
};
class PearFactory :public Factory
{
public:
	virtual Fruit* produceFruit()
	{
		return new Pear;
	}
protected:
private:
};

int main()
{
	cout << endl << "---------简单工厂模式---------" << endl;
	Fruit* fruit = NULL;
	Factory_Simple* factorySimple = new Factory_Simple;
	fruit = factorySimple->produceFruit("banana");
	fruit->getFruit();
	delete fruit;
	fruit = NULL;

	fruit = factorySimple->produceFruit("apple");
	fruit->getFruit();
	delete fruit;
	fruit = NULL;

	fruit = factorySimple->produceFruit("pear");
	fruit->getFruit();
	delete factorySimple;
	delete fruit;
	fruit = NULL;
	factorySimple = NULL;
	system("pause");

	//////////////////////////////////////////////////////////////////////////
	//改进后的工厂(工厂抽象成一个虚基类)
	cout << endl << "---------改进后的工厂模式---------" << endl;
	Factory *factory = NULL;
	factory = new BananaFactory;
	fruit = factory->produceFruit();
	fruit->getFruit();
	delete factory;
	delete fruit;
	fruit = NULL;

	factory = new AppleFactory;
	fruit = factory->produceFruit();
	fruit->getFruit();
	delete factory;
	delete fruit;
	fruit = NULL;

	factory = new PearFactory;
	fruit = factory->produceFruit();
	fruit->getFruit();
	delete factory;
	delete fruit;
	system("pause");
	return 0;
}

3.抽象工厂模式

#include <iostream>
#include <stdlib.h>
using namespace std;

class Fruit
{
public:
	virtual void getFruitName() = 0;
protected:
private:
};

class Banana :public Fruit
{
public:
	virtual void getFruitName()
	{
		cout << "香蕉" << endl;
	}
protected:
private:
};
class Apple :public Fruit
{
public:
	virtual void getFruitName()
	{
		cout << "苹果" << endl;
	}
protected:
private:
};
class Pear : public Fruit
{
public:
	virtual void getFruitName()
	{
		cout << "梨" << endl;
	}
protected:
private:
};
class Mango : public Fruit
{
public:
	virtual void getFruitName()
	{
		cout << "芒果" << endl;
	}
protected:
private:
};

//////////////////////////////////////////////////////////////////////////

//工厂模式只能生产一个产品。(要么香蕉、要么苹果)
//抽象工厂可以一下生产一个“产品族”(里面有很多产品组成),就是可以生产多种产品。

//缺点是:
//抽象工厂的缺点就是产品线写死了。
//如果需要添加新的产品,就需要在原来抽象类上改
//////////////////////////////////////////////////////////////////////////
class AbstractFactory
{
public:

	//抽象工厂的缺点就是产品线写死了。
	//如果需要添加新的产品,就需要在原来抽象类上改

	virtual Fruit* produceBanana() = 0;
	virtual Fruit* produceApple() = 0;
	virtual Fruit* producePear() = 0;
	virtual Fruit* produceMango() = 0;
protected:
private:
};

class Factory : public AbstractFactory
{
public:
	virtual Fruit* produceApple()
	{
		return new Apple;
	}
	virtual Fruit* produceBanana()
	{
		return new Banana;
	}
	virtual Fruit* producePear()
	{
		return new Pear;
	}
	virtual Fruit* produceMango()
	{
		return new Mango;
	}
protected:
private:
};

int main()
{
	cout << "---------------抽象工厂模式---------------" << endl;

	Factory* factory = new Factory;
	Fruit* fruit = NULL;

	fruit = factory->produceApple();
	fruit->getFruitName();
	delete fruit;
	fruit = NULL;

	fruit = factory->produceBanana();
	fruit->getFruitName();
	delete fruit;
	fruit = NULL;

	fruit = factory->producePear();
	fruit->getFruitName();
	delete fruit;
	fruit = NULL;

	fruit = factory->produceMango();
	fruit->getFruitName();
	delete fruit;
	fruit = NULL;

	delete factory;
	factory = NULL;

	system("pause");
	return 0;
}

4.建造者模式

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

//////////////////////////////////////////////////////////////////////////
/*
1) Builder:为创建产品各个部分,统一抽象接口。
2) ConcreteBuilder:具体的创建产品的各个部分,部分A, 部分B,部分C。
3) Director:构造一个使用Builder接口的对象。
4) Product:表示被构造的复杂对象。
ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,
包括将这些部件装配成最终产品的接口。

适用情况:
一个对象的构建比较复杂,将一个对象的构建(?)和对象的表示(?)进行分离。

建造者模式设计三个类对象(案例):
	设计者(也叫指挥者)、
	工程队(可以造别墅、平房、四合院等),
	房子(有门、窗户、墙等)
*/
//////////////////////////////////////////////////////////////////////////

/////////////////////////////////建造者模式产生原因///////////////////////

class House_Previous
{
public:
	//set 属性
	void setDoor(string door){ this->m_door = door; }
	void setWindow(string window){ this->m_window = window; }
	void setWall(string wall){ this->m_wall = wall; }

	//get 属性
	string getDoor(){ cout << m_door << endl; return m_door; }
	string getWindow(){ cout << m_window << endl; return m_window; }
	string getWall(){ cout << m_wall << endl; return m_wall; }
protected:
private:
	string m_door;
	string m_window;
	string m_wall;
};

class Builder_Previous
{
public:
	Builder_Previous()
	{
		this->m_house = new House_Previous;
	}
	void buildHouse()
	{
		buildDoor();
		buildWindow();
		buildWall();
	}

	void buildDoor()
	{
		m_house->setDoor("门");
	}
	void buildWindow()
	{
		m_house->setWindow("窗户");
	}
	void buildWall()
	{
		m_house->setWall("墙壁");
	}
	House_Previous* getHouse()
	{
		return m_house;
	}
protected:
private:
	House_Previous *m_house;
};

///////////////////////建造者模式/////////////////////////////
/*

建造者模式设计三个类对象(案例):
	设计者(也叫指挥者、主管)、------------------  class Director  主管类
	工程队(可以造别墅、平房、四合院等),------  class Builder   工程队类
	房子(有门、窗户、墙等)--------------------  class House     房子类

扩展:
		设计师(指挥者) 负责建造逻辑。建筑队 干具体的活
	再让设计师分三六九等,指挥三六九等建筑队,建造三六九等的房子
	也就是可以把设计师在细化分类,建筑队也可以再细化分类,房子同样可以细化不同的房子。
	就是“主管抽象、工程队抽象、房子抽象”。
*/

class House
{
public:
	virtual void setDoor(string door){}; //虚函数必须有实现代码,纯虚函数可以没实现代码。
	virtual void setWindow(string window){};
	virtual void setWall(string wall){};

	string getDoor(){ cout << m_door << endl; return m_door; };
	string getWindow(){ cout << m_window << endl; return m_window; };
	string getWall(){ cout << m_wall << endl; return m_wall; };

protected:
	string m_door;
	string m_window;
	string m_wall;
private:
};

//平房、公寓
class Flat :public House
{
public:
	virtual void setDoor(string door){ this->m_door = door; }
	virtual void setWindow(string window){ this->m_window = window; }
	virtual void setWall(string wall){ this->m_wall = wall; }
protected:
private:
};

// 楼房
class Floor :public House
{
public:
	virtual void setDoor(string door){ this->m_door = door; }
	virtual void setWindow(string window){ this->m_window = window; }
	virtual void setWall(string wall){ this->m_wall = wall; }
protected:
private:
};

// 别墅
class Villa :public House
{
public:
	virtual void setDoor(string door){ this->m_door = door; }
	virtual void setWindow(string window){ this->m_window = window; }
	virtual void setWall(string wall){ this->m_wall = wall; }
protected:
private:
};

class Builder //建造者
{
public:
	/*void buildHouse()
	{
	buildDoor();
	buildWindow();
	buildWall();
	}*/
	virtual void buildHouse() = 0;
	virtual void buildDoor() = 0;
	virtual void buildWindow() = 0;
	virtual void buildWall() = 0;
protected:
	House *m_house;
private:
};

class SanDengBuilder : public Builder //三等builder
{
public:
	SanDengBuilder(House* house)
	{
		m_house = house;
	}
	virtual void buildHouse()
	{
		buildDoor();
		buildWindow();
		buildWall();
	}
	virtual void buildDoor()
	{
		m_house->setDoor("三等门");
	}
	virtual void buildWindow()
	{
		m_house->setWindow("三等窗户");
	}
	virtual void buildWall()
	{
		m_house->setWall("三等墙壁");
	}
protected:
private:
};
class LiuDengBuilder : public Builder // 六等builder
{
public:
	LiuDengBuilder(House *house)
	{
		m_house = house;
	}
	virtual void buildHouse()
	{
		buildDoor();
		buildWindow();
		buildWall();
	}
	virtual void buildDoor()
	{
		m_house->setDoor("六等门");
	}
	virtual void buildWindow()
	{
		m_house->setWindow("六等窗户");
	}
	virtual void buildWall()
	{
		m_house->setWall("六等墙壁");
	}
protected:
private:
};
class JiuDengBuilder : public Builder //九等builder
{
public:
	JiuDengBuilder(House *house)
	{
		m_house = house;
	}
	virtual void buildHouse()
	{
		buildDoor();
		buildWindow();
		buildWall();
	}
	virtual void buildDoor()
	{
		m_house->setDoor("九等门");
	}
	virtual void buildWindow()
	{
		m_house->setWindow("九等窗户");
	}
	virtual void buildWall()
	{
		m_house->setWall("九等墙壁");
	}
protected:
private:
};

class Director
{
public:
	virtual void Construct() = 0;
protected:
	Builder* m_builder;
private:
};

class SanDengDirector : public Director
{
public:
	SanDengDirector(Builder *builder)
	{
		m_builder = builder;
	}
	virtual void Construct()
	{
		m_builder->buildDoor();
		m_builder->buildWindow();
		m_builder->buildWall();
	}
protected:
private:
};

class LiuDengDirector : public Director
{
public:
	LiuDengDirector(Builder *builder)
	{
		m_builder = builder;
	}
	virtual void Construct()
	{
		m_builder->buildDoor();
		m_builder->buildWindow();
		m_builder->buildWall();
	}
protected:
private:
};

class JiuDengDirector : public Director
{
public:
	JiuDengDirector(Builder *builder)
	{
		m_builder = builder;
	}
	virtual void Construct()
	{
		m_builder->buildDoor();
		m_builder->buildWindow();
		m_builder->buildWall();
	}
protected:
private:
};

int main()
{
	cout << "-----------------客户直接造房子-----------------" << endl;
	House_Previous *house_pre = new House_Previous;
	house_pre->setDoor("门");
	house_pre->setWindow("窗户");
	house_pre->setWall("墙壁");

	house_pre->getDoor();
	house_pre->getWindow();
	house_pre->getWall();
	delete house_pre; house_pre = NULL;

	cout << "-----------------工程队造房子-----------------" << endl;
	Builder_Previous *builder_Previous = new Builder_Previous;
	builder_Previous->buildDoor();
	builder_Previous->buildWindow();
	builder_Previous->buildWall();

	house_pre = builder_Previous->getHouse();
	house_pre->getDoor();
	house_pre->getWindow();
	house_pre->getWall();
	delete house_pre; house_pre = NULL;
	delete builder_Previous; builder_Previous = NULL;

	cout << "---------------建造者模式------------------" << endl;

	//定义房子
	Flat *flat = new Flat; //平房
	Floor *floor = new Floor; //楼房
	Villa *villa = new Villa; //别墅

	//定义基类的指针
	Director *director = NULL;
	Builder *builder = NULL;
	House* house = NULL;

	SanDengBuilder *sanBuilder = new SanDengBuilder(flat);
	LiuDengBuilder *liuBuilder = new LiuDengBuilder(floor);
	JiuDengBuilder *jiuBuilder = new JiuDengBuilder(villa);

	cout << "---------三等指挥,三等建造者,建设平房-------------" << endl;
	director = new SanDengDirector(sanBuilder);
	director->Construct();
	flat->getDoor();
	flat->getWindow();
	flat->getWall();

	cout << "---------三等指挥,三等建造者,建设楼房-------------" << endl;
	director = new SanDengDirector(liuBuilder);
	director->Construct();
	floor->getDoor();
	floor->getWindow();
	floor->getWall();

	cout << "---------三等指挥,三等建造者,建设别墅-------------" << endl;
	director = new SanDengDirector(jiuBuilder);
	director->Construct();
	villa->getDoor();
	villa->getWindow();
	villa->getWall();

	cout << endl << "因为new的太多,不再一个一个删除,先不用管内存泄露" << endl;
	system("pause");
	return 0;
}

5.原型模式

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

//////////////////////////////////////////////////////////////////////////
/*                             原型模式
Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。
使用Prototype模式创建的实例,具有与原型一样的数据。
1)由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。
2)目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,
   不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
3)根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

		 其实原型模式就是返回一个和自己一模一样的类型的数据(深浅拷贝)

*/
//////////////////////////////////////////////////////////////////////////

class Person
{
public:
	virtual Person* clone() = 0;
	virtual void printT() = 0;
protected:
	string m_name;
	int m_age;
	char *m_resume;
private:
};

class CPlusPlusProgrammer : public Person
{
public:
	CPlusPlusProgrammer()
	{
		m_name = "";
		m_age = 0;
		m_resume = NULL;
	}
	CPlusPlusProgrammer(string name, int age)
	{
		m_name = name;
		m_age = age;
		m_resume = NULL;
		setResume("aaaa");
	}
	void setResume(char *p)
	{
		if (m_resume != NULL)
		{
			delete m_resume;
		}
		m_resume = new char[strlen(p) + 1];
		strcpy(m_resume, p);
	}
	virtual Person* clone()
	{
		CPlusPlusProgrammer *tmp = new CPlusPlusProgrammer;
		*tmp = *this;  // 浅拷贝 (深拷贝需要考虑开辟空间的问题) 使用默认拷贝构造函数(值传递)
		return tmp;
	}
	virtual void printT()
	{
		cout << "m_name"<<m_name << " m_age" << m_age << "m_resume:" << m_resume << endl;
	}
protected:
private:
};

int main()
{
	Person *c1 = new CPlusPlusProgrammer("皇帝",20);
	c1->printT();

	Person *c2 = c1->clone();
	c2->printT();

	system("pause");
	return 0;
}
时间: 2024-10-20 22:00:27

设计模式1—创建型模式的相关文章

设计模式之创建型模式(上)

没有总结的学习不算学习,这一个月的学习可谓收获多多啊,接下来与大家分享一下. 一.设计模式的分类 总体来说设计模式分为三大类: 1.创建型模式,共五种. 2.结构型模式,共七种. 3.行为型模式,共十一种. 首先研究创建型模式 二. 概述 创建型模式,就是用来创建对象的模式,抽象了实例化的过程.它帮助一个系统独 立于如何创建.组合和表示它的那些对象. 三. 为什么需要创建型模式 所有的创建型模式都有两个永恒的主旋律: 第一,它们都将系统使用哪些具体类的信息封装起来: 第二,它们隐藏了这些类的实例

设计模式 (创建型模式)

  设计模式 创建型模式 1.创建型模式         创建型模式,包括了5种设计模式,分别是 Singleton (单例模式),Factory(工厂模式),AbstractFactory(抽象工厂模式),Builder(创建者),Prototype(原型) ,创建型模式主要作用就是抽象了实例化过程.他们帮助一个系统独立于如何创建.组合和表示他的那些对象.一个类创建型模式使用继承改变被实例化的类.而一个对象创建型模式将实例化委托给另一个对象. 2.Singleton (单例模式)      单

设计模式系列 - 创建型模式

单例模式 懒汉式,线程不安全. 除非是单线程程序,否则不推荐使用. public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } 饿汉式,线程安全 当程序总是使用这个

设计模式之创建型模式

一.前言 设计模式应该是在软件工程的背景下进行讨论的,而不是为了设计模式而论设计模式.设计模式是软件工程面向对象设计工作中一个抽象.归纳.总结的过程.软件设计的最高目标和最高准则就是易扩展,易复用,易维护, 灵活性高,高可用,稳定性高一切的设计原则和设计模式最终的目标都是向这个目标靠拢的. 二.面向对象设计六大原则 任何的设计模式都是基于面向对象的特性(抽象.封装.继承.多态)和设计原则进行设计和实现的,是面向对象设计原则的在不同场景下的实现方案. 抽象:抽离变化的部分,引入抽象层,实现具体实现

Java设计模式之创建型模式

创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类-工厂类 工厂类的目的是为了产生Sender对象,通过不同的参数传入产生不同的对象. 将工厂类中的工厂方法改为多个工厂方法即为多个工厂方法的设计模式 将工厂类中的工场方法改为static即为静态工厂方法设计模式 二.抽象工厂方法模式:接口-实现类-工厂类 特点是: 工厂类实现某个接口,利于以后扩展,比如可以增加BlueTooth的工厂类. 工厂设计模式是抽象工厂设计模式的一个特例. 三.

设计模式_创建型模式_简单工厂模式

转载自:http://blog.csdn.net/lovelion  作者:刘伟 简单工厂模式并不属于GoF 23个经典设计模式,但通常将它作为学习其他工厂模式的基础,它的设计思想很简单,其基本流程如下:        首先将需要创建的各种不同对象(例如各种不同的Chart对象)的相关代码封装到不同的类中,这些类称为具体产品类, 而将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类: 然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方

设计模式之“创建型模式”

创建型模式主要分为五大模式,分别为:抽象工厂模式.建造者模式.工厂方法模式.原型模式.单例模式. 抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 一.优点 1.易于交换产品系列. 2.它让具体的创建实例过程与客户端分离. 二.反射 Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")需要在程序顶端写上using System.Reflection;来引用Reflection所有用简单工

设计模式_创建型模式——工厂方法

工厂方法(Factory Method):工厂方法模式属于类的创建型模式.在工厂方法模式中,父类负责定义创建产品对象的工厂接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化哪一个类. abstract Product factoryMethod(String type) abstract:工厂方法是抽象的,依赖子类来处理对象的创建 Product:工厂方法返回一个产品,超类中定义的方法,通常使用到工厂方法的返回值 String:工厂方法

设计模式_创建型模式

创建型模式与对象创建有关. 1. Abstract Factory (抽象工厂) 定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用:一个系统要独立于它的产品的创建.组合和表示时. 与工厂模式的区别:工厂模式的一个工厂接口的子类只能实例化一个产品:抽象工厂能实例多个产品. 例子代码: package designModel; // 产品1 interface IProduct1 { } class Product1A implements IProduct1 { }