设计模式(二)――工厂方法模式

时间:2022-10-02 15:12:04

设计模式(二)――工厂方法模式

一、工厂方法模式简介

1、工厂方法模式简介

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

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

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

    工厂方法模式特点:

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

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

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

    UML类图如下:

设计模式(二)――工厂方法模式

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类图:

设计模式(二)――工厂方法模式

代码实例:

#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;

}

2CPU工厂实例

设计模式(二)――工厂方法模式

    生产处理器核的产家赚了不少钱,于是决定再开设一个工厂专门用来生产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++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。


本文出自 “生命不息,奋斗不止” 博客,谢绝转载!