【问题标题】:object dependency on to concrete classes对象对具体类的依赖
【发布时间】:2021-04-25 13:18:45
【问题描述】:

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

因为对比萨饼具体实现的任何更改都会影响 DependentPizzaStore,我们说DependentPizzaStore“取决于”披萨 实现。

我真的不明白它如何影响刚刚由news 启动并使用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;
  }
}

【问题讨论】:

    标签: java design-patterns dependency-injection factory-pattern abstract-factory


    【解决方案1】:

    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 需要明确了解所有实现。
    • @snr 是的,知道构造函数签名是一个实现细节
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    相关资源
    最近更新 更多