工厂方法

一、工厂方法模式简介

1、工厂方法模式简介

    工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法将一个类的实例化延迟到其子类。

对每一个子类产品都分别对应一个工厂子类,用来创建相应的产品,若增加了新的产品,只需相应增加工厂子类即可。

    工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得工厂方法可以被子类继承。

    工厂方法模式特点:

    (1)工厂方法模式是对简单工厂模式的稍微的改进。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。

    (2)与简单工厂模式相比,制造产品的工厂类不再只有一个,而是每种具体产品类都对应一个生产它的具体工厂类。而具体工厂类的共同特征被提取出来形成一个抽象产品类,具体产品类都继承自抽象产品类。

    (3)当需要增加一种产品的时候,需要做的是:增加一种继承自抽象产品的具体产品类,增加一种继承在抽象工厂的具体工厂类,更改客户端的逻辑判断。

    UML类图如下:

wKioL1nKYyyz8m_UAACkqNc0IQY250.jpg

 

2、工厂方法模式角色

    工厂接口:抽象工厂是工厂方法模式的核心,与调用者直接交互用来提供产品。工厂接口可以由抽象类来代替。

    工厂实现:工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。

    产品接口:产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。

    产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。

3、工厂方法模式优缺点

优点:

    A、良好的封装性

    B、良好的扩展性

    C、屏蔽了产品类,用户不需要知道产品类的实例化过程。

    D、实现解耦,符合迪米特法则

    E、不用修改已有代码,开放封闭原则:对扩展开放,对更改封闭

缺点:

每增加一种产品,就需要增加一个对象的工厂。

4、工厂方法模式适用场景

    A、作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。

    B、工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。

    C、工厂模式是依靠抽象架构的,把实例化产品的任务交由实现类完成,扩展性比较好。当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。

    D、当客户程序不需要知道要使用对象的创建过程。 
        E、客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。
       在工厂方法模式中,要么将判断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色进行逻辑判断,而且产品对象创建条件的改变必然会引起工厂角色的修改。

二、工厂方法模式实现

IFactory抽象工厂类:
#ifndef IFACTORY_H
#define IFACTORY_H
#include "IProduct.h"
 
class IFactory
{
public:
    virtual IProduct* createProduct() = 0;
};
 
#endif // IFACTORY_H
ConcreteFactoryA具体工厂A:
#include "IFactory.h"
#include "ConcreteProductA.h"
 
class ConcreteFactoryA : public IFactory
{
public:
    ConcreteFactoryA(){}
    IProduct* createProduct()
    {
        IProduct* product = new ConcreteProductA();
        return product;
    }
};
 
#endif // CONCRETEFACTORYA_H
ConcreteFactoryB具体工厂B:
#ifndef CONCRETEFACTORYB_H
#define CONCRETEFACTORYB_H
#include "IFactory.h"
#include "ConcreteProductB.h"
 
class ConcreteFactoryB : public IFactory
{
public:
    ConcreteFactoryB(){}
    IProduct* createProduct()
    {
        IProduct* product = new ConcreteProductB();
        return product;
    }
};
 
#endif // CONCRETEFACTORYB_H
IProduct抽象产品类:
#ifndef IPRODUCT_H
#define IPRODUCT_H
 
class IProduct
{
public:
    virtual void show() = 0;
};
 
#endif // IPRODUCT_H
ConcreteProductA具体产品A:
#ifndef CONCRETEPRODUCTA_H
#define CONCRETEPRODUCTA_H
#include "IProduct.h"
 
#include <iostream>
using std::cout;
using std::endl;
 
class ConcreteProductA : public IProduct
{
public:
    ConcreteProductA(){}
    void show()
    {
        cout << "This is a ConcreteProductA" << endl;
    }
};
 
#endif // CONCRETEPRODUCTA_H
ConcreteProductB具体产品类B:
#ifndef CONCRETEPRODUCTB_H
#define CONCRETEPRODUCTB_H
#include "IProduct.h"
#include <iostream>
using std::cout;
using std::endl;
 
