首页 > 代码库 > 设计模式解析之工厂模式 (一)

设计模式解析之工厂模式 (一)

工厂模式在“创造模式”中是比较难理解的,困难之处并不在于工厂模式的定义本身,困惑的地方在于为什么要使用工厂模式,或者说是必须使用工厂的理由。


工厂模式的定义

Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate.

The Factory method lets a class defer instantiation to subclasses.

wKioL1R6wLjBoOjzAADfROTPUUw444.jpg


对于使用工厂模式的疑问在于,产品类所定义产品实体是在客户逻辑中真正使用的目标,如果产品类已经抽象,使用者只需要将产品的子类实例化后使用产品的接口或父类,为什么一定要使用工厂类,多此一举

即使使用工厂类,实际上是工厂的子类去实例化具体的产品,对于使用者来说,去判断使用哪一个工厂和去判断使用哪一个产品没有本质的区别,为什么在设计的时候还需要加入工厂的接口,和工厂的继承类,增加复杂度呢。


关键的问题在于工厂模式定义中的最后一句,工厂的子类决定如何实现子产品,实现局域化和特性化的产品。


产品的实例化,指的是子产品的实例化,子产品在实现的时候,是不是需要有特性化和局域化的需求,成为是否使用工厂模式的判断标准


更简单的说,如果所有的产品在的实例化只是一个简单的new,可以解决,那使用工厂就完全是多此一举。而各种产品,虽然可以维持统一接口, 但在实例化时是需要不同的,甚至复杂的处理,或者更复杂的逻辑处理,那么,工厂的目的就是,将复杂的不同的实例化逻辑统一成统一的接口,来屏蔽使用者对于实例化产品是对其复杂逻辑的理解与实现,而统一使用简单的工厂接口。


就以图中类为例

class Light{
public:
    Light(){}
    virtual void TurnOn() = 0;
}
class BulbLight : public {
public:
    BulbLight()
    void TurnOn() {
        // power 5v
    }
}
class TubeLight : public {
public:
    TubeLight(){}
    void TurnOn(){
        // power 220v
    }
}



如果做两个工厂类BulbFactory和TubeFactory对BulbLight和TubeLight进行实例化,使用者仍然需要决定并实现Factory的实例,这同实现具体的Light类没有区别,也没有益处,反而增加工作量和复杂度。

然而,Light子类的构造变得复杂时,情况变不一样了

class BulbLight : public {
    Power power;
public:
    BulbLight(Power bettery) : power(bettery) {}
    void Fill(Gas current_gas);
    void TurnOn() {
        // power 5v
    }
}
class TubeLight : public {
    Cable wire;
public:
    TubeLight(Cable power) : wire(power) {}
    void TurnOn(){
        // power 220v
    }
}

对于使用者来说,不去向BulbLight和TubeLight的设计者(文档)了解实例化的细节,将很难使用两个子类

这将是Factory的优势所在,Light子类的设计者,同时提供Factory接口的产品实例化方法,屏蔽了产品本身实例化的复杂逻辑

如果实例化之后还有其他本地化的逻辑,如Fill之类,工厂模式的特性会更具体的体现出来。




设计模式解析之工厂模式 (一)