设计模式——简单工厂模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——简单工厂模式相关的知识,希望对你有一定的参考价值。

设计模式(一)——简单工厂模式

一、简单工厂模式简介

1、简单工厂模式简介

    简单工厂模式Simple Factory Pattern属于创建型模式,又静态工厂方法(Static Factory Method)模式是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。

    简单工厂模式UML图如下:

技术分享

    简单工厂模式解决的问题是如何去实例化一个合适的对象。

    简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。

     如果简单工厂模式所涉及到的具体产品之间没有共同的逻辑,那么可以使用接口来扮演抽象产品的角色;如果具体产品之间有共同的逻辑,就必须把共同的逻辑提取出来,放在一个抽象类中,然后让具体产品继承抽象类。

2、简单工厂模式角色

简单工厂模式包含如下角色:

    工厂角色(SampleFactory):是简单工厂模式的核心,负责创建所有的类的内部逻辑。工厂类必须能够被外界调用,创建所需要的产品对象。工厂类是用来制造产品的。因此,在Factory中有一个用于制造产品的Create函数或者Generate函数之类的函数。工厂函数能够根据标识符的不同生成不同的ConcreteProduct,当然ConcreteProduct都是继承自AbstractProduct

    抽象(AbstractProduct)产品角色:抽象产品是从其他具体产品抽象出来的。抽象产品类只有一个。简单工厂模式所创建的所有对象的父类,父类可以是接口也可以是抽象类,负责描述所有实例所共有的公共接口。

    具体产品(Concrete Product)角色:具体产品类继承自抽象产品类,可以有多个,是简单工厂所创建的具体实例对象,具体产品往往都拥有共同的父类。当需要增加新的产品的时候就增加一个继承自抽象产品类的具体产品类即可。

3、简单工厂模式优缺点

在实际的的使用中,抽象产品和具体产品之间往往是多层次的产品结构,如下图所示:

技术分享

优点:

    工厂类是简单工厂模式的关键,工厂类包含了必要的逻辑判断根据外界给定的信息决定究竟应该创建哪个具体类的对象通过使用工厂类外界可以从直接创建具体产品对象的尴尬局面摆脱出来仅仅需要负责消费对象就可以而不必管这些对象究竟如何创建及如何组织的明确了各自的职责和权利,有利于整个软件体系结构的优化。

在简单工厂模式中,客户端不再负责对象的创建,而是把创建对象的责任丢给了工厂类,客户端值负责对象的调用,从而明确了各个类的职责(单一职责)。

缺点:

    由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;工厂类所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类。

    当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求。创建实例时对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利这些缺点在工厂方法模式中得到了一定的克服。

    由于工厂类负责所有对象的创建,那么当子类不断增多的时候,就需要去修改工厂的代码,违反了开闭原则。

4、简单工厂模式使用场景

简单工厂模式使用场景:

    A工厂类负责创建的对象比较少

    B客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;

    由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

        JDBCSUN公司提供的一套数据库编程接口API,利用Java语言提供简单、一致的方式来访问各种关系型数据库。Java程序通过JDBC可以执行SQL语句,对获取的数据进行处理,并将变化了的数据存回数据库,因此,JDBCJava应用程序与各种关系数据进行对话的一种机制。用JDBC进行数据库访问时,要使用数据库厂商提供的驱动程序接口与数据库管理系统进行数据交互。

技术分享

二、简单工厂模式实现

SampleFactory工厂类:

#ifndef SAMPLEFACTORY_H

#define SAMPLEFACTORY_H

#include "AbstractProduct.h"

#include "ConcreteProductA.h"

#include "ConcreteProductB.h"

#include "ConcreteProductC.h"

 

class SampleFactory

{

public:

    SampleFactory(){}

    AbstractProduct* createProduct(char type)

    {

        AbstractProduct* product;

        switch(type)

        {

            case ‘A‘:

                product = new ConcreteProductA();

                break;

            case ‘B‘:

                product = new ConcreteProductB();

                break;

            case ‘C‘:

                product = new ConcreteProductC();

                break;

        }

        return product;

    }

};

 

#endif // SAMPLEFACTORY_H

AbstractProduct抽象产品类:

#ifndef ABSTRACTPRODUCT_H

#define ABSTRACTPRODUCT_H

#include <iostream>

using namespace std;

 

class AbstractProduct

{

public:

    AbstractProduct(){}

    virtual void show() = 0;

};

 

#endif // ABSTRACTPRODUCT_H

ConcreteProductA具体产品A类:

#ifndef CONCRETEPRODUCTA_H

#define CONCRETEPRODUCTA_H

#include "AbstractProduct.h"

 

class ConcreteProductA : public AbstractProduct

{

public:

    ConcreteProductA(){}

    void show()

    {

        cout << "This is a ProductA" << endl;

    }

};

 

#endif // CONCRETEPRODUCTA_H

ConcreteProductB具体产品类B

#ifndef CONCRETEPRODUCTB_H

#define CONCRETEPRODUCTB_H

#include "AbstractProduct.h"

 

class ConcreteProductB : public AbstractProduct

{

public:

    ConcreteProductB(){}

    void show()

    {

        cout << "This is a ProductB" << endl;

    }

 

};

 

#endif // CONCRETEPRODUCTB_H

ConcreteProductC具体产品类C

#ifndef CONCRETEPRODUCTC_H

#define CONCRETEPRODUCTC_H

#include "AbstractProduct.h"

 

class ConcreteProductC : public AbstractProduct

{

public:

    ConcreteProductC(){}

    void show()

    {

        cout << "This is a ProductC" << endl;

    }

};

 

#endif // CONCRETEPRODUCTC_H

客户调用程序:

#include <iostream>

#include "AbstractProduct.h"

#include "SampleFactory.h"

 

using namespace std;

 

int main()

{

    SampleFactory factory;//工厂对象

    AbstractProduct* a = factory.createProduct(‘A‘);

    a->show();

    AbstractProduct* b = factory.createProduct(‘B‘);

    b->show();

    AbstractProduct* c = factory.createProduct(‘C‘);

    c->show();

 

    delete a,b,c;

    return 0;

}


三、简单工厂模式实例

1、计算器实例

技术分享

代码实例:

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

{

public:

    Operation *CreateOperation(char type)

    {

        Operation *oper;

        switch(type)

        {

        case ‘+‘:

            oper = new OperationAdd;

            break;

        case ‘-‘:

            oper = new OperationSub;

            break;

        case ‘*‘:

            oper = new OperationMul;

            break;

        case ‘/‘:

            oper = new OperationDiv;

            break;

        }

        return oper;

    }

};

//客户端使用

int main(int argc, char *argv[])

{

    Operation *oper = NULL;

    OperationFactory factory;

    oper = factory.CreateOperation(‘*‘);

    oper->setA(1);

    oper->setB(3);

    cout<<oper->getResult()<<endl;

    if(oper != NULL)

    {

        delete oper;

        oper = NULL;

    }

    return 0;

}

2CPU工厂实例

    有一家生产处理器核的厂家,只有一个工厂,能够生产两种型号的处理器核。客户需要什么样的处理器核,一定要显示地告诉生产工厂。下面给出一种实现方案。

    简单工厂模式的UML图如下:

技术分享

//简单工厂模式

#include <iostream>

using namespace std;

//处理器类型

enum CTYPE{COREA, COREB};

class SingleCore

{

public:

    virtual void show() = 0;

};

//单核A

class SingleCoreA : public SingleCore

{

public:

    void show()

    {

        cout << "SingleCoreA" << endl;

    }

};

//单核B

class SingleCoreB : public SingleCore

{

public:

    void show()

    {

        cout << "SingleCoreB" << endl;

    }

};

//工厂类,创建单核A和单核B两种型号的处理器,在工厂类内部判断

class Factory

{

public:

    SingleCore * createSingleCore(enum CTYPE type)

    {

        SingleCore* ret = NULL;

        if(type == COREA)

        {

            ret = new SingleCoreA();

        }

        else if(type == COREB)

        {

            ret = new SingleCoreB();

        }

        return ret;

    }

};

 

//使用方式

int main()

{

    Factory factory;

    SingleCore* p = factory.createSingleCore(COREA);

    p->show();

    SingleCore* pp = factory.createSingleCore(COREB);

    pp->show();

    return 0;

}

3、简单工厂模式实例分析

计算器实例:

    如果要增加新的产品类,即新的运算类型时,需要修改工厂类,违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改

CPU工厂实例:

    如果要增加新的产品类,即不同的核类型时,就需要修改工厂类违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改

    工厂方法模式解决了简单工厂模式的缺点。




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

以上是关于设计模式——简单工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式从青铜到王者第五篇:创建型模式之简单工厂模式( Simple Factory Pattern )

iOS经常使用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

02 简单工厂模式

设计模式—— 简单工厂

设计模式一:简单工厂模式

设计模式----简单工厂模式