class ConcreteProductB : public IProduct
{
public:
    ConcreteProductB(){}
    void show()
    {
        cout << "This is a ConcreteProductB" << endl;
    }
};
 
#endif // CONCRETEPRODUCTB_H
客户端调用程序:
#include <iostream>
#include "IFactory.h"
#include "ConcreteFactoryA.h"
#include "ConcreteFactoryB.h"
 
using namespace std;
 
int main()
{
    IFactory* factoryA = new ConcreteFactoryA();
    IProduct* productA = factoryA->createProduct();
    productA->show();
 
    IFactory* factoryB = new ConcreteFactoryB();
    IProduct* productB = factoryB->createProduct();
    productB->show();
 
    return 0;
}

 

 

三、工厂方法模式实例

1、计算器实例

UML类图:

wKiom1nKY6TSutHWAACjQh9f9rA606.jpg

代码实例:

#include <iostream>
#include <cstdlib>
using namespace std;
//抽象产品类
class Operation
{
protected:
    double numberA;
    double numberB;
public:
    double getA()
    {
        return numberA;
    }
    double getB()
    {
        return numberB;
    }
    void setA(double number)
    {
        numberA = number;
    }
    void setB(double number)
    {
        numberB = number;
    }
    virtual double getResult()
    {
        double ret = 0;
        return ret;
    }
};
//具体产品类
class OperationAdd:public Operation
{
public:
    double getResult()
    {
        double ret = 0;
        ret = numberA + numberB;
        return ret;
    }
};
class OperationSub:public Operation
{
public:
    double getResult()
    {
        double ret = 0;
        ret = numberA - numberB;
        return ret;
    }
};
class OperationMul:public Operation
{
public:
    double getResult()
    {
        double ret = 0;
        ret = numberA * numberB;
        return ret;
    }
};
class OperationDiv:public Operation
{
public:
    double getResult()
    {
        double ret = 0;
        if(numberB != 0)
            ret = numberA / numberB;
        return ret;
    }
};
//抽象工厂类
class AbstructFactory
{
public:
    virtual Operation *CreateOperation()
    {
        return new Operation;
    }
};
//具体工厂类
class AddFactory:public AbstructFactory
{
public:
    Operation *CreateOperation()
    {
        Operation *oper = new OperationAdd;
        return oper;
    }
};
class SubFactory:public AbstructFactory
{
public:
    Operation *CreateOperation()
    {
        Operation *oper = new OperationSub;
        return oper;
    }
};
class MulFactory:public AbstructFactory
{
public:
    Operation *CreateOperation()
    {
        Operation *oper = new OperationMul;
        return oper;
    }
};
class DivFactory:public AbstructFactory
{
public:
    Operation *CreateOperation()
    {
        Operation *oper = new OperationDiv;
        return oper;
    }
};
//客户端使用
int main(int argc, char *argv[])
{
    AbstructFactory *af = NULL;
    af = new AddFactory();
    Operation *oper = NULL;
    oper = af->CreateOperation();
    oper->setA(2);
    oper->setB(10);
    cout << oper->getResult() << endl;
    if(af != NULL)
    {
        delete af;
        af = NULL;
    }
    if(oper != NULL)
    {
        delete oper;
        oper = NULL;
    }
    return 0;
}

 

2、CPU工厂实例

wKioL1nKY7PynxcFAAD_bydbi10646.jpg

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

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:    
    SingleCore* CreateSingleCore() { return new SingleCoreA; }    
};    
//生产B核的工厂    
class FactoryB: public Factory    
{    
public:    
    SingleCore* CreateSingleCore() { return new SingleCoreB; }    
};

 

    工厂方法模式也有缺点,每增加一种产品,就需要增加一个对象的工厂。如果公司发展迅速,推出了很多新的处理器核,那么就要开设相应的新工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值