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

发布于:2024-05-04 ⋅ 阅读:(144) ⋅ 点赞:(0)

设计模式-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.总结
 

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


网站公告

今日签到

点亮在社区的每一天
去签到