关于java:工厂方法与抽象工厂

Factory Method Vs Abstract Factory

本问题已经有最佳答案,请猛点这里访问。

我读过工厂方法,其中子类创建所需对象,抽象工厂有方法,其中具体类创建所需对象。

工厂法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
    }

    abstract Pizza createPizza(String type);

}

public NewYorkPizzaStore extends PizzaStore {

    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if("cheese".equals(type)) {
            pizza = new CheesePizza();
        }
        else if("onion".equals(type)) {
            pizza = new OnionPizza();
        }

        return pizza;
    }

}

public class pizzaTestDriveByFactoryMethod() {

    public static void main(String args[]) {
        PizzaStore ps =  new NewYorkPizzaStore();
        ps.orderPizza("cheese");
    }

}

使用工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class NewYorkPizzaFactory extends PizzaFactory {

    public Pizza createPizza(String pizza) {
        Pizza pizza = null;
        if("cheese".equals(type)) {
            pizza = new CheesePizza();
        } else if("onion".equals(type)) {
            pizza = new OnionPizza();
        }

        return pizza;
    }

}

public class PizzaStore {

    PizzaFactory factory;

    public PizzaStore(PizzaFactory factory) {
        this.factory =  factory
    }

    public Pizza orderPizza(String type) {
        Pizza pizza =  factory.createPizza(type)
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        return pizza;
    }

}

public class pizzaTestDriveByAbstractFactory() {

    public static void main(String args[]) {
        PizzaFactory nwFactory = new NewYorkPizzaFactory();
        PizzaStore ps =  new PizzaStore(nwFactory);
        ps.orderPizza("cheese");
    }

}

使用工厂方法和抽象工厂实现相同的用例。为什么应该使用FactoryMethod而不是抽象工厂或实用工厂(如芝加哥工厂/纽约工厂)。在哪种情况下,工厂方法对抽象方法有用?


主要的区别在于,您可以实现一个工厂对象,而无需对正在处理工厂的对象进行子类化。这也意味着你可以做一些事情,比如在飞行中交换工厂。另一方面,如果您只是做一些简单的或紧密耦合的事情,那么您最好提供简单的方法。


您应该询问工厂任务在概念上是否与基类和/或子类(如CreatePizza)相关联(如ProcurePizzaBox)。比萨盒供应商不仅概念上不同,而且可以互换。它甚至可能是一家为每个城市提供比萨盒的全国性公司。

另一种决定方法是,如果您只是为了实现工厂方法而创建子类,那么最好将其分解为抽象工厂。

但是,如果子类有自己的特点,不管怎样都需要存在,并且方法的实现是与它们联系在一起的(即使它是采购包装盒,但是供应商是本地的并且不是一个重要的细节),那么您应该使用工厂方法作为多态性和OO的自然应用,并保持类的计数。

从工厂方法到抽象工厂的重构可能比反向更容易,并且需要的类更少,因此可以认为是更保守的选择。