回顾设计模式之工厂模式1_简单工厂

工厂模式主要是XXXXXXXXXXXXX。 哈哈,有关XXXX,我只想让大家不要深入学习设计模式前,不要太关心某某设计模式是XXXXX。为什么呢?其实,一句话,一个定义很难表现出某个设计模式是为解决什么问题而衍生出来,才被称为设计模式。所以,这个系列的文章,主要以使用场景为入口,在使用场景中发挥设计模式的作用,知道设计模式怎么用,才能用好设计模式。

简单工厂(SimpleFactory)

简单工厂只是一种编程习惯,大家在开发过程中,不经意都在使用这种方式,误将它成为设计模式。下面这种场景我们经常会使用简单工厂。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//代码片段1
public class HamburgStore {

public Hamburg orderHamburg(String type) {
Hamburg hamburg = null;

if ("bacon".equals(type)) {
hamburg = new BaconHamburg();
} else if ("vegetarian".equals(type)) {
hamburg = new VegetarianHamburg();
} else if ("wheat".equals(type)) {
hamburg = new WheatHamburg();
}

hamburg.prepare();
hamburg.make();
hamburg.box();

return hamburg;
}
}

通过这段代码可以总结以下几个问题:

  • Line7-13的修改可能比较多(比如我们新增(减少)一种汉堡),导致orderHamburg方法没有做到对修改关闭;
  • 同时非Line7-13基本不会有太大变动,我们需要把变化和不变化的分离开来。

我们很快就调整为如下写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//代码片段2
public class HamburgStore {

private SimpleFactory simpleFactory;

public HamburgStore(SimpleFactory simpleFactory) {
this.simpleFactory = simpleFactory;
}

public Hamburg orderHamburg(String type) {

Hamburg hamburg = simpleFactory.createHamburg(type);
hamburg.prepare();
hamburg.make();
hamburg.box();

return hamburg;
}
}
//代码片段3
public class SimpleFactory {

    public Hamburg createHamburg(String type){

        Hamburg hamburg = null;
        if ("bacon".equals(type)) {
            hamburg = new BaconHamburg();
        } else if ("vegetarian".equals(type)) {
            hamburg = new VegetarianHamburg();
        } else if ("wheat".equals(type)) {
            hamburg = new WheatHamburg();
        }
        return hamburg;
    }
}
简单工厂 UML图如下:

SimpleFactory UML

简单工厂的描述:
  • Hamburg是抽象类;
  • VegetarianHamburg和BaconHamburg等是具体类,需要实现Hamburg接口;
  • SimpleFactory是我们创建Hamburg的工厂;
  • HamburgStore是工厂的“客户”。
简单工厂的优点:
  • 使“客户”HamburgStore无需了解“产品”Hamburg种类的增加,减少,以及Hamburg的创建细节,HamburgStore可以专注于消费产品。
简单工厂的缺点:
  • SimpleFactory违背了“系统对扩展开放,对修改关闭”原则,每次“产品”Hamburg的调整都需要修改SimpleFactory。
简单工厂的使用场景:
  • 工厂类负责创建的对象比较少;
  • 客户只知道传入工厂类的参数,不关心工厂如何创建对象;
  • 违背了“开放关闭”原则,所以一般在比较简单情况下使用;