工厂方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
实例
main.cc:
#include "nike_factory.h"
#include "asics_factory.h"
#include "nike_running_shoe.h"
#include "asics_running_shoe.h"
#include <windows.h>
/*
design_pattern:factory_method
*/
int main(){
Factory *nike_factory = new NikeFactory();
Factory *asics_factory = new AsicsFactory();
RunningShoe *nike_running_shoe = nike_factory->CreateRunningShoe();
RunningShoe *asics_running_shoe = asics_factory->CreateRunningShoe();
nike_running_shoe->run();
asics_running_shoe->run();
//clear
delete nike_factory;
delete asics_factory;
delete nike_running_shoe;
delete asics_running_shoe;
system("Pause");
return 0;
}
Factory:
//factory.h
#ifndef HELENDP_SOURCE_FACTORY_H_
#define HELENDP_SOURCE_FACTORY_H_
#include "running_shoe.h"
class Factory{
public:
Factory();
virtual ~Factory();
virtual RunningShoe *CreateRunningShoe() = 0;
};
#endif
//factory.cc
#include "factory.h"
Factory::Factory(){
}
Factory::~Factory(){
}
AsicsFactory:
//asics_factory.h
#ifndef HELENDP_SOURCE_ASICS_FACTORY_H_
#define HELENDP_SOURCE_ASICS_FACTORY_H_
#include "factory.h"
class AsicsFactory : public Factory{
public:
AsicsFactory();
~AsicsFactory();
RunningShoe *CreateRunningShoe();
};
#endif
//asics_factory.cc
#include "asics_factory.h"
#include "asics_running_shoe.h"
AsicsFactory::AsicsFactory(){
}
AsicsFactory::~AsicsFactory(){
}
RunningShoe *AsicsFactory::CreateRunningShoe(){
return new AsicsRunningShoe();
}
NikeFactory:
//nike_factory.h
#ifndef HELENDP_SOURCE_NIKE_FACTORY_H_
#define HELENDP_SOURCE_NIKE_FACTORY_H_
#include "factory.h"
class NikeFactory : public Factory{
public:
NikeFactory();
~NikeFactory();
RunningShoe *CreateRunningShoe();
};
#endif
//nike_factory.cc
#include "nike_factory.h"
#include "nike_running_shoe.h"
NikeFactory::NikeFactory(){
}
NikeFactory::~NikeFactory(){
}
RunningShoe* NikeFactory::CreateRunningShoe(){
return new NikeRunningShoe();
}
RunningShoe:
//running_shoe.h
#ifndef HELENDP_SOURCE_RUNNING_SHOE_H_
#define HELENDP_SOURCE_RUNNING_SHOE_H_
class RunningShoe
{
public:
RunningShoe();
virtual ~RunningShoe();
virtual void run() = 0;
};
#endif
//running_shoe.cc
#include "running_shoe.h"
RunningShoe::RunningShoe(){
}
RunningShoe::~RunningShoe(){
}
AsicsRunningShoe:
//asics_running_shoe.h
#ifndef HELENDP_SOURCE_ASICS_RUNNING_SHOE_H_
#define HELENDP_SOURCE_ASICS_RUNNING_SHOE_H_
#include "running_shoe.h"
class AsicsRunningShoe : public RunningShoe
{
public:
AsicsRunningShoe();
~AsicsRunningShoe();
void run();
};
#endif
//asics_running_shoe.cc
#include "asics_running_shoe.h"
#include <iostream>
using namespace std;
AsicsRunningShoe::AsicsRunningShoe(){
}
AsicsRunningShoe::~AsicsRunningShoe(){
}
void AsicsRunningShoe::run(){
cout << "Asics Run!" << endl;
}
NikeRunningShoe:
//nike_running_shoe.h
#ifndef HELENDP_SOURCE_NIKE_RUNNING_SHOE_H_
#define HELENDP_SOURCE_NIKE_RUNNING_SHOE_H_
#include "running_shoe.h"
class NikeRunningShoe : public RunningShoe{
public:
NikeRunningShoe();
~NikeRunningShoe();
void run();
};
#endif
//nike_running_shoe.cc
#include "nike_running_shoe.h"
#include <iostream>
using namespace std;
NikeRunningShoe::NikeRunningShoe(){
}
NikeRunningShoe::~NikeRunningShoe(){
}
void NikeRunningShoe::run(){
cout << "Nike Run!" << endl;
}
代码和UML图(EA)工程文件,最后会整理打包上传.
UML类图
结构
- Product(Running Shoe):抽象产品.
- ConcreteProduct(AsicsRunning Shoe,NikeRunning Shoe):具体产品.
- Creator(Factory):抽象工厂.
- ConcreteCreator(AsicsFactory,NikeFactory):具体工厂.
优点
- 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
- 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
- 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
缺点
- 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。