• 【设计模式】简单工厂模式


    简单工厂模式–》工厂模式—》抽象工厂模式

    简单工厂模式定义:

    简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同的实例,被创建的实例通常都有共同的父类,因为在简单工厂模式中用于创建实例的方法是今天方法,因此简单工厂模式也称为静态工厂模式,它属于类创建型模式。

    1.要点
    当你需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道细节,简单工厂的结构模式比较简单,其核心就是工厂类的设计。

    各个角色

    1.Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产品对象,
    在工厂中提供静态的工厂方法factory(),它的返回类型为抽象产品类型Product。)
    2.Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入提高了系统的灵活性,是的工厂类只需要定义一种通用的工厂方法,因为所有擦黄建德具体铲平都是它的子类对象。
    3.ConcreteProduct(具体产品角色):简单工厂模式的创建目标,所有被创建的对象都充当这个角色的具体类的实例,每个具体产品角色都继承了抽象产品角色,需要实现的抽象产品中声明的抽象方法。
    请添加图片描述

    代码实现 :

    1. 抽象产品类

    在使用简单工厂模式时,首先需要对产品进行重构,不能设计一个包罗万象的产品类,而根据实际情况设计一个铲平层次结构,将所有产品公共的代码移到抽象产品类,并在抽象产品类中声明一些抽象方法,以供不同的具体产品来实现,如下:

    class Product
    {
       //所有产品类的公共业务方法
    }
    public:
      void methodSame()
      {
          //公共方法的实现。
      }
      //声明抽象业务方法
      virtual void methoddiff() = 0;
      };
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2. 具体产品类:

    实现抽象类中的抽象方法。

    class ConcreateProductA:public Product
    {
       //实现业务
       public:
          void methodiff()
          {
              //业务方法的具体实现。
          }
    }class ConcreateProductB:public Product
    {
       //实现业务
       public:
          void methodiff()
          {
              //业务方法的具体实现。
          }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3. 工厂类:简单工厂模式的核心。

    提供的工厂方法必须是,静态方法>
    功能:通过客户端传入的参数,选择创建不同的对象。

    class Factory
    {
       public:
       static Product * getProduct(string src)
       {
          Product *product = NULL;
          if(src = "B")
          {
          product = new ConcreteProductA();
          //初始化 product
           }
           else if(src = B)
           {
              product = new ConcreteProductB();
               //初始化产品
           }
           return product;
       }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    客户端

    int main()
    {
       Profuct *product = nullptr;
       //通过工厂创建产品对象
       product = Factory::getProduct("A");
       product -> methodSame();
       product->methodDiff();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    设计图表

    未使用简单工厂模式:

    class Chart
    {
    private:
    	string type; // 图表类型
    public:
    	Chart(const string& t) : type(t)
    	{
    		if (type == "histogram") {
    			// 初始化柱状图
    		}
    		else if (type == "pie") {
    			// 初始化饼状图
    		}
    		else if (type == "line") {
    			// 初始化折线图
    		}
    	}
    
    	void display()
    	{
    		if (type == "histogram") {
    			// 显示柱状图
    		}
    		else if (type == "pie") {
    			// 显示饼状图
    		}
    		else if (type == "line") {
    			// 显示折线图
    		}
    	}
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    出现的问题:

    1. 在Chart类中包含很多"if…else"代码块,整个类的代码相当冗长;如果需求大,代码会越长,阅读难度和维护难度越大;而且大量条件语句会影响系统的性能。
    2. Chart类的职责过重,违反了“单一职责原则”,不利于类的重用和维护。
    3. 当需要增加新类型的图表时,必须修改chart类的源代码,违反了“开闭原则”。
    4. 客户端只能通过new关键字来直接创建Chart类对象,4.类与客户端类的耦合度较高,对象的创建和使用无法分离。

    使用简单工厂模式:

    抽象产品类

    class Chart
    {
    public:
        virtual void display() = 0;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    具体产品类

    //具体产品类
    class histogram : public Chart
    {
    public:
         histogram()
        {
            cout << "创建柱状图" << endl;
        }
        void display()
        {
            cout << "显示柱状图" << endl;
        }
    };
    class Linechart : public Chart
    {
    public:
        Linechart()
        {
            cout << "创建线形图" << endl;
        }
        void display()
        {
            cout << "显示线形图" << endl;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    静态工厂方法

    1. 没有this指针,不依赖于对象,只能访问静态成员。
    2. 可以直接根据类来调用。因为它的功能就是创建对象。
    
    • 1
    • 2
    class Factory
    {
    public:
        //静态工厂方法   
        //没有this指针,不依赖于对象,只能访问静态成员。
        //可以直接根据类来调用。因为它的功能就是创建对象。
        static Chart *getFactory(string src)
        {
           Chart * chart = NULL;
            if (src == "histogram")
            {
                chart = new histogram();
                cout << "初始化柱状图" << endl;
            }
            else if (src == "line")
            {
                chart = new Linechart();
                cout << "初始化线形图" << endl;
            }
            return chart;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    int main()
    {
        Chart *fa = NULL;
        //通过静态工厂方法创建具体产品类对象
        fa = Factory::getFactory("line");
        fa->display();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果:请添加图片描述

    总结:

    在简单工厂模式下,客户端通过工厂类创建了一个产品类的实例,而无需直接使用new关键字来创建对象。

    优点:

    1.工厂类包含必要的逻辑判断,可以再什么时候创建哪一个产品的实例。客户端就不需要做这些了。
    2.客户端无需知道具体产品类的类名,只需要直到具体产品类对应的参数,对于一些复杂的类名,免去了使用者去记忆。
    3.引入配置文件,可以在不修改任何客户端代码的情况下更换合增加新的具体产品类,提高了系统的灵活性。

    缺点:

    1.工厂类集中类所有产品的创建逻辑,职责过重。
    2.使用简单工厂模式势必增加系统中累的个数。增加了系统的复杂度。
    3.系统扩展困难,因为每添加一个具体的产品类,势必要修改工厂类。产品太多,更难维护,
    4.简单工厂模式使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

    使用场景:

    1.工厂类负责创建的对象少。
    2.客户端只知道传入工厂类的参数,对如何创建不关注,

    改进:

    class Chart
    {
    public:
        virtual void display() = 0;
         static Chart *getFactory(const string &src);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
     static Chart *Chart::getFactory(const string &src)
        {
           Chart * chart = NULL;
            if (src == "histogram")
            {
                chart = new histogram();
                cout << "初始化柱状图" << endl;
            }
            else if (src == "line")
            {
                chart = new Linechart();
                cout << "初始化线形图" << endl;
            }
            return chart;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    还可以使用Json,通过修改配置文件来创建不同的对象。

  • 相关阅读:
    基于51单片机的智能遥控晾衣架温度湿度光强检测proteus仿真原理图PCB
    WordPress 后台密码忘记后,重置找回密码的 N 种方法
    Spring boot和Vue.js实现基于oauth2授权码模式的认证 (二)
    APISIX 在君润人力云原生平台的架构实践
    PDF文件怎么解密?教你三种解密的方法
    第六章 数字化工作方法与应用
    【SetpNumber计数器StepNumber详解,购物车制作(呆),五星好评制作Starjs详解】
    Pytest简介及jenkins集成
    理解自动驾驶感知技术
    输出总结是成长的开始
  • 原文地址:https://blog.csdn.net/weixin_52958292/article/details/127592989