关闭

设计模式-------创建型模式总览

标签: 设计模式创建型模式
411人阅读 评论(0) 收藏 举报
分类:

申明:本文属于本人(xzben)个人总结与看法,如果您有不同看法或我有哪里不正确,请指出!

设计模式宗旨(个人):

       在人类社会中各种巧妙的技巧都是为了偷懒,人们也在思考如何能够让自己更好的偷懒。所以设计模式也是如此,它让我们在编写代码的时候能够少思考,让我们在使用现成的代码时候更加方便。让我在维护代码的时候少做事情而达到需求。所以使用设计模式是为了偷懒。如果你发现你用了设计模式不能偷懒说明你用得不对。所以设计模式是一种给我们偷懒的艺术。用它就要达到偷懒的宗旨。

创建型模式的目的:

      创建模式主要目的,就是将系统中对象的实例化提取出来专门管理,这样对于系统中对象的实例化管理更加方便简洁。

类型及特点:

1、抽象工厂: 

       将系统中一系列对象的实例化过程,封装在一个专门的类中,可以通过对此类的继承实现一系列的对象的实例化的重定义。要与工厂模式区别的是抽象工厂模式用于管理一系列相互关联的类的工厂。所以抽象工厂是基于工厂模式的。

2、Build模式:

       将一个复杂的对象的构建过程封装在一个类中,使使用此复杂对象的用户能够忽略此复杂对象中各个子对象的组成。通过Build模式将一个复杂对象一步一步安装用户的指定构建出最终的对象。

3、简单工厂模式: 

       将对象的实例化封装在一个类中,也就将对象的创建隐藏起来了,使用户不必关系具体是怎么创建的。与抽象工厂的区别在于,简单工厂纠结于同一系(基于同一父类的)列类的的创建到底是要哪一个。简单工厂模式是创建型模式的基础模式,其它四种创建模式很大程度上都有简单工厂的影子。

4、Prototype模式:

      个人感觉Prototype模式是抽象工厂模式的一种升级版本,它通过将系统中的对象原件化,所谓的原件化就是将对象抽象化并提供一个clone方法实现对象的自身复制。然后再创建系统元件工厂的时候传递给工厂一些基础元件,然后在使用此工厂实例化对象的时候都是使用指定的元件的clone。这种方法的好处是避免了抽象工厂方法要将每一种元件构成的工厂定义一个类。

5、Singleton模式:

       Singleton模式也叫单例模式,也就是说通过此模式实现此类的对象全局唯一,而不增加额外的开销。

简单工厂实现:

简单工厂的目的就是要将对象的创建提取出来放到一个类中管理。所以其实现也很简单。定义一个类在类中提供接口专门创建对应的类并返回对应的指针。
#include <iostream>
using namespace std;


class Base 
{
public:
	Base()
	{
		printf("Construct Base");
	}
	~Base()
	{
		printf("Destruct Base");
	}
};

class ClassA : public Base
{
public:
	ClassA()
	{
		printf("Construct ClassA");
	}
	~ClassA()
	{
		printf("Destruct ClassA");
	}
};

class ClassB : public Base
{
public:
	ClassB()
	{
		printf("Construct ClassB");
	}
	~ClassB()
	{
		printf("Destruct ClassB");
	}
};


class Factory
{
public:
	Factory(){};
	~Factory(){};
	enum{
		TYPE_BASE,
		TYPE_A,
		TYPE_B,
	};
	Base* Create(int type)
	{
		Base *pRet = nullptr;

		switch(type)
		{
		case TYPE_BASE:
			pRet = new Base;
			break;
		case TYPE_A:
			pRet = new ClassA;
			break;
		case TYPE_B:
			pRet = new ClassB;
			break;
		}
		return pRet;
	}

};

int main()
{
	Factory factory;
	Base *p1 = factory.Create(Factory::TYPE_BASE);
	Base *p2 = factory.Create(Factory::TYPE_A);
	Base *p3 = factory.Create(Factory::TYPE_B);
}

抽象工厂实现:

抽象工厂的目的是:管理一系列相关类的创建,所以它的实现也很简单,我们只要在一个类中提供一系列的接口,这些接口创建对应的对象并返回指针。
#include <iostream>
using namespace std;


class classA 
{
public:
	classA()
	{
		printf("Construct classA");
	}
	~classA()
	{
		printf("Destruct classA");
	}
};

class classB 
{
public:
	classB()
	{
		printf("Construct classB");
	}
	~classB()
	{
		printf("Destruct classB");
	}
};

class AbstractFactory
{
public:
	AbstractFactory(){};
	~AbstractFactory(){};

	classA* CreateA()
	{
		return new classA;
	}

	classB* CreateB()
	{
		return new classB;
	}
};

