简单工厂、工厂、抽象工厂模式

简单工厂、工厂、抽象工厂模式

 

生活中当你想要买车子的时候,会去汽车销售店。而当你进去的时候,就会有销售人员给你介绍各种各样的车子,它的类型、品牌、价格等等。你想买那种的时候,只需要说一声,相关人员就会帮你办理相应手续,你就可以付款提车走人。

我这里也有个汽车销售店,只卖宝马、奔驰和大众。

  1. 起步阶段--简单工厂

刚开业的时候,没钱、没客户,因此我只请了一个销售员进行销售产品,因为节省资源,实现利益最大化。

而这个时候的交易流程:

销售员介绍->客户选择车子->交易结款。交易流程中,用户只需要知道我要买什么车子,而不会太过于车子是怎么来的,毕竟我的各种证件齐全。

 

而这种模式就叫做“简单工厂模式”,所有的产品都由一个销售员(工厂)负责出售或者被制造等等,而用户只需要向销售员提供足够的信息,“我要买大众”等等,就可以从销售员得到需要的车子(产品)。

而“简单工厂模式”是最简单的工厂模式,也是最基本的工厂模式,后面的工厂模式和抽象工厂模式,都是慢慢拓展来的。

对上述的交易流程通过uml进行描述 :

 

其中的Enum(ECarType)就是类似于销售员的讲解和一些产品说明书,你在其中选择,然后告诉给销售员(CCarFactory)所需要的产品,而销售员(CCarFactory)通过内部的一系列手续或者操作来得到结果,将你需要的产品(CCar)给你。而销售员(CCarFactory)内部就存在“业务逻辑”,就是他需要分析你的需求,然后使用不同车子对应的手续办理方法,而“简单工厂模式”就是将“业务逻辑”和“产品”从用户进行分离,解耦合。

可是随着时间的流逝,我的销售点扩张了,变大了,虽然汽车种类没有变化,但是各种型号变多了。这个时候销售不干了,她说:“这么多汽车型号和逐渐增多的客户流,我一个人哪里照顾的来。”

这就是“简单工厂”的不足之处:

  1. 型号、种类(产品)进行增加的时候,销售员(CCarFactory)必须修改内部逻辑,这就违反了“开发-封闭”原则,这可是最基本的原则
  2. 客户量的增加,反映出资源的浪费。如果销售员(CCarFactory)他真的记住了所有产品特点,但是他给用户讲的可能只是一种品牌的车子相关知识,其他的不浪费了吗?

 

因此产生了“工厂模式”,对“销售员(CCarFactory)”进行加工处理,让其遵循“开发-封闭”原则,也要保证对资源的充分利用。

(2)拓张阶段-工厂模式

我对销售员(CCarFactory)进行了拓张,一开始的销售员升职了,好吧,忘记介绍她叫“小A”,她现在的工作不是每天讲的口干舌燥的,然后还需要看客户脸色了,她成了经理,干着轻松的活,拿着更多的工资和分红。

这次我招了三个人,小B(负责奔驰相关的产品)、小C(负责大众相关的产品)、小D(负责宝马相关的产品)。而这个时候就不仅仅是人讲了,我还有一个大屏幕啦,然后一直循环展示一些产品,并且还附带有相关产品的销售员相片。

而这个时候的交易流程:

用户自己看大屏或者产品书->根据附带的相片找到想要的销售人员->在销售员(CCarFactory)的介绍下选择产品->交易结款。这个时候的流程图:

 

虽然流程图一样,但是根据具体讲解就知道,有些功能被用户承但了:

用户除了“说出选择”之外,还承但了“做出选择销售员(Factory)”的责任。因为我的客户多,但是我的销售员(Factory)少啊,所以只能是客户去选择销售员(Factory)了。而不是销售员(Factory)主动过来寻找客户,很傲娇的,而且现在大多数人也不太喜欢太过于热情的服务。那么我没就可以从销售员(Factory)中将“业务逻辑”这部分消除掉了,因为这部分的分析被用户通过“做出选择销售员(Factory)”已经完成了。

而这种销售流程就行“工厂模式”,用户自己进行销售员(Factory)选择,然后得到对应的销售员(Factory)的对象,然后进行车子(产品)的购买,而销售员(Factory)只需要知道自己所负责的一种品牌的车子的手续怎么办理就行了,然后办理手续,把车子交给用户。用uml显示:

 

其中ICarFactory接口就相当于你刚进商店的时候,一个虚拟的销售员(Factory)对象,然后你查看大屏或者产品说明,来选择(创建)对应的销售员(Factory)对象,而实际的这个销售员(Factory)可能是小B(CBenChiCarFactory)、小C(CDaZhongCarFactory)或小D(CBMWCarFactory),

然后他们给你将对应的产品和办理对应的手续,然后交易就完成了。而这个时候拓展就不需要改变“业务逻辑”了,只需要添加对应的接口和对应的销售员(Factory)对象就行了,而且每次只是让对应品牌的销售员负责对应的产品,也减少了资源浪费。

而随着卖出去的车子越来越多,相应的车损耗率也上升了,修改车灯、换个车玻璃等等的,我又嗅到了商机......

(3)形成产品家族--抽象工厂模式

我拓展了维修服务,我针对三种品牌的车子,拓展了对应车子的车玻璃商品,又是一波收入。但是我不想再花钱去请销售员了,太麻烦,又太费钱。我让小B负责奔驰相关的车玻璃产品、小C负责大众的、小D负责宝马的,最大多加点工资,嘿嘿。

而这个时候的交易流发生了简单的变化:

