工厂模式相对比较简单,不专门介绍。只说下工厂模式的目的,工厂模式主要是为了解决:调用者不需要关注每个具体实现,通过一个工厂加一个功能抽象(一个抽象类),就可以直接使用每个具体实现的功能。
//抽象功能定义,具体每个功能需要继承该定义,并实现Do完成自定义的功能
class AbsIns {
public:
virtual int Do() = 0;
};
class Factory
{
private:
/* data */
public:
Factory(/);
~Factory();
public:
//通过调用不同方法,获取自己想要的实现
//也可以定一个方法,通过传参的方式获取想要的对象实现
AbsIns* GetA();
AbsIns* GetB();
};
对于工厂模式,可以认为它把每个行为抽象了一级。同一行为,但表现不同,通过一个抽象类来描述,使用工厂获取具体的行为实现。
这里有一个明显的问题,当行为种类较多的时候,这就会让工厂比较庞大,不好维护。比如说对于支付这么一个对象,有在线和离线俩种行为。很明显每一种行为里又有很多表现,比如在线支付可以通过银行卡,也可以通过支付宝。如果每个具体实现都通过工厂,那工厂的修改和维护就会非常频繁。抽象工厂就是为了解决这种场景。
抽象工厂对于创建对象的行为又抽象了一级。抽象工厂定义好创建对象的接口,具体创建什么对象,由具体工厂来实现。
还说针对支付这个场景来说。支付存在俩种行为,一种是支付本身,需要抽象出一个对象;一种是支付异常之后的错误处理,也需要抽象出一个对象。支付动作与支付异常的处理,一般是相辅相成,因此针对这俩个对象的创建,往上再抽象出一级。
因此整个模块分为俩大类
- 抽象工厂定义和具体工厂定义;
- 业务定义,包括支付行为定义、错误处理定义;
工厂的定义:
#ifndef ABSFACTORY_H
#define ABSFACTORY_H
#include "pay_ins.h"
#include "err_handler_ins.h"
//定义抽象工厂的创建方法
class AbsFactory
{
public:
virtual PayIns* CreatePayIns() = 0;
virtual ErrHandlerIns* CreateErrHandler() = 0;
};
//俩个具体的工厂实现,不同的工厂创建不同的对象
class OnlineFactory : public AbsFactory {
public:
virtual PayIns* CreatePayIns() override;
virtual ErrHandlerIns* CreateErrHandler() override;
};
class OfflineFactory : public AbsFactory {
public:
virtual PayIns* CreatePayIns() override;
virtual ErrHandlerIns* CreateErrHandler() override;
};
#endif
业务定义-支付行为:
#ifndef PAYINS_H
#define PAYINS_H
class PayIns
{
public:
virtual int DoPay() = 0;
};
class OnlinePay : public PayIns {
public:
int DoPay();
};
class OfflinePay : public PayIns {
public:
int DoPay();
};
#endif
业务定义-错误处理行为:
#ifndef ERRHANDLERINS_H
#define ERRHANDLERINS_H
class ErrHandlerIns
{
public:
virtual int HandlerErr() = 0;
};
class OnlineErrHandler : public ErrHandlerIns {
public:
int HandlerErr();
};
class OfflineErrHandler : public ErrHandlerIns {
public:
int HandlerErr();
};
#endif
调用示例:
#include "abs_factory.h"
#include "err_handler_ins.h"
#include "pay_ins.h"
using namespace std;
int main() {
AbsFactory *factory = new OfflineFactory;
PayIns* pay_ins = factory -> CreatePayIns();
ErrHandlerIns* err_handler = factory -> CreateErrHandler();
pay_ins -> DoPay();
err_handler -> HandlerErr();
return 0;
}