软件设计模式之工厂模式

软件设计模式之工厂模式

软件设计模式之工厂模式,是创建对象的核心设计原则之一,它允许客户以与库的类层次结构不紧密耦合的方式来创建库的对象

技术开发 编程 技术框架 技术发展

 

软件设计模式之工厂模式

软件设计模式之工厂模式,是创建对象的核心设计原则之一,它允许客户以与库的类层次结构不紧密耦合的方式来创建库的对象

工厂方法是一种创新的设计模式,即与对象创建有关。 在Factory模式中,我们创建对象时不将创建逻辑暴露给客户端,并且客户端使用相同的通用接口来创建新类型的对象。

这个想法是使用静态成员函数(静态工厂方法)来创建并返回实例,从而向用户隐藏类模块的详细信息。工厂模式是创建对象的核心设计原则之一,它允许客户以与库的类层次结构不紧密耦合的方式来创建库的对象(下面说明)。

当我们谈论图书馆和客户时,这意味着什么?

库是由某个第三方提供的,它公开了一些公共API,并且客户端调用这些公共API来完成其任务。一个非常简单的示例可以是Android OS提供的各种视图。

为什么采用工厂模式?

让我们通过一个例子来理解它:

// A design without factory pattern
#include <iostream>
using namespace std;
  
// Library classes
class Vehicle {
public:
    virtual void printVehicle() = 0;
};
class TwoWheeler : public Vehicle {
public:
    void printVehicle()  {
        cout << "I am two wheeler" << endl;
    }
};
class FourWheeler : public Vehicle {
    public:
    void printVehicle()  {
        cout << "I am four wheeler" << endl;
    }
};
  
// Client (or user) class
class Client {
public:
    Client(int type)  {
  
        // Client explicitly creates classes according to type
        if (type == 1)
            pVehicle = new TwoWheeler();
        else if (type == 2)
            pVehicle = new FourWheeler();
        else
            pVehicle = NULL;
    }
  
    ~Client()   {
        if (pVehicle)
        {
            delete[] pVehicle;
            pVehicle = NULL;
        }
    }
  
    Vehicle* getVehicle() {
        return pVehicle;
    }
private:
    Vehicle *pVehicle;
};
  
// Driver program
int main() {
    Client *pClient = new Client(1);
    Vehicle * pVehicle = pClient->getVehicle();
    pVehicle->printVehicle();
    return 0;
}

Output:

I am two wheeler

以上设计有什么问题?

正如您在上面的示例中已经观察到的那样,客户端在构造对象时会基于一些输入来创建TwoWheeler或FourWheeler的对象。

说,图书馆引入了一个新的类ThreeWheeler,其中也包含了三个轮车。会发生什么?如果在条件阶梯中创建ThreeWheeler对象,客户端将最终链接一个新的else。反过来,则需要重新编译客户端。因此,每次在库端进行新的更改时,客户端都需要在其末端进行一些相应的更改并重新编译代码。听起来不好吗?这是非常糟糕的设计实践。

如何避免这个问题?

答案是,创建一个静态(或工厂)方法。让我们看下面的代码。

// C++ program to demonstrate factory method design pattern
#include <iostream>
using namespace std;
  
enum VehicleType {
    VT_TwoWheeler,    VT_ThreeWheeler,    VT_FourWheeler
};
  
// Library classes
class Vehicle {
public:
    virtual void printVehicle() = 0;
    static Vehicle* Create(VehicleType type);
};
class TwoWheeler : public Vehicle {
public:
    void printVehicle() {
        cout << "I am two wheeler" << endl;
    }
};
class ThreeWheeler : public Vehicle {
public:
    void printVehicle() {
        cout << "I am three wheeler" << endl;
    }
};
class FourWheeler : public Vehicle {
    public:
    void printVehicle() {
        cout << "I am four wheeler" << endl;
    }
};
  
// Factory method to create objects of different types.
// Change is required only in this function to create a new object type
Vehicle* Vehicle::Create(VehicleType type) {
    if (type == VT_TwoWheeler)
        return new TwoWheeler();
    else if (type == VT_ThreeWheeler)
        return new ThreeWheeler();
    else if (type == VT_FourWheeler)
        return new FourWheeler();
    else return NULL;
}
  
// Client class
class Client {
public:
  
    // Client doesn't explicitly create objects
    // but passes type to factory method "Create()"
    Client()
    {
        VehicleType type = VT_ThreeWheeler;
        pVehicle = Vehicle::Create(type);
    }
    ~Client() {
        if (pVehicle) {
            delete[] pVehicle;
            pVehicle = NULL;
        }
    }
    Vehicle* getVehicle()  {
        return pVehicle;
    }
  
private:
    Vehicle *pVehicle;
};
  
// Driver program
int main() {
    Client *pClient = new Client();
    Vehicle * pVehicle = pClient->getVehicle();
    pVehicle->printVehicle();
    return 0;
}

Output:

I am three wheeler

在上面的示例中,我们已经完全从Client分离了用于对象创建的类型选择。该库现在负责根据输入决定要创建的对象类型。客户只需要调用库的工厂Create方法并传递所需的类型,而不必担心对象创建的实际实现。

工厂方法的其他示例:

  • 假设,在“绘图”系统中,根据用户的输入,可以绘制不同的图片,例如正方形,矩形,圆形。在这里,我们可以使用工厂方法根据用户的输入创建实例。要添加新的形状,无需更改客户代码。

  • 另一个例子:在旅游网站上,我们可以预订火车票,公共汽车票和机票。在这种情况下,用户可以将其旅行类型指定为“公共汽车”,“火车”或“航班”。这里,我们有一个抽象类'AnyTravel',其静态成员函数'GetObject'取决于用户的旅行类型,将创建并返回'BusTravel'或'TrainTravel'的对象。“公共汽车旅行”或“火车旅行”具有常用功能,例如乘客姓名,始发地,目的地参数。

技术开发 编程 技术框架 技术发展