1、定义
工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
2、介绍
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
设计思路:1、将基类定义为接口类(虚函数),运用基类指针指向子类对象,来确定具体实现方法。2、定义工厂类,作为统一调用的方法,通过工厂类,具体设置基类指向的子类对象。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
3、源码
类关系图:
具体实现思路:由父类指针指向子类对象,调用子类的方法
3.1、头文件
IHuman.h
#pragma once
class IHuman
{
public:
IHuman(void)
{
}
virtual ~IHuman(void)
{
}
virtual void Laugh() = 0;
virtual void Cry() = 0;
virtual void Talk() = 0;
};
YellowHuman.h
#pragma once
#include "ihuman.h"
class CYellowHuman :
public IHuman
{
public:
CYellowHuman(void);
~CYellowHuman(void);
void Laugh();
void Cry();
void Talk();
};
WhiteHuman.h
#pragma once
#include "ihuman.h"
class CWhiteHuman :
public IHuman
{
public:
CWhiteHuman(void);
~CWhiteHuman(void);
void Laugh();
void Cry();
void Talk();
};
BlackHuman.h
#pragma once
#include "ihuman.h"
class CBlackHuman :
public IHuman
{
public:
CBlackHuman(void);
~CBlackHuman(void);
void Laugh();
void Cry();
void Talk();
};
SimpleHumanFactory.h
#pragma once
#include "IHuman.h"
class CSimpleHumanFactory
{
public:
CSimpleHumanFactory(void);
virtual ~CSimpleHumanFactory(void);
virtual IHuman * CreateHuman(string classType);
};
3.2、实现
YellowHuman.cpp
#include "YellowHuman.h"
#include <iostream>
using std::cout;
using std::endl;
CYellowHuman::CYellowHuman(void)
{
}
CYellowHuman::~CYellowHuman(void)
{
}
void CYellowHuman::Cry()
{
cout << "黄色人种会哭" << endl;
}
void CYellowHuman::Laugh()
{
cout << "黄色人种会大笑,幸福呀!" << endl;
}
void CYellowHuman::Talk()
{
cout << "黄色人种会说话,一般说的都是双字节" << endl;
}
WhiteHuman.cpp
#include "StdAfx.h"
#include "WhiteHuman.h"
#include <iostream>
using std::cout;
using std::endl;
CWhiteHuman::CWhiteHuman(void)
{
}
CWhiteHuman::~CWhiteHuman(void)
{
}
void CWhiteHuman::Cry()
{
cout << "白色人种会哭" << endl;
}
void CWhiteHuman::Laugh()
{
cout << "白色人种会大笑,侵略的笑声" << endl;
}
void CWhiteHuman::Talk()
{
cout << "白色人种会说话,一般都是单字节" << endl;
}
BlackHuman.cpp
#include "BlackHuman.h"
CBlackHuman::CBlackHuman(void)
{
}
CBlackHuman::~CBlackHuman(void)
{
}
void CBlackHuman::Cry()
{
cout << "黑人会哭" << endl;
}
void CBlackHuman::Laugh()
{
cout << "黑人会笑" << endl;
}
void CBlackHuman::Talk()
{
cout << "黑人可以说话,一般人听不懂" << endl;
}
SimpleHumanFactory.cpp
#include "SimpleHumanFactory.h"
#include "YellowHuman.h"
#include "WhiteHuman.h"
#include "BlackHuman.h"
CSimpleHumanFactory::CSimpleHumanFactory(void)
{
}
CSimpleHumanFactory::~CSimpleHumanFactory(void)
{
}
IHuman * CSimpleHumanFactory::CreateHuman( string classType )
{
if (classType.compare("CYellowHuman") == 0)
{
return new CYellowHuman();
}
else if(classType.compare("CWhiteHuman") == 0)
{
return new CWhiteHuman();
}
else if(classType.compare("CBlackHuman") == 0)
{
return new CBlackHuman();
}
}
main.cpp
#include "IHuman.h"
#include "YellowHuman.h"
#include "WhiteHuman.h"
#include "BlackHuman.h"
#include "SimpleHumanFactory.h"
#include <iostream>
using std::cout;
using std::endl;
using std::string;
void DoSimpleFactory()
{
CSimpleHumanFactory *pSimpleHumanFactory = new CSimpleHumanFactory();
cout << "----------第一批人是这样的:黄种人" << endl;
IHuman *pYellowHuman = pSimpleHumanFactory->CreateHuman("CYellowHuman");
pYellowHuman->Cry();
pYellowHuman->Laugh();
pYellowHuman->Talk();
delete pYellowHuman;
cout << "----------第二批人是这样的:白种人" << endl;
IHuman *pWhiteHuman = pSimpleHumanFactory->CreateHuman("CWhiteHuman");
pWhiteHuman->Cry();
pWhiteHuman->Laugh();
pWhiteHuman->Talk();
delete pWhiteHuman;
cout << "----------第三批人是这样的:黑种人" << endl;
IHuman *pBlackHuman = pSimpleHumanFactory->CreateHuman("CBlackHuman");
pBlackHuman->Cry();
pBlackHuman->Laugh();
pBlackHuman->Talk();
delete pBlackHuman;
}
int main()
{
DoSimpleFactory();
system("pause");
return 0;
}
4、结果
参考文献:《菜鸟教程》 https://blog.csdn.net/phiall/article/details/52199659博客