.NET Разработчик
6.56K subscribers
443 photos
4 videos
14 files
2.13K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День 1127. #DDD
Раскрытие Реализации в Именах Классов
Эта тема возникла в ответ на вопрос о паттерне CQRS, но он в равной степени применима и к другим паттернам. Вопрос:
Почему DatabaseRetryDecorator раскрывает свою структуру и детали реализации в имени класса? Что, если я изменю реализацию и заменю декоратор чем-то другим? Придется ли мне переименовывать его только потому, что я изменил его реализацию?

Просто для контекста, декораторы — это классы, которые позволяют вам вводить сквозную функциональность в вашем приложении.

Вот пример использования декоратора для повторных попыток при обращении к базе данных:
[DatabaseRetry]
public class EditPersonalInfoCommandHandler :
ICommandHandler<EditPersonalInfoCommand>
{
public Result Handle(EditPersonalInfoCommand command)
{
/* Изменяем данные клиента */
}
}

Приведенный выше атрибут DatabaseRetryAttribute соединяет обработчик команд с DatabaseRetryDecorator. Если обработчик команды выдаёт исключение базы данных, декоратор повторно его запускает (как вариант, через некоторое время). Идея аналогична тому, как промежуточное ПО работает в ASP.NET.

Действительно, почему вы должны называть класс DatabaseRetryDecorator, а не просто DatabaseRetry? Тот же аргумент можно применить и к другим классам, например, CustomerRepository, CustomerFactory или даже к EditPersonalInfoCommandHandler. Так ли им нужно указывать на паттерны, которые они реализуют, в своих именах (репозиторий, фабрика и обработчик команд)?

Здесь есть 2 совета.
1. Никогда не используйте имена паттернов при именовании классов на уровне предметной области (Domain layer). Вы должны использовать только термины из общего языка. Так что, не CustomerEntity или CustomerAggregate, а просто Customer.

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

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

Самый распространенный пример нарушения YAGNI — вызов репозитория CustomerSqlRepository. Если вы не используете несколько парадигм хранения, таких как SQL и NoSQL, нет необходимости указывать, что ваш репозиторий работает поверх базы данных SQL.

Источник: https://khorikov.org/posts/2021-08-16-exposing-implementation-details-in-class-names/
👍9
День 1133. #DDD
Коллекции и Одержимость Примитивными Типами. Начало
Одержимость примитивными типами (Primitive Obsession) — это антипаттерн, который заключается в чрезмерном использовании примитивных типов, особенно для моделирования предметной области.

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

Обычно одержимость примитивными типами проявляется в использовании строк, целых чисел и других простых типов. Распространённые примеры:
- Использование строки для представления адресов электронной почты. Специально созданный объект-значение Email был бы здесь намного лучше.
- Использование double для моделирования концепции денег вместо введения объекта-значения Money.

Конечно, не все концепции в вашей предметной области должны быть представлены как объекты-значения, необходимо провести некоторый анализ, чтобы выяснить, стоит ли создавать новый объект-значение. Но недостаточное использование объектов-значений — гораздо более серьёзная проблема, чем чрезмерное их использование.

Но зачем нам вообще нужны объекты-значения?
Дело в инкапсуляции. Она предназначена для защиты данных от перехода в недопустимое состояние. Гораздо сложнее защитить от этого строку, чем специально созданный класс со всеми необходимыми встроенными проверками.

Действительная строка может быть или не быть действительным адресом электронной почты; концепция строки слишком широка и сама по себе не может учитывать правила валидности электронного адреса.

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

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

Окончание следует…

Источник:
https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
👍16