用户自己看大屏或者产品书->根据附带的相片找到想要的销售人员->在销售员(CCarFactory)的介绍下选择产品(选择买车子、还是买车玻璃并维修)->交易结款。只是用户找到对应的销售员后,所可以选择的服务增加了一项服务,流程图却没有变化。也就意味着代码修改不大,只是用户阶段多做一些选择就行了。因此,可以推出“抽象工厂模式”其本质就是“工厂模式”,“工厂模式”是对一种产品的模式,比如车子、房子等等,而“抽象工厂模式”则是再一种上增加了垂直的一类,比如车子和车子的车玻璃等等,大众说法就是“产品族”。

其UML表示为:

 

而且其拓展步骤不难,大体分为4步:

  1. 添加一个车子相关的产品,如车玻璃CMirror。
  2. 对CMirror进行派生,产生和车子种类相对于的车玻璃类。
  3. 再ICarFactory中添加创建CMirror的调用接口
  4. 在生产车子的工厂中(即对应销售员),添加一个新的服务“车玻璃”

就这样我的销售店越来越大,汽车类型越来越多,相应的维修产品也越来越多,然后我的钱也越来越多,我很开心,然后开心死了,这个文章也就结束了。

  1. 后记+代码

抽象工厂还有一些改编,我就不一一阐述了,如:

简单工厂+抽象工厂

反射+抽象工厂

反射+文件+抽象工厂

.......

// FactortyTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;
#define interface struct

enum ECarType
{
    e_carType_DaZhong = 0 ,
    e_carType_BenChi,
    e_carType_BMW,
};

//车子种类相关产品,包括
//基类CCar
//大众CDaZhongCar
//奔驰CBenChiCar
//宝马CBMWCar
class CCar
{ 
public:   
    virtual void createCar() {}

public:
    string m_carName;
};
class CDaZhongCar :public CCar
{
public:
    CDaZhongCar() { m_carName = "DaZhong Car"; }
    ~CDaZhongCar(){}
    void createCar() { cout << "Create a DaZhong Car!" << endl; }
};
class CBenChiCar :public CCar
{
public:
    CBenChiCar() { m_carName = "BenChi Car"; }
    ~CBenChiCar() {}
    void createCar() { cout << "Create a BenChi Car!" << endl; }
};
class CBMWCar :public CCar
{
public:
    CBMWCar() { m_carName = "BMW Car"; }
    ~CBMWCar() {}
    void createCar() { cout << "Create a BMW Car!" << endl; }
};

//简单工厂模式下的工厂
//工厂负责返回实例和业务逻辑
//业务逻辑:根据输入进行分析,之后产生对应车子的实例对象
class CCarFactory
{
public:
    CCar* createCar(ECarType carType);
};
CCar* CCarFactory::createCar(ECarType carType)
{
    CCar* car = NULL;
    switch (carType)
    {
        case e_carType_DaZhong:
        {
            car = new CDaZhongCar();
        }break;
        case e_carType_BenChi:
        {
            car = new CBenChiCar();
        }break;
        case e_carType_BMW:
        {
            car = new CBMWCar();
        }break;
        default: {}
    }
    return car;
}

//抽象工厂模式时的产品族
//此处为车玻璃
//包括基类、宝马对应的车玻璃类、大众对应的车玻璃类、奔驰对应的车玻璃类
class CMirror
{
public:
    virtual void createMirror() {}

public:
    string m_mirrorName;
};

class CDaZhongMirror :public CMirror
{
public:
    CDaZhongMirror() { m_mirrorName = "DaZhong Mirror"; }
    ~CDaZhongMirror() {}
    void createMirror() { cout << "Create a DaZhong Mirror!" << endl; }
};
class CBenChiMirror :public CMirror
{
public:
    CBenChiMirror() { m_mirrorName = "BenChi Mirror"; }
    ~CBenChiMirror() {}
    void createMirror() { cout << "Create a BenChi Mirror!" << endl; }
};
class CBMWMirror :public CMirror
{
public:
    CBMWMirror() { m_mirrorName = "BMW Mirror"; }
    ~CBMWMirror() {}
    void createMirror() { cout << "Create a BMW Mirror!" << endl; }
};

//简单工厂和抽象工厂下的工厂类
//包括提供获取CCar和CMirror接口的接口类
//包括专门生产大众相关、奔驰相关、宝马相关的对应工厂类
interface ICarFactory
{
    //简单工厂只生产车子
    virtual CCar* createCar() = 0;
    //而抽象工厂还需要生产每种品牌的车子所对应的车玻璃等等(当然可能还有轮胎等等)
    virtual CMirror* createMirror() = 0;
};

class CDaZhongCarFactory :public ICarFactory
{
public:
    CCar* createCar() { return new CDaZhongCar(); }
    CMirror* createMirror() { return new CDaZhongMirror(); }
};
class CBenChiCarFactory :public ICarFactory
{
public:
    CCar* createCar() { return new CBenChiCar(); }
    CMirror* createMirror() { return new CBenChiMirror(); }
};
class CBMWCarFactory :public ICarFactory
{
public:
    CCar* createCar() { return new CBMWCar(); }
    CMirror* createMirror() { return new CBMWMirror(); }
};



int main()
{
    //简单工厂模式
    //通过输入用户的选择,再工厂中进行逻辑,分析所需要产生的实例
    CCarFactory cFactory;
    CCar* car = cFactory.createCar(e_carType_BenChi);
    if (car)
    {
        car->createCar();
    }
    //工厂和抽象工厂
    //通过用自行创造对应的品牌工厂类
    //再用对应的工厂类来产生所需要的实例
    //工厂--只生产汽车
    //抽象工厂--既生产汽车,也生产相关产品
    ICarFactory *iCarFac = new CBMWCarFactory();
    CCar* iCar = iCarFac->createCar();
    CMirror* iMirror = iCarFac->createMirror();
    if (iCar && iMirror)
    {
        iCar->createCar();
        iMirror->createMirror();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值