1 核心思想
工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
简单工厂模式的优缺点:
- 优点:简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。比如在使用简单工厂模式实现计算器时,客户端不需要关心该使用哪个类的实例,只需要把‘+’给工厂,工厂自动就给出了相应的实例,客户端只需要去做运算就可以了,不同的实例会实现不同的运算;
- 缺点:添加新的计算操作时,除了要添加新的操作实现类,还需要对工厂类的switch case进行扩充,违背了开放-封闭原则(对扩展开放,对修改关闭)。
工厂方法模式:
根据倒转依赖原则,把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,于是在增加新的操作时,就不需要修改原来的工厂类了,指需要增加此功能的运算类和相应的工厂类就可以了,也就符合了开闭原则。
Creator是一个类,它实现了所有操作产品的方法,同时提供了一个抽象的创建产品的函数FactoryMethod;ConcreteCreator是具体的工厂类,必须实现FactoryMethod方法创建出对应的产品,只有ConcreteCreator知道如何去创建出对应的Product。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现Product类,判断选择的问题还是存在的,也就是说,工厂方法模式把简单工厂的内部判断逻辑移到了客户端代码来进行。在增加新的功能时,本来是要修改工厂类的,现在是修改客户端。
2 工厂方法模式实现计算器
3 工厂方法模式实现雷锋工厂
//IFactory.h
#include "Leifeng.h"
class IFactory
{
public:
IFactory() {
}
virtual ~IFactory() {
}
virtual Leifeng* CreateLeifeng() =0;
protected:
Leifeng* m_Leifeng;
};
//UnderGraduateFactory.h
#include "IFactory.h"
#include "UnderGraduate.h"
class UnderGraduateFactory : public IFactory
{
public:
UnderGraduateFactory();
virtual ~UnderGraduateFactory();
virtual Leifeng* CreateLeifeng();
};
//VolunteerFactory.h
#include "IFactory.h"
#include "Volunteer.h"
class VolunteerFactory : public IFactory
{
public:
VolunteerFactory();
virtual ~VolunteerFactory();
virtual Leifeng* CreateLeifeng();
};
//Leifeng.h
class Leifeng
{
public:
Leifeng() {
}
virtual ~Leifeng() {
}
virtual void BuyRice() =0;
virtual void Sweep() =0;
virtual void Wash() =0;
};
//UnderGraduate.h
#include "Leifeng.h"
#include<iostream>
class UnderGraduate : public Leifeng
{
public:
UnderGraduate();
virtual ~UnderGraduate();
virtual void BuyRice();
virtual void Sweep();
virtual void Wash();
};
//Volunteer.h
#include "Leifeng.h"
#include <iostream>
class Volunteer : public Leifeng
{
public:
Volunteer();
virtual ~Volunteer();
virtual void BuyRice();
virtual void Sweep();
virtual void Wash();
};
//UnderGraduateFactory.cpp
#include "UnderGraduateFactory.h"
UnderGraduateFactory::UnderGraduateFactory(){
}
UnderGraduateFactory::~UnderGraduateFactory(){
}
Leifeng* UnderGraduateFactory::CreateLeifeng(){
m_Leifeng = new UnderGraduate;
return m_Leifeng;
}
//VolunteerFactory.cpp
#include "VolunteerFactory.h"
VolunteerFactory::VolunteerFactory(){
}
VolunteerFactory::~VolunteerFactory(){
}
Leifeng* VolunteerFactory::CreateLeifeng(){
m_Leifeng = new Volunteer;
return m_Leifeng;
}
//UnderGraduate.cpp
#include "UnderGraduate.h"
UnderGraduate::UnderGraduate(){
}
UnderGraduate::~UnderGraduate(){
}
void UnderGraduate::BuyRice(){
std::cout << "大学生买米!" << std::endl;
}
void UnderGraduate::Sweep(){
std::cout << "大学生扫地!" << std::endl;
}
void UnderGraduate::Wash(){
std::cout << "大学生洗衣!" << std::endl;
}
//Volunteer.cpp
#include "Volunteer.h"
Volunteer::Volunteer(){
}
Volunteer::~Volunteer(){
}
void Volunteer::BuyRice(){
std::cout << "志愿者买米!" << std::endl;
}
void Volunteer::Sweep(){
std::cout << "志愿者扫地!" << std::endl;
}
void Volunteer::Wash(){
std::cout << "志愿者洗衣!" << std::endl;
}
//main.cpp
#include "IFactory.h"
#include "Leifeng.h"
#include "UnderGraduateFactory.h"
#include "VolunteerFactory.h"
int main()
{
IFactory* factory = new UnderGraduateFactory; //只需改为VolunteerFactory就变成志愿者服务
Leifeng* leifeng = factory->CreateLeifeng();
leifeng->BuyRice();
leifeng->Sweep();
leifeng->Wash();
return 0;
}
4 工厂方法模式总结
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态,工厂方法模式保持了简单工厂模式的优点,而且克服了其违反开闭原则的缺点。
工厂方法模式的缺点是每增加一个产品,就需要增加一个产品工厂的类,增加了额外的代码量。
使用抽象工厂中的反射技术,可以避免工厂方法模式中的分支判断问题。
5 推荐学习
https://blog.csdn.net/lovelion/article/details/9306457
https://blog.csdn.net/lovelion/article/details/9306745
https://blog.csdn.net/lovelion/article/details/9307137
https://blog.csdn.net/lovelion/article/details/9307561