int main()
{
	AbstractFactory factory;
	classA *pA = factory.CreateA();
	classB *pB = factory.CreateB();
}

Build模式实现:

Build 模式的目的是为了将复杂对象的创建过程分解成一些小步骤并交给一个专门的类来管理。所以要实现此模式,我们只要定义一个类在类中提供一系列的接口,每一个接口对应复杂对象构建的一个步骤,并且能够在最好获取一个构建完成的对象。

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

class Display
{
public:
	Display(const char *szName, int nSize)
	{
		strcpy(m_szName, szName);
		m_nSize = nSize;
	}
	~Display()
	{

	}
private:
	char m_szName[50];//显示器品牌
	int	 m_nSize;  //显示器尺寸
};
class RAM
{
public:
	RAM(const char *szName, int nSize)
	{
		strcpy(m_szName, szName);
		m_nSize = nSize;
	}
	~RAM()
	{

	}
private:
	char m_szName[50];//内存厂商
	int	 m_nSize;//内存大小
};
class CPU
{
public:
	CPU(const char *szName, int nCores)
	{
		strcpy(m_szName, szName);
		m_nCores = nCores;
	}
	~CPU()
	{

	}
private:
	char m_szName[50];//CPU厂商
	int	 m_nCores;//内核数
};
class Keyboard
{
public:
	Keyboard(const char *szName)
	{
		strcpy(m_szName, szName);
	}
	~Keyboard()
	{

	}
private:
	char m_szName[50];//键盘厂商
};

class Compute
{
	friend class BuildCompute;
public:
	Compute()
	{
		m_pKeyboard = nullptr;
		m_pCpu = nullptr;
		m_pDisplay = nullptr;
		m_pRam[0] = m_pRam[1] = nullptr;
		m_nRamNum = 0;
	}
	~Compute()
	{

	}

private:
	Keyboard *m_pKeyboard;
	CPU		 *m_pCpu;
	Display  *m_pDisplay;
	RAM		 *m_pRam[2]; //两个内存插槽
	int		  m_nRamNum;
};

class BuildCompute
{
public:
	BuildCompute()
	{
		m_pCurBuildCompute = nullptr;
	}

	~BuildCompute()
	{

	}
	
	void CreateCompute()
	{
		m_pCurBuildCompute = new Compute;
	}
	
	bool AddCpu(const char *szName, int nCores)
	{
		if(nullptr != m_pCurBuildCompute->m_pCpu)
			return false;
		m_pCurBuildCompute->m_pCpu = new CPU(szName, nCores);
		return true;
	}

	bool AddRam(const char *szName, int nSize)
	{
		int& nCurRamNum = m_pCurBuildCompute->m_nRamNum;
		if(2 <= nCurRamNum)
			return false;

		m_pCurBuildCompute->m_pRam[nCurRamNum++] = new RAM(szName, nSize);
		return true;
	}

	bool AddDisplay(const char *szName, int nSize)
	{
		if(nullptr != m_pCurBuildCompute->m_pDisplay)
			return false;
		m_pCurBuildCompute->m_pDisplay = new Display(szName, nSize);
		return true;
	}

	bool AddKeyboar(const char *szName)
	{
		if(nullptr != m_pCurBuildCompute->m_pKeyboard)
			return false;
		m_pCurBuildCompute->m_pKeyboard = new Keyboard(szName);
		return true;
	}
	Compute* GetCompute()
	{
		return m_pCurBuildCompute;
	}
private:
	Compute *m_pCurBuildCompute;
};

int main()
{
	BuildCompute build;
	build.CreateCompute();
	build.AddCpu("Intel-i7", 4);//intel i7 4核
	build.AddDisplay("HG", 40); // HG 40寸显示器
	build.AddKeyboar("双飞燕");//双飞燕 键盘
	build.AddRam("金士顿", 2); //金士顿2G内存
	build.AddRam("金士顿", 2); //金士顿2G内存

	Compute *pCompute = build.GetCompute();
}

Prototype模式实现:

     prototype(元件)模式, 个人觉得它就是为了解决抽象工厂每个配置方案需要定义一个子类这种麻烦的事情而存在,所以当系统中需要很多种配置方案,但是你又不想定义太多Code结构几乎没什么差别的Factory类(比如常见的是:修改了具体要实例化的子类),请选择Prototype模式。

#include<iostream>
using namespace std;

class MapSit
{
public:
	MapSit(){}
	~MapSit(){}
};

class Door : public MapSit
{
public:
	Door(){}
	~Door(){}
	Door(const Door& rDoor)
	{
		//复制构造
	}
	Door* Clone()
	{
		return new Door(*this);
	}
};

class Wall : public MapSit
{
public:
	Wall(){}
	~Wall(){}
	Wall(const Wall& rDoor)
	{
		//复制构造
	}
	Wall* Clone()
	{
		return new Wall(*this);
	}
};

