Bootstrap

1 工厂方法(Factory Method)模式

工厂方法模式

1.1 分类

(类)创建型

1.2 提出问题

一个物流公司最初只使用卡车运输,现需要增加轮船运输业务。目前的程序代码与卡车关联。

1.3 解决方案

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

1.4 实现关键

如何把new关起来,实现创造者和产品松耦合?
在这里插入图片描述

  1. 产品(Product)将会对接口进行声明。
  2. 具体产品(Concrete Products)是产品接口的不同实现。
  3. 创建者(Creator)声明返回产品对象的工厂方法。
  4. 具体创建者(Concrete Creators) 将会重写基础工厂方法, 使其返回不同类型的产品。

1.5 示例代码

#include <iostream>
//产品的接口
class Transport {
public:
    virtual ~Transport(){}
    virtual void deliver() const = 0;
};
//产品A
class Truck:public Transport {
public:
    void deliver() const override{
        std::cout << "卡车运输货物中ing。\n";
    }
};
//产品B
class Ship :public Transport {
public:
    void deliver() const override {
        std::cout << "轮船运输货物中ing。\n";
    }
};
//创造者(注意:除了创建产品以外,创造者还有自己的业务需要处理)
class Logistics {
public:
    virtual ~Logistics(){}
    //工厂方法的核心
    virtual Transport * factoryMethod() const = 0;
    void doSomething() const {
        Transport * transport= factoryMethod();
        transport->deliver();
        delete transport;
    }
};
//具体的创造者A
class TruckLogistis:public Logistics {
public:
    virtual ~TruckLogistis(){}
    virtual Transport* factoryMethod() const override{
        return new Truck();
    }
};
//具体的创造者B
class ShipLogistis :public Logistics {
public:
    virtual ~ShipLogistis() {}
    virtual Transport* factoryMethod() const override {
        return new Ship();
    }
};
int main()
{
    Logistics* truckLogistics = new TruckLogistis();
    Logistics* shipLogistics = new ShipLogistis();

    truckLogistics->doSomething();
    truckLogistics->doSomething();
   
    shipLogistics->doSomething();
    shipLogistics->doSomething();
    shipLogistics->doSomething();
    delete truckLogistics;
    delete shipLogistics;
}

1.6 举个栗子

跨平台的对话框:在不同的操作系统下,UI组件外观或许略有不同,但其功能保持一致。Windows系统中的按钮在Linux系统中仍然是按钮。 如果使用工厂方法,就不需要为每种操作系统重写对话框逻辑。
在这里插入图片描述

1.7 总结

  1. 对扩展开放,对修改关闭。
  2. 依赖倒置,避免依赖具体的类,尽量依赖抽象。可以避免创建者和具体产品之间的紧密耦合。
  3. 单一职责原则。将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
  4. 和针对接口编程,不要针对实现编程相比,依赖倒置,更注重抽象。产品和创造者都要依赖抽象。而倒置指的是从具体的产品,往上依赖。
  5. 缺点:应用工厂方法模式需要引入许多新的子类,代码可能会因此变得更复杂。最好的情况是将该模式引入创建者类的现有层次结构中。
;