设计模式-02 设计模式-工厂模式factory


设计模式-02 设计模式-工厂模式factory

1.定义


工厂模式是一种创建型设计模式,它定义了一个创建对象的接口,让子类决定实例化哪一个类。

工厂模式使程序不必指定要创建产品的具体类,从而解耦应用程序与实际创建产品的具体类。

工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。

工厂模式属于创建型模式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。
               

			   
                                             .-------------.
                                             |             |
                                             | Factory     |
                                             '-------------'
                                                   |
                                                   |
                         .-------------------------v---------------------.
                         |                                               |
                         |           ProductA             ProductB       |
                         |-----------------------------------------------|
                                |              |              |
                                |  ProductA1   |  ProductA2   |  ProductB1 |
                                |              |              |            | 
                 .-----------------. |              |              |
                 |               |   v              v              v          |
  Client  .---> | FactoryMethod  | ->  ProductA1   ->  ProductA2   -> ProductB1
                 |               |
                 '---------------'

2.内涵

设计原则:

  • 单一职责原则:工厂类仅负责创建对象,不负责其他操作。
  • 开闭原则:工厂类对扩展开放,对修改关闭。新产品可以轻松添加到工厂中,而无需修改现有代码。
  • 依赖倒置原则:应用程序依赖于抽象(工厂类),而不是具体实现(产品类)。

优点:

  • 提高代码的灵活性,容易扩展。
  • 解耦应用程序与具体创建产品的类。
  • 封装产品创建过程,提高了可维护性。

缺点:

  • 引入了额外的抽象层,可能会增加代码复杂性。
  • 如果需要经常创建新产品,可能会导致大量工厂类。
3.案例对比


bad 设计


#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <fstream>
#include <tuple>
#include <sstream>
#include <memory>
#include <cmath>

using namespace std;

enum class PointType
{
    cartesian,polar
};


struct Point
{
    /**
     *  构造方法
     * @param a x or rho
     * @param b y or theta
     * @param type  根据Type 初始化对象
     */
    Point(float a, float b, PointType type = PointType::cartesian)
    {
        if(type == PointType::cartesian){
            x = a;
            y = b;
        }else {
            x = a * cos(b);
            y = a * sin(b);
        }
    }
    float x, y;
};

int main()
{
    return 0;
}


好的设计

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <fstream>
#include <tuple>
#include <sstream>
#include <memory>
#include <cmath>
using namespace std;

enum class PointType
{
    cartesian,
    polar
};

struct Point
{
    Point(float x, float y):x(x),y(y){}

public:
    float x, y;
    static Point NewCartesian(float x, float y)   // 静态工厂方法
    {
        return {x,y};
    }
    static Point NewPolar(float rho, float theta)   // 静态工厂方法
    {
        return {rho*cos(theta), rho*sin(theta)};
    }
    friend ostream &operator<<(ostream &os, const Point &point)
    {
        os << "X:" << point.x << " Y:" << point.y << endl;
        return os;
    }
};


int main()
{
    auto p = Point::NewPolar(5, 3.1415 / 4);
    cout << p <<endl;
}

4.注意事项

简单工厂

  • 局限性:限制了创建产品的灵活性,仅能创建预先定义好的产品。
  • 依赖管理:难以管理创建不同产品所依赖的类和对象。

其他注意事项:

  1. 职责单一原则:工厂类应仅负责创建产品,避免与其他职责混合。
  2. 可扩展性:工厂设计应考虑可扩展性,以支持未来添加新产品。
  3. 可测试性:工厂代码应易于测试,以验证创建产品的正确性。
  4. 性能瓶颈:如果工厂创建产品需要大量计算或资源,可能会成为性能瓶颈。
  5. 谨慎使用:工厂模式的过度使用可能会导致代码复杂性和维护成本增加。

5.最佳实践
  • 考虑抽象工厂,而不是简单工厂:抽象工厂提供更灵活和可扩展的解决方案。
  • 使用反射创建产品:当产品类型在运行时才知道时,反射可以帮助创建产品。
  • 利用设计模式组合:将工厂模式与其他模式相结合,例如策略模式或单例模式,以提高代码的可重用性和灵活性。
  • 单元测试工厂:使用单元测试验证工厂创建产品的正确性。
  • 避免过度使用:只有在确实需要分离产品创建时才使用工厂模式。

6.总结
 

工厂模式提供了一种创建对象而不指定其具体类的接口。

相关推荐

  1. 设计模式-02 设计模式-工厂模式factory

    2024-05-04 07:20:01       29 阅读
  2. 设计模式-03 设计模式-工厂模式factory-内部工厂

    2024-05-04 07:20:01       32 阅读
  3. 设计模式-工厂模式(Factory)

    2024-05-04 07:20:01       45 阅读
  4. 设计模式——工厂模式Factory

    2024-05-04 07:20:01       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-04 07:20:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-04 07:20:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-04 07:20:01       82 阅读
  4. Python语言-面向对象

    2024-05-04 07:20:01       91 阅读

热门阅读

  1. 2024牛客五一集训派对day2

    2024-05-04 07:20:01       26 阅读
  2. Matplotlib 绘图可视化全面总结

    2024-05-04 07:20:01       37 阅读
  3. 富格林:细节决定能否安全出金

    2024-05-04 07:20:01       32 阅读
  4. Spring MVC 中配置 DispatcherServlet

    2024-05-04 07:20:01       24 阅读
  5. 【EXCEL自动化12】删除excel文件中指定的行数据

    2024-05-04 07:20:01       34 阅读
  6. C#面:解释一下 UDDI、WSDL 的意义及其作用

    2024-05-04 07:20:01       28 阅读