工厂模式(Factory Pattern)

工厂模式提供一种创建对象的最佳方法。

在创建对象时不会对客户端暴露创建逻辑,并且是用过使用一个共同的接口来指向新创建的对象。

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

解决:解决接口选择问题。

使用:明确的计划不同条件下创建不同实例。

实现:让其子类实现工厂接口,返回的也是一个抽象的产品。

代码:创建过程在其子类执行。

应用实例:1、需要一辆车,直接从工厂提货,而不用去管这两汽车的制作过程以及具体如何实现。

     2、需要一部手机,直接从工厂提货,不用管手机制作细节。

优点:1、一个调用者想创建一个对象,只要知道其名称就行。

           2、扩展性高,如果需要增加产品,只要扩张一个工厂类就行。

           3、屏蔽产品的实现细节,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

 

注意事项:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。

                  复杂对象适合使用工厂模式,而简单对象,特别是通过new就可完成创建的对象,无需使用工厂模式。

 

 

 

 C++实现:

 1、创建一个接口:

Shape.h

#pragma once
class Shape
{
public:
    virtual void draw() = 0;
};

 

 

2、创建实现接口的实体类:

Circle.h

#pragma once
#include<iostream>
#include "Shape.h"

class Circle :public Shape
{
public:
    void draw()
    {
        std::cout << "Circle::draw() method." << std::endl;
    }
};

Rectangle.h

#pragma once
#include<iostream>
#include "Shape.h"

class Rectangle :public Shape
{
public:
    void draw() 
    {
        std::cout << "Rectangle::draw() method." << std::endl;
    }
};

Square.h

#pragma once
#include<iostream>
#include "Shape.h"

class Square :public Shape
{
public:
    void draw()
    {
        std::cout << "Square::draw() method." << std::endl;
    }
};

 

 

3、创建一个工程,生成基于给定信息的实体类的对象:

ShapeFactory.h

#pragma once
#include <iostream>
#include <string>
#include "Shape.h"
#include "Rectangle.h"
#include "Circle.h"
#include "Square.h"

class ShapeFactory
{
public:
    Shape* getShape(std::string shapeType)
    {    
        if (shapeType == " ")
        {
            return NULL;
        }
        if (shapeType == "CIRCLE")
        {
            return new Circle();
        }
        else if (shapeType == "RECTANGLE")
        {
            return new Rectangle();
        }
        else if (shapeType == "SQUARE")
        {
            return new Square();
        }
        return NULL;
    }
};

 上述方法存在不足,因为new的对象无法delete,所以使用智能指针替代。版本如下:

#pragma once
#include <iostream>
#include <string>
#include <memory>
#include "Shape.h"
#include "Rectangle.h"
#include "Circle.h"
#include "Square.h"

class ShapeFactory
{
public:
    std::unique_ptr<Shape> getShape(std::string shapeType)
    {    
        if (shapeType == " ")
        {
            return nullptr;
        }
        if (shapeType == "CIRCLE")
        {
            return std::unique_ptr<Circle>(new Circle);
        }
        else if (shapeType == "RECTANGLE")
        {
            return std::unique_ptr<Rectangle>(new Rectangle);
        }
        else if (shapeType == "SQUARE")
        {
            return std::unique_ptr<Square>(new Square);
        }
        return NULL;
    }
    
    ~ShapeFactory()
    {
        std::cout << "调用析构函数!" << std::endl;
    }
};

 

 

4、使用该工厂,通过传递类型信息来获取实体类的对象:

FactoryPatternDemo.cpp

 

#include<iostream>
#include "ShapeFactory.h"
#include "Shape.h"

using namespace std;

int main()
{
    ShapeFactory* shapeFactory = new ShapeFactory();

    //获取 Circle 的对象,并调用它的 draw 方法
    //对象向上转型
    Shape* shape1 = shapeFactory->getShape("CIRCLE");
    //调用 Circle 的 draw 方法
    //多态的体现
    shape1->draw();
    delete shape1;
    shape1 = NULL;

    //获取 Rectangle 的对象,并调用它的 draw 方法
    Shape* shape2 = shapeFactory->getShape("RECTANGLE");
    //调用 Rectangle 的 draw 方法
    shape2->draw();
    delete shape2;
    shape2 = NULL;

    //获取 Square 的对象,并调用它的 draw 方法
    Shape* shape3 = shapeFactory->getShape("SQUARE");
    //调用 Square 的 draw 方法
    shape3->draw();
    delete shape3;
    shape3 = NULL;

    delete shapeFactory;
    shapeFactory = NULL;

    system("pause");
    return 0;
}

 不知道上述方法中使用delete方法是否正确,如下版本使用智能指针。

#include<iostream>
#include "ShapeFactory.h"
#include "Shape.h"

using namespace std;

int main()
{
    unique_ptr<ShapeFactory> shapeFactory = unique_ptr<ShapeFactory>(new ShapeFactory);
    //获取 Circle 的对象,并调用它的 draw 方法
    //对象向上转型
    unique_ptr<Shape> shape1 = shapeFactory->getShape("CIRCLE");
    //调用 Circle 的 draw 方法
    //多态的体现
    shape1->draw();

    //获取 Rectangle 的对象,并调用它的 draw 方法
    unique_ptr<Shape> shape2 = shapeFactory->getShape("RECTANGLE");
    //调用 Rectangle 的 draw 方法
    shape2->draw();

    //获取 Square 的对象,并调用它的 draw 方法
    unique_ptr<Shape> shape3 = shapeFactory->getShape("SQUARE");
    //调用 Square 的 draw 方法
    shape3->draw();

    system("pause");
    return 0;
}

 

 

5、实验结果

 

 

 

参考:https://www.runoob.com/design-pattern/factory-pattern.html

 

posted @ 2020-08-14 17:13  夏~  阅读(241)  评论(0编辑  收藏  举报