对象依赖于具体 类

object dependency on to concrete classes

我正在努力理解抽象工厂模式,虽然它真的很难。我从 Head First Design Patterns 书中看到了以下示例,试图描述依赖关系以及为什么依赖不好。但是,我不明白该代码示例中的以下说法。

Because any change to the concrete implementations of pizzas affects the DependentPizzaStore, we say that the DependentPizzaStore “depends on” the pizza implementations.

我真的不明白它是如何影响 class 的,它只是由 new 发起并使用 bakecut 等方法。 DependentPizzaStore对具体实现一无所知。

public class DependentPizzaStore {
  public Pizza createPizza(String style, String type) {
    Pizza pizza = null;
    if (style.equals("NY")) {
      if (type.equals("cheese")) {
        pizza = new NYStyleCheesePizza();
      } else if (type.equals("veggie")) {
        pizza = new NYStyleVeggiePizza();
      } else if (type.equals("clam")) {
        pizza = new NYStyleClamPizza();
      } else if (type.equals("pepperoni")) {
        pizza = new NYStylePepperoniPizza();
      }
    } else if (style.equals("Chicago")) {
      if (type.equals("cheese")) {
        pizza = new ChicagoStyleCheesePizza();
      } else if (type.equals("veggie")) {
        pizza = new ChicagoStyleVeggiePizza();
      } else if (type.equals("clam")) {
        pizza = new ChicagoStyleClamPizza();
      } else if (type.equals("pepperoni")) {
        pizza = new ChicagoStylePepperoniPizza();
      }
    } else {
      System.out.println("Error: invalid type of pizza");
      return null;
    }
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
  }
}

DependentPizzaStore 需要明确了解所有实现才能初始化它们。因此 DependentPizzaStore 依赖于这些实现并紧密耦合。如果这些实现的构造函数中的任何一个要更改,那么您还需要更改 DependentPizzaStore

抽象工厂将允许您提供一个接口来创建相关或依赖对象的系列,而无需指定它们的具体 类。

因为你的例子也有不同风格的披萨

public interface PizzaFactory {
    string getStyle();
    Pizza createPizza(String type);
}

那么不同的款式需要不同的工厂

public class NYStylePizzaFactory implements PizzaFactory {
    
    public string getStyle() { return "NY"; }
    
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new NYStyleCheesePizza();
        } else if (type.equals("veggie")) {
            pizza = new NYStyleVeggiePizza();
        } else if (type.equals("clam")) {
            pizza = new NYStyleClamPizza();
        } else if (type.equals("pepperoni")) {
            pizza = new NYStylePepperoniPizza();
        }
        
        if(pizza == null){
            //...throw?
        }
        
        return pizza;
    }
}

public class ChicagoStylePizzaFactory implements PizzaFactory {
    
    public string getStyle() { return "Chicago"; }
    
    public Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            pizza = new ChicagoStyleCheesePizza();
        } else if (type.equals("veggie")) {
            pizza = new ChicagoStyleVeggiePizza();
        } else if (type.equals("clam")) {
            pizza = new ChicagoStyleClamPizza();
        } else if (type.equals("pepperoni")) {
            pizza = new ChicagoStylePepperoniPizza();
        }
        
        if(pizza == null){
            //...throw?
        }
        
        return pizza;
    }
}

DependentPizzaStore 现在可以将制作披萨的任务委派给工厂,而无需了解任何实施细节。

public class DependentPizzaStore {
    List<PizzaFactory> factories;
    
    public DependentPizzaStore(List<PizzaFactory> factories) {
        this.factories = factories;
    }

    public Pizza createPizza(String style, String type) {
        Pizza pizza = null;
        for (PizzaFactory factory : factories) {
            if (factory.getStyle().equals(style)) {
                pizza = factory.createPizza(type);
                break;
            }
        }
        if (pizza == null){
          System.out.println("Error: invalid type of pizza");
          return null;
        }
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

任何其他样式都不会影响或导致商店发生变化。工厂制作披萨的方式的任何变化也不会影响或导致商店发生变化。

因此,存储依赖于抽象而不是具体化。