Заводской метод нарушает принцип инверсии зависимостей?

public class DependentPizzaStore {
  public Pizza createPizza(String type) {
    Pizza pizza = null;
    if (Style.equals("NY")) {
      if (type.equals("cheese")) {
        pizza = new NYStyleCheesePizza();
      }
      else if(type.equals("Veggie")){
        pizza = new NYStyleVeggiePizza();
      }
    }

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
  }
}

Этот пример из Headfirst Design Patterns нарушает "Принцип обращения зависимостей", который называется "Зависит от абстракций. Не зависит от конкретных классов".

Приведенный выше пример нарушает правила, поскольку DependentPizzaStore (компонент высокого уровня) зависит от конкретных реализаций пицц (компонентов низкого уровня).

Чтобы исправить это, мы используем шаблон Factory Method.

public abstract class PizzaStore {
  protected abstract Pizza createPizza(String item);
  public Pizza orderPizza(String type) {
    Pizza pizza = createPizza(type);
    System.out.println("--- Making a " + pizza.getName() + " ---");
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
  }

  public class NYPizzaStore extends PizzaStore {
    protected Pizza createPizza(String item) {
      Pizza pizza = null;
      if (item.equals("cheese")) {
        pizza = new CheesePizza();
      } else if (item.equals("veggie")) {
        pizza = new VeggiePizza();
      }
      return pizza;
    }   
  }

Теперь PizzaStore (компонент высокого уровня) зависит только от абстракции Pizza конкретных классов Pizza, а также конкретные пиццы зависят от абстракции Pizza, поскольку они расширяют ее.

Мой вопрос: нарушает ли класс NYPizzaStore "Принцип инверсии зависимости", потому что он зависит от CheesePizza() и VeggiePizza(), которые являются конкретными реализациями Pizza.

1 ответ

По моему мнению, DIP применяется в вашей основной части программы. Вы должны задаться вопросом:

Где код, который изменяет мою цель?

В вашем случае ваша цель состоит в том, чтобы позволить создавать пиццу, следуя некоторым правилам и не завися от того, какую пиццу вы строите.

Таким образом, DIP должен применяться к вашему классу PizzaStore. Но все классы, которые вы используете для достижения этой цели, являются просто разновидностями "плагинов", и поэтому нет необходимости использовать DIP.

Действительно, во всех типах программ должно быть хотя бы одно место для простых серий if/else, содержащих конкретные классы, в противном случае вы никогда не сможете получить готовый продукт. Даже самый совершенный код не может быть "абстрактным" на все 100%.

Другие вопросы по тегам