zoukankan      html  css  js  c++  java
  • 工厂模式(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

  • 相关阅读:
    Java 注解
    java多线程
    webstorm配置Monokai-Sublime.jar主题
    express
    npm与package.json
    Node require方法加载规则
    js伪数组转数组
    node中的Console
    Node.js核心模块-url
    服务端渲染SSR和客户端渲染CSR
  • 原文地址:https://www.cnblogs.com/dreammmz/p/13503319.html
Copyright © 2011-2022 走看看