成都软件开发的设计模式第二季

成都软件开发是创造性设计模式,即与对象创建有关。 在Factory模式中,我们创建对象而不将创建逻辑暴露给客户端,并且客户端使用相同的公共接口来创建新类型的对象。
我们的想法是使用静态成员函数(静态工厂方法)来创建和返回实例,从而隐藏用户的类模块的细节。
 
工厂模式是创建对象的核心设计原则之一,允许客户端以某种方式创建库的对象(如下所述),使其不与库的类层次结构紧密耦合。
 
当我们谈论图书馆和客户时,意味着什么?
库是由某些第三方提供的,它暴露了一些公共API,客户端调用这些公共API来完成其任务。一个非常简单的例子可以是Android OS提供的不同种类的视图。
 
 
 
 
 
为什么工厂模式?
让我们用一个例子来理解它:
 
filter_none
编辑
play_arrow
 
brightness_4
// 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; 
输出:
 
我是两轮车
上述设计有什么问题?
正如您在上面的示例中所观察到的那样,Client在构造其对象期间根据某些输入创建了TwoWheeler或FourWheeler的对象。
比如说,图书馆引入了一个新的类ThreeWheeler,以便合并三辆轮车。会发生什么?如果在条件梯形图中创建ThreeWheeler对象,客户端将最终链接一个新的else。这反过来又需要重新编译客户端。因此,每次在库侧进行新的更改时,客户端都需要在其末尾进行一些相应的更改并重新编译代码。听起来不错?这是一种非常糟糕的设计实践。
 
如何避免这个问题?
答案是,创建一个静态(或工厂)方法。我们来看下面的代码。
 
filter_none
编辑
play_arrow
 
brightness_4
// 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; 
输出:
 
我是三轮车
在上面的示例中,我们完全从Client中分离了对象创建的类型选择。库现在负责根据输入决定要创建的对象类型。客户端只需要调用库的工厂Create方法并传递它想要的类型,而不必担心对象创建的实际实现。
 
感谢Rumplestiltskin提供上述解释。
 
 
工厂方法的其他示例:
 
比如说,在“绘图”系统中,根据用户的输入,可以绘制不同的图片,如方形,矩形,圆形。在这里,我们可以使用工厂方法根据用户的输入创建实例。要添加新类型的形状,无需更改客户端的代码。
另一个例子:在旅游网站,我们可以预订火车票以及公交车票和机票。在这种情况下,用户可以将他的旅行类型称为“公共汽车”,“火车”或“航班”。
这里我们有一个带有静态成员函数'GetObject'的抽象类'AnyTravel',它取决于用户的旅行类型,将创建并返回'BusTravel'或'TrainTravel'的对象。“BusTravel”或“TrainTravel”具有常用功能,如乘客姓名,Origin,destinationparameters。
 
18215660330
179001057@qq.com