В чем разница между шаблоном стратегии и инъекцией зависимостей?

Стратегия и инжекция зависимостей позволяют нам устанавливать/внедрять объекты во время выполнения. В чем разница между шаблоном стратегии и инъекцией зависимостей?

Ответ 1

DI и Strategy работают одинаково, но стратегия используется для более мелкозернистых и короткоживущих зависимостей.

Когда объект сконфигурирован с "фиксированной" стратегией, например, когда объект построен, различие между Strategy и DI размывается. Но в сценарии DI более необычно, что зависимости объектов изменяются в течение их жизни, в то время как это не редкость со Стратегией.

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

Стратегия фокусируется на намерениях и призывает вас создать интерфейс с различными реализациями, которые подчиняются одному и тому же поведенческому контракту. DI больше связан с реализацией какого-либо поведения и его обеспечением.

С помощью DI вы можете разложить свою программу по другим причинам, чем просто для замены частей реализации. Интерфейс, используемый в DI только с одной реализацией, очень распространен. "Стратегия" только с одной конкретной реализацией (когда-либо) не является реальной проблемой, но, вероятно, ближе к DI.

Ответ 2

Разница заключается в том, чего они пытаются достичь. Шаблон стратегии используется в ситуациях, когда вы знаете, что хотите поменять местами реализации. Например, вам может понадобиться форматировать данные по-разному - вы можете использовать шаблон стратегии, чтобы поменять формат форматирования XML или форматировщик CSV и т.д.

Injection Dependency отличается тем, что пользователь не пытается изменить поведение во время выполнения. Следуя приведенному выше примеру, мы можем создать программу экспорта XML, в которой используется форматировщик XML. Вместо того, чтобы структурировать код следующим образом:

public class DataExporter() {
  XMLFormatter formatter = new XMLFormatter();
}

вы бы "ввели" форматирование в конструкторе:

public class DataExporter {
  IFormatter formatter = null;

  public DataExporter(IDataFormatter dataFormatter) {
    this.formatter = dataFormatter;
  }
}

DataExporter exporter = new DataExporter(new XMLFormatter());

Есть несколько оправданий для Injection Dependency Injection, но первичный для тестирования. У вас может быть случай, когда у вас есть какой-то механизм устойчивости (например, база данных). Однако при повторном тестировании может быть больно использовать реальную базу данных. Таким образом, для ваших тестовых примеров вы должны вводить базу данных фиктивных данных, чтобы не налагать на них накладные расходы.

Используя этот пример, вы можете увидеть разницу: мы всегда планируем использовать стратегию хранения данных, а также ту, которую мы передаем (реальный экземпляр БД). Однако при разработке и тестировании мы хотим использовать разные зависимости, поэтому мы вводим различные конкреции.

Ответ 3

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

Было бы рискованно говорить, что DI - это просто переименованный шаблон стратегии, так как он начинает разбавлять то, на что действительно рассчитан шаблон стратегии, IMO.

Ответ 4

Чувак, инъекция зависимостей - более общий шаблон, и он зависит от абстракций, а не конкреций и является частью каждого шаблона, но шаблон стратегии является решением более конкретной проблемы.

это определение из википедии:

DI:

Зависимость инъекции (DI) в объектно-ориентированное компьютерное программирование представляет собой шаблон проектирования с ядром принцип ветки поведения от разрешение зависимостей. Другими словами: техника для развязки зависимых программных компонентов.

Стратегия:

В компьютерном программировании стратегия шаблон (также известный как политика шаблон) - это конкретное программное обеспечение шаблона проектирования, посредством чего алгоритмы могут выбирается во время выполнения.

Схема стратегии предназначена для предоставить средства для определения семьи алгоритмов, инкапсулировать каждый из них как объект и сделать их взаимозаменяемыми. Шаблон стратегии позволяет алгоритмы меняются независимо от клиентов, которые их используют.

Ответ 5

Стратегии - это вещи более высокого уровня, которые используются для изменения того, как вещи вычисляются. При инъекции зависимостей вы можете изменить не только то, как вещи вычисляются, но и изменить то, что есть.

Для меня это становится понятным при использовании модульных тестов. Для выполнения производственного кода у вас есть все данные, скрытые (т.е. Частные или защищенные); тогда как при модульных тестах большинство данных является общедоступным, поэтому я могу посмотреть на него с помощью утверждений.


Пример стратегии:

public class Cosine {
  private CalcStrategy strat;

  // Constructor - strategy passed in as a type of DI
  public Cosine(CalcStrategy s) {
    strat = s;
  }
}

