# 工厂模式之“抽象工厂”

还是继续昨天的公司员工信息系统的例子。最后实现的代码是这样的。

function Factory(name, age, career) {
    let work
    switch(career) {
        case 'coder':
            work =  ['写代码','写系分', '修Bug'] 
            break
        case 'product manager':
            work = ['订会议室', '写PRD', '催更']
            break
        case 'boss':
            work = ['喝茶', '看报', '见客户']
        case 'xxx':
            // 其它工种的职责分配
            ...
            
    return new User(name, age, career, work)
}

这是一个相当扁平化的工厂,虽然很多公司声称扁平化管理,没有层级。但你还是要清楚,你和boss 是有区别的,一个是领工资的,一个是发工资的。老板有能力领工资,但你未必有能力发工资。

所以在上面这段代码里至少有两个层级,但也可以按照基层+中层+高层+外部人员的方式分出管理层级。这就有了一个新的需求。

将员工的层级区分出来。

怎么办?直接修改 Factory 吗?

# 开放封闭原则

对拓展开放,对修改封闭。

软件尸体(类,模块,函数可以扩展但不能修改)

所以在增加新的需求的时候,我们首先要想的不是修改,而是扩展。

怎么样才能实现拓展,怎么写才方便拓展。

# 抽象工厂和具体工厂

抽象工厂(AbstractFactory)不干活只定规矩,具体工厂(ConcreteFactory)才是干活的那一个。

在具体工厂中,用来 new 出具体对象的类叫做具体产品类(ConcreteProduct)。

具体产品类不会孤立存在,不同的具体产品类都有着共同的功能。

而这个所谓的共同功能实际上是在抽象产品类(AbstractProduct)中规定的。

有点乱是不是,我们不妨简单的梳理一下:

  1. 抽象工厂和具体工厂的关系:继承,具体工厂继承自抽象工厂
  2. 抽象工厂和抽象产品类的关系:没有直接的关系
  3. 具体工厂和具体产品类:具体产品类会在具体工厂里 new
  4. 抽象产品类和具体产品类:继承,具体产品类继承自抽象产品类