От ООП в стиле Java к более… чувству TypeScripty?
Разделение кода, устранение неявных зависимостей, обеспечение тестируемости - все это прекрасно, и внедрение зависимостей является шаблоном для этого. Однако традиционный подход DI с экземплярами классов, использующими интерфейсы для других экземпляров класса, тоже ... Java? ООП? Предприимчивый? Разве мы можем избавиться от слишком сложных структур и сделать вместо этого что-нибудь попроще?
Проблема
Давайте определим набор интерфейсов, службу, некоторые объекты доступа к данным (DAO) и небольшой пример использования (в тестовом коде). Предположим, у нас уже определены некоторые типы User и Org (анизация). А пока мы делаем это скучным.
Нет ничего плохого в написании кода, подобного приведенному выше, это полностью рабочий шаблон, который хорошо масштабируется. Однако у меня есть некоторые проблемы с этим.
- Классы подразумевают изменяемое состояние. Или, по крайней мере, потенциал для этого. Это хорошая привычка - немного пугаться, когда вы идете на занятия. Если необходимо неизменяемое состояние, зачем его использовать?
- Многословие, шаблон. Очевидно, это дело вкуса, но я чувствую, что мы могли бы сделать все немного более лаконичным.
- Интерфейсы подразумевают наследование или объединение деклараций. Или, по крайней мере, в потенциале для них. Почему бы вместо этого не использовать
type
? Это похоже на более ограниченную вещь, что мне нравится. Если вам абсолютно необходимо использовать интерфейс, просто переверните его при необходимости.
Экономичный подход
Тот же код: DAO, Сервис, пример использования. Но все немного более ограничено, короче, и мы больше играем с функциями и объектными литералами. Посмотрим, как это пойдет:
Так что же происходит?
- Использует
type
через интерфейс. Он немного строже, что для меня хорошо. - Служба теперь закрытие, а не класс. Функция возвращает литерал объекта. Нет возможности для скрытого изменяемого состояния, и, откровенно говоря, это намного проще и, возможно, даже проще для глаз.
- У DAO больше нет интерфейса. Небольшая ошибка. DAO или, возможно, они должны быть коннекторами или клиентами API / БД, даже могут быть совершенно разными в зависимости от того, что именно они делают.
- Реализации тестов - это просто литералы объектов. Неужели им действительно нужно быть чем-то большим?
- Все кажется немного больше TypeScript. А современный? Это дело вкуса, дайте мне знать, что вы думаете.
Вывод
Совершенно очевидно, что я предпочитаю один стиль другому. Но я считаю, что пытался обосновать свою позицию хорошими аргументами. Также хорошо отметить, что различия здесь связаны не столько с внедрением зависимостей, сколько с TypeScript в целом. Я склонен полагать, что часто лучше заменить объектно-ориентированные структуры на основе классов / экземпляров функциями и записями (мне нравится думать об объектных литералах как о записях, а не о синглетонах).
Попробуйте разные подходы и посмотрите, с чем вы предпочитаете работать и на что смотреть.