public abstract class CalcStrategy {
  public double goFigure(double angle);
}

public class RadianStrategy extends CalcStrategy {
  public double goFigure(double angle) {
    return (...);
  }
}
public class DegreeStrategy extends CalcStrategy {
  public double goFigure(double angle) {
    return (...);
  }
}

Обратите внимание, что нет общедоступных данных, которые отличаются между стратегиями. Не существует и других методов. Обе стратегии имеют все те же функции и подписи.


Теперь для инъекции зависимостей:

public class Cosine {
  private Calc strat;

  // Constructor - Dependency Injection.
  public Cosine(Calc s) {
    strat = s;
  }
}

public class Calc {
  private int numPasses = 0;
  private double total = 0;
  private double intermediate = 0;

  public double goFigure(double angle) {
    return(...);
}

public class CalcTestDouble extends Calc {
  // NOTICE THE PUBLIC DATA.
  public int numPasses = 0;
  public double total = 0;
  public double intermediate = 0;
  public double goFigure(double angle) {
    return (...);
  }
}

Использование:

public CosineTest {

  @Test
  public void testGoFigure() {
    // Setup
    CalcTestDouble calc = new CalcTestDouble();
    Cosine instance = new Cosine(calc);

    // Exercise
    double actualAnswer = instance.goFigure(0.0);

    // Verify
    double tolerance = ...;
    double expectedAnswer = ...;
    assertEquals("GoFigure didn't work!", expectedAnswer,
         actualAnswer, tolerance);

    int expectedNumPasses = ...;
    assertEquals("GoFigure had wrong number passes!",
        expectedNumPasses, calc.numPasses);

    double expectedIntermediate = ...;
    assertEquals("GoFigure had wrong intermediate values!",
        expectedIntermediate, calc.intermediate, tolerance);
  }
}

Обратите внимание на последние 2 проверки. Они использовали публичные данные в тестовом двойном экземпляре, который был введен в тестируемый класс. Я не мог сделать это с производственным кодом из-за данных скрывая принцип. Я не хотел, чтобы код специального назначения был вставлен в производственный код. Публичные данные должны быть в другом классе.

Двойной тест вводили. Это отличается от стратегии, поскольку она затрагивает данные, а не только функции.

Ответ 6

Включение зависимостей - это уточнение шаблона стратегии, которое я кратко объясню. Часто бывает необходимо выбирать между несколькими альтернативными модулями во время выполнения. Эти модули реализуют общий интерфейс, чтобы их можно было использовать взаимозаменяемо. Цель шаблона стратегии - снять бремя принятия решения о том, какой из модулей использовать (то есть, какая "конкретная стратегия" или зависимость) путем инкапсуляции процесса принятия решений в отдельный объект, который я буду называть объектом стратегии.

Инъекция зависимостей уточняет стратегический паттерн, не только решая, какую конкретную стратегию использовать, но создавая экземпляр конкретной стратегии и "вставляя" ее обратно в вызывающий модуль. Это полезно, даже если есть только одна зависимость, как знание того, как управлять (инициализировать и т.д.), Конкретный экземпляр стратегии также может быть скрыт внутри объекта стратегии.

Ответ 7

Фактически, инъекция зависимостей также очень похожа на шаблон моста. Для меня (и в соответствии с определением) шаблон Bridge предназначен для размещения различных версий реализации, а шаблон стратегии - для совершенно другой логики. Но пример кода выглядит так, как с помощью DI. Так что, возможно, DI - это просто техническая или реализация?

Ответ 8

Стратегия - это арена, чтобы использовать свои навыки инъекций зависимости. Реальные способы реализации инъекции зависимостей заключаются в следующем: -

  • События
  • Конфигурационные файлы единой/структурной карты (или программно) и т.д.
  • Методы расширения
  • Абстрактный шаблон Factory
  • Инверсия шаблона управления (используется как стратегией, так и абстрактным Factory)

Есть одна вещь, хотя стратегия стоит отдельно. Как вы знаете в Unity, когда приложение запускается, все зависимости установлены, и мы не можем его изменить дальше. Но стратегия поддерживает изменение зависимости от времени выполнения. Но мы должны управлять/внедрять зависимость, а не ответственность Стратегии!

На самом деле стратегия не говорит об инъекции зависимостей. При необходимости это можно сделать с помощью Abstract Factory внутри шаблона стратегии. Стратегия говорит только о создании семейства классов с интерфейсом и "игре" с ним. Во время игры, если мы находим, что классы находятся на другом уровне, тогда мы должны сами вводить это, но не выполнять Стратегию.