简单工厂&&工厂方法

定义

工厂模式属于创建型设计模式,大致可以分为三类,简单工厂模式、工厂方法模式、抽象工厂模式。
什么是简单工厂模式?
简单工厂模式不是23种标准设计模式之一。它提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。

什么是工厂方法模式?
工厂方法是一种创建型设计模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

举个例子
有一家生产处理器核的厂家,能够生产两种型号的处理器核,厂家如何根据自身情况和客户的需求进行生产。

解决方案

情景1:当厂家刚起步,只有一个工厂,生产何种型号的处理器核,需要在内部判断。
此时,客户需要什么样的处理器核(A型号、B型号),必须要显示地告诉了生产工厂。

情景2:这家生产处理器核的产家赚了不少钱,于是决定再开设一个工厂专门用来生产B型号的单核,而原来的工厂专门用来生产A型号的单核。
这时,客户要做的是找好工厂,比如要A型号的核,就找A工厂生产;否则找B工厂生产,不再需要告诉工厂具体要什么型号的处理器核了。

类图

  • 简单工厂模式
    在这里插入图片描述
    Client: 需要处理器核的客户
    Factory:生产A/B型号处理器核的唯一工厂
    SingleCore: 处理器单核,A或B
    SingleCoreA: 处理器单核A
    SingleCoreB: 处理器单核B
    这样设计的主要缺点就是要增加新的核类型时,就需要修改工厂类。这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。
  • 工厂方法模式
    在这里插入图片描述
    Factory:
    FactoryA:生产A型号处理器核的工厂
    FactoryB:生产B型号处理器核的工厂
    工厂方法模式通过定义两个子类 FactoryA和FactoryB,分别负责生产A型号处理器核和B型号处理器核。
    当需要增加新的核类型时,更容易扩展对象的新版本,已有的代码都不会改变,只要新加入一个子类来提供新的工厂方法实现,然后在客户端使用这个新的子类即可。

方案实现

  • 简单工厂模式
enum CTYPE {
COREA, 
COREB,
};   
class SingleCore  
{  
public:  
    virtual void Show() = 0;
};  
//单核A  
class SingleCoreA: public SingleCore  
{  
public:  
    void Show() { cout<<"SingleCore A"<<endl; }  
};  
//单核B  
class SingleCoreB: public SingleCore  
{  
public:  
    void Show() { cout<<"SingleCore B"<<endl; }  
};  
//唯一的工厂,可以生产两种型号的处理器核,在内部判断  
class Factory  
{  
public:   
    SingleCore* CreateSingleCore(enum CTYPE ctype)  
    {  
        if(ctype == COREA) //工厂内部判断  
            return new SingleCoreA(); //生产核A  
        else if(ctype == COREB)  
            return new SingleCoreB(); //生产核B  
        else  
            return NULL;  
    }  
};
  • 工厂方法模式
class SingleCore  
{  
public:  
    virtual void Show() = 0;
};  
//单核A  
class SingleCoreA: public SingleCore  
{  
public:  
    void Show() { cout<<"SingleCore A"<<endl; }  
};  
//单核B  
class SingleCoreB: public SingleCore  
{  
public:  
    void Show() { cout<<"SingleCore B"<<endl; }  
};  
class Factory  
{  
public:  
    virtual SingleCore* CreateSingleCore() = 0;
};  
//生产A核的工厂  
class FactoryA: public Factory  
{  
public:  
    SingleCoreA* CreateSingleCore() { return new SingleCoreA; }  
};  
//生产B核的工厂  
class FactoryB: public Factory  
{  
public:  
    SingleCoreB* CreateSingleCore() { return new SingleCoreB; }  
};

适用场景

  • 简单工厂模式
  1. 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无须关心具体的实现。
  2. 如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多的、不相关的对象,可以把对外创建对象的职责集中到个简单工厂来,从而实现集中管理和控制。
  • 工厂方法模式
  1. 如果一个类需要创建某个接口的对象,但是又不知道具体的实现,这种情况可以选用工厂方法模式,把创建对象的工作延退到子类中去实现。
  2. 如果一个类本身就希望由它的子类来创建所需的对象的时候,应该使用工厂方法模式。

对比总结

  • 简单工厂模式
    优点:
  1. 帮助封装:简单工厂虽然很简单,但是非常友好地帮助我们实现了组件的封装,然后让组件外部能真正面向接口编程。
  2. 解耦:通过简单工厂,实现了客户端和具体实现类的解耦。如同上面的例子,客户端根本就不知道具体是由谁来实现,也不知道具体是如何实现的,客户端只是通过工厂获取它需要的接口对象。
    缺点:
  3. 可能增加客户端的复杂度:如果通过客户端的参数来选择具体的实现类,那么就必须让客户端能理解各个参数所代表的具体功能和含义,这样会增加客户端使用的难度,也部分暴露了内部实现,这种情况可以选用可配置的方式来实现。
  4. 不方便扩展子工厂:私有化简单工厂的构造方法,使用静态方法来创建接口,也就不能通过写简单工厂类的子类来改变创建接口的方法的行为了。不过,通常情况下是不需要为简单工厂创建子类的。
  • 工厂方法模式
    优点:
  1. 可以在不知具体实现的情况下编程:工厂方法模式可以让你在实现功能的时候,如果需要某个产品对象,只需要使用产品的接口即可,而无需关心具体的实现。选择具体实现的任务延退到子类去完成。
  2. 更容易扩展对象的新版本:已有的代码都不会改变,只要新加入一个子类来提供新的工厂方法实现,然后在客户端使用这个新的子类即可。
  3. 连接平行的类层次:工厂方法除了创造产品对象外,在连接平行的类层次上也大显身手。比如有一个硬盘的接口, 具体实现有台式机希捷, 笔记本IBM。所以还会各自有着自己的读写硬盘方法。这种情况下使用工厂方法是比较合适的
    缺点:
  4. 具体产品对象和工厂方法的耦合性:在工厂方法模式中,工厂方法是需要创建产品对象的,也就是需要选择具体的产品对象,并创建它们的实例,因此具体产品对象和工厂方法是耦合的。
  • 54
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值