Skip to content

设计模式 - 工厂模式 #12

@DelBlank

Description

@DelBlank

简单工厂模式(Simple Factory Pattern)

通过定义一个‘工厂’来创建不同的‘产品’,创建的‘产品’由传入的参数决定。

OOP 中,‘工厂’就是一个用来创建其他’产品‘对象实例的对象,这些’产品‘对象往往继承自相同的父类。

一般而言,‘工厂’也可以是一个接收‘产品’参数的函数,通过调用该函数来创建‘产品’。

/* OOP */
// 产品类
class Product {
    method() {}  
}
// 产品 A 类
class ProductA extends Product {
    method() {return 'a'}
}
// 产品 B 类
class ProductB extends Product {
    method() {return 'b'}
}
// 工厂类
class Factory {
    static createProduct(type) {
        switch(type) {
            case 'A':
	        return new ProductA()
            case 'B':
                return new ProductB()
        }
     }
}

const product1 = Factory.createProduct('A')

// 工厂函数
function factory(type) {
    switch(type) {
        case 'A':
	    return new ProductA()
	case 'B':
            return new ProductB()
    }
}

const product2 = factory('B')

优点

  • 分离对象的创建和使用,外部创建‘产品’时无需知道‘产品’的创建细节。

缺点

  • 添加新‘产品’时不得不修改‘工厂’内部逻辑,不符合‘开闭原则‘。
  • 在‘产品’类型较多时,会造成‘工厂’内部逻辑过于复杂不利于维护。

工厂方法模式(Factory Method Pattern)

简单工厂模式的进一步扩展,创建具体‘产品’的过程由具体’子工厂‘去执行,而不是像简单工厂模式一样,具体‘产品’通过一个‘父工厂’去创建。

// 工厂父类
class Factory {
    createProduct(){}
}

// 工厂子类 A
class FactoryA extends Factory {
    createProduct(){return new ProductA()}
}

// 工厂子类 B 
class FactoryB extends Factory {
    createProduct(){return new ProductB()}
}

const product1 = new FactoryA().createProduct()
const product2 = new FactoryB().createProduct()

优点

  • 外部不需要知道具体‘产品’细节就可以创建它 。
  • 增加新‘产品’或新‘工厂’时候,只需要新增‘工厂子类’和‘产品子类’即可,不需要修改原来的代码,更加符合‘开闭原则’。
  • 不同类型‘产品类‘的创建逻辑维护在不同的’工厂类‘中,方便维护和扩展,符合‘单一职责原则’。

缺点

  • 每增加一个新‘产品类’就需要新增一个匹配的‘工厂类’,会给系统带来额外开销。

抽象工厂模式(Abstract Factory Pattern)

在工厂方法模式中,每个具体的‘工厂’只能生产一种具体的‘产品’,产品和工厂一一对应,对于单一类型的‘产品’,工厂方法模式完全可以支持,但是对于多种类型的‘产品’,工厂方法模式就难以支持。为了解决这种问题,在工厂方法模式的基础上提出抽象工厂模式,它允许你在不知道’产品‘细节的前提下,创建一系列相关的’产品‘。

// 抽象产品 A 类
class AbstractProductA {}
// 产品 A1 类
class ProductA1 extends AbstractProductA{}
// 产品 A2 类
class ProductA2 extends AbstractProductA{}

// 抽象产品 B 类
class AbstractProductB {}
// 产品 B1 类
class ProductB1 extends AbstractProductB{}
// 产品 B2 类
class ProductB2 extends AbstractProductB{}

// 抽象工厂类
class AbstractFactory {
    createProductA(){}
    createProductB(){}
}
// 工厂 1 类, 专门生产 1 类产品
class Factory1 extends AbstractFactory{
    createProductA() {return new ProductA1()}
    createProductB() {return new ProductB1()}
}
// 工厂 2 类,专门生产 2 类产品
class Factory2 extends AbstractFactory{
    createProductA() {return new ProductA2()}
    createProductB() {return new ProductB2()}
}

const factory1 = new Factory1()
const factory2 = new Factory2()
const productA1 = factory1.createProductA()
const productB1 = factory1.createProductB()
const productA2 = factory2.createProductA()
const productB2 = factory2.createProductB()

像上面代码中 ProductA1ProductB1,ProductA2ProductB2 被分别称为一个产品簇(彼此强关联的不同类型‘产品集合’),我们可以说:Factory1 用来制造产品簇1Factory2 用来制造产品簇2

优点

  • 该模式把强关联的’产品‘放到一个’工厂‘中去创建,外部不需要关注这些‘产品’ 的实现和创建细节,更加符合高内聚松耦合的原则
  • 方便新增具体‘工厂类’和‘产品簇’,符合‘开闭原则’。

缺点

  • 新增某个类型‘产品’时,需要修改抽象工厂类及继承它的所有子工厂类,子工厂类如果比较多,则修改会比较繁琐,不符合‘开闭原则’。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions