C# 8 Реализация по умолчанию и инверсия зависимостей

В C#8 Microsoft представила реализацию по умолчанию для методов интерфейса. Это все еще довольно новая функция, и, похоже, об этом пишут многие обеспокоенные блоггеры.

Мне интересно, может ли реализация по умолчанию быть полезным инструментом для инверсии зависимостей и DI или способствует плохому стилю программирования? Нарушает ли это какой-либо из хорошо известных принципов, таких как SOLID?

1 ответ

Решение

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

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

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

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

  • Расширение интерфейсов без нарушения совместимости и необходимости версии интерфейсов.
  • Расширение классов без необходимости создавать жесткую древовидную иерархию, полученную в результате наследования классов.

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

Наконец, если вас беспокоят такие принципы, как SOLID, давайте попробуем:

  • SRP - Без реальных изменений, несколько новых вариантов неразрушающего добавления новой логики в одном месте. Я говорю, что это небольшая победа для SRP.
  • OCP - вы получаете новые мощные способы расширения классов без необходимости изменять сам класс, если этот класс реализует интерфейс, в котором новая функция имеет смысл. Но вы не можете изменить поведение существующих классов таким образом, поэтому они все еще закрыты для модификации. Здесь довольно полезная победа.
  • LSP - особо не повлиял. Некоторые незначительные победы, позволившие вам добавить новое замещаемое поведение к классу просто путем реализации интерфейса (с возможностью переопределения этого поведения по мере необходимости).
  • Интернет-провайдер - это может быть обе стороны. Реализации по умолчанию могут упростить наличие большого количества небольших интерфейсов, если у вас есть разумные реализации по умолчанию. Но они также могут побудить вас продолжать изменять существующие интерфейсы вместо добавления новых.
  • DIP - в основном не затронуты. Вам будет проще добавлять новые абстракции, если они являются разумным расширением того, что у вас уже есть, или если поведение по умолчанию может быть реализовано без зависимости от состояния. У вас также может возникнуть соблазн использовать поведение по умолчанию как договорное, но ИМО это все же меньше соблазна, чем в абстрактном методе (где вы также имеете контроль над состоянием).
Другие вопросы по тегам