class TransparentWall : public Wall
{
public:
	TransparentWall(){}
	~TransparentWall(){}
	TransparentWall(const TransparentWall& rDoor)
	{
		//复制构造
	}
	TransparentWall* Clone()
	{
		return new TransparentWall(*this);
	}
};

class Room : public MapSit
{
public:
	Room(){}
	~Room(){}
	Room(const Room& rDoor)
	{
		//复制构造
	}
	Room* Clone()
	{
		return new Room(*this);
	}
};

class BoomRoom : public Room
{
public:
	BoomRoom(){}
	~BoomRoom(){}
	BoomRoom(const BoomRoom& rDoor)
	{
		//复制构造
	}
	BoomRoom* Clone()
	{
		return new BoomRoom(*this);
	}
};

class Maze
{
public:
	Maze(){}
	~Maze(){}
	bool AddDoor(Door *pDoor)
	{
		//.....省略操作
		return true;
	}
	bool AddWall(Wall *pWall)
	{
		//.....省略操作
		return true;
	}
	bool AddRoom(Room *pRoom)
	{
		//.....省略操作
		return true;
	}
};

class PrototypeFactory
{
public:
	PrototypeFactory(Wall *pWall, Door* pDoor, Room* pRoom)
	{
		m_pWall = pWall;
		m_pDoor = pDoor;
		m_pRoom = pRoom;
	}
	~PrototypeFactory()
	{
	}
	Wall* CreateWall()
	{
		return m_pWall->Clone();
	}
	Door* CreateDoor()
	{
		return m_pDoor->Clone();
	}
	Room* CreateRoom()
	{
		return m_pRoom->Clone();
	}
private:
	Wall	*m_pWall;
	Door	*m_pDoor;
	Room	*m_pRoom;
};
int main()
{
	PrototypeFactory factor1(new Wall, new Door, new Room);
	PrototypeFactory factor2(new TransparentWall, new Door, new BoomRoom);

	Maze *pMaze;
	pMaze->AddDoor(factor1.CreateDoor());
	pMaze->AddRoom(factor2.CreateRoom());
	pMaze->AddWall(factor1.CreateWall());
}

Singleton模式实现:

        Singleton(单例)模式,就是为了得到一个类的全局唯一对象方便访问的接口。对于这个目的可能我们能想到的就是static成员。于是你就用类对象的static成员函数和成员变量,实现了一个这样的Code:
#include <iostream>
using namespace std;

class SingletonClass
{
public:
	~SingletonClass(){};
	static SingletonClass* Singleton();
	static void DestroySingleton();
	void TestFunction();
private:
	SingletonClass(){};
	static SingletonClass *m_pSingleton;
};

SingletonClass* SingletonClass::m_pSingleton = nullptr;

SingletonClass* SingletonClass::Singleton()
{
	if(nullptr == m_pSingleton)
		m_pSingleton = new SingletonClass;
	return m_pSingleton;
}
void SingletonClass::DestroySingleton()
{
	if(nullptr != m_pSingleton)
		delete m_pSingleton;
	m_pSingleton = nullptr;
}

void SingletonClass::TestFunction()
{
	printf("SingletonClass::TestFunction()\n");
}

int main()
{
	SingletonClass::Singleton()->TestFunction();
	SingletonClass::Singleton()->DestroySingleton();
	return 0;
}
        这个方法很明显是实现了全局唯一对象的方便访问,但是我们会发现我们还要显示的去将这个Singleton对象去删除,虽然在我这里小例子里面这个没什么问题,但是如果在一个复杂的系统里面就可能出现没有在合适的位置删除这个singleton对象而导致内存泄露。那下面我将介绍另一个方法解决这个问题。
#include <iostream>
using namespace std;

class SingletonClass
{
public:
	~SingletonClass(){};
	static SingletonClass* Singleton();
	void TestFunction();
private:
	SingletonClass(){};
};


SingletonClass* SingletonClass::Singleton()
{
	static SingletonClass _instance;
	return &_instance;
}

void SingletonClass::TestFunction()
{
	printf("SingletonClass::TestFunction()\n");
}

int main()
{
	SingletonClass::Singleton()->TestFunction();

	return 0;
}
        这个方法里面,不仅解决的上面的问题,而且简化了一些。而且功能是一样的。这个单例对象也将会在第一次调用时创建,并且在程序结束时释放。个人建议以后使用单例模式都使用这种方法。

如上代码都只是为了演示模式的实现,所以都比较简单粗略,随着具体的应用我相信他们会有着丰富的表达方式,但是他们的宗旨和原理都是大相径庭的。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:29663次
    • 积分:671
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:19篇
    • 译文:0篇
    • 评论:11条
    最新评论