Java 对象对具体类的依赖性

Java 对象对具体类的依赖性,java,design-patterns,dependency-injection,factory-pattern,abstract-factory,Java,Design Patterns,Dependency Injection,Factory Pattern,Abstract Factory,我试图理解抽象的工厂模式,但这确实很难。我看到了下面的例子,来自Head First Design Patterns一书,试图描述依赖性以及为什么依赖性不好。然而,我不理解下面关于代码示例的说法 因为对pizzas具体实现的任何更改都会影响 在DependentPizzaStore中,我们说DependentPizzaStore依赖于比萨饼 实现 public class DependentPizzaStore { public Pizza createPizza(String style,

我试图理解抽象的工厂模式,但这确实很难。我看到了下面的例子,来自Head First Design Patterns一书,试图描述依赖性以及为什么依赖性不好。然而,我不理解下面关于代码示例的说法

因为对pizzas具体实现的任何更改都会影响 在
DependentPizzaStore
中,我们说
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;
  }
}
我真的不明白它是如何影响这个类的,它只是通过
new
s启动,并使用
bake
cut
等方法
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;
    }
}
公共类DependentPizzaStore{
列出工厂名单;
公共从属IzzaStore(列出工厂){
这个。工厂=工厂;
}
公共披萨createPizza(字符串样式,字符串类型){
比萨饼=空;
用于(比萨饼工厂:工厂){
if(factory.getStyle().equals(style)){
pizza=factory.createPizza(类型);
打破
}
}
if(pizza==null){
System.out.println(“错误:比萨饼类型无效”);
返回null;
}
比萨饼;
比萨饼;
比萨饼;
比萨饼盒();
返回比萨饼;
}
}
任何附加样式都不会影响或导致商店发生变化。对工厂制作比萨饼的方式的任何改变也不会影响或引起商店的变化


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

我们可以说构造函数的签名是实现细节吗?因为在第一句话中,您说DependentPizzaStore需要明确了解所有实现。@是的,了解构造函数签名是一个实现细节