Суть паттерна заключается в том, что ответственность выполнения операций должна быть назначена тому типу, который владеет максимумом необходимой информации - информационному эксперту.
Эксперт - бывший перт
public class Customer
{
private readonly List<Order> _orders;
// ...
public decimal TotalCost => _orders.Sum(x => x.Cost);
}
Паттерн подразумевает то, что логика обработки и изменения информации, хранимой объектом, должна содержаться в самом типе объекта. В сложных системах, может быть множество методов обработки данных, хранимых объектом, что может привести к разрастанию типов. Проблема заключается в том, что главная функция типов - стейт менеджмент, и слепое следование такому подходу - приведёт к тому, что большая часть типа будет забита всевозможными кверями к его атрибутам, нежели определением поведений которыми тип характеризуется.
Проблему разрастающихся классов можно решать добавлением доменных сервисов, инкапсулирующих логику обработки данных объекта. Объект, соответсвенно должен предоставлять доступ к данным, нужным для выполнения этих операций, поддерживая сокрытие, т.е. в read-only виде. Вышесказанное не означает, что типы должны инкапсулировать только логику стейт-менеджмента, вполне валидно иметь свойства, которые вычисляют что-либо основываясь на хранимых атрибутах, в случаях, когда эти свойства можно считать за атрибуты типа.
В языке C# можно реализовывать такой функционал без использования доменных сервисов. Учитывая, что речь идёт о логике, которая может быть помещена напрямую в сущности, не подразумевающей использование внешних зависимостей, а только атрибутов и свойств сущности, эти методы обработки данных могут быть вынесены в методы расширений. Такой подход даже более предпочтителен, так как внедрение в систему доменных сервисов подразумевает добавление абстракции, получение из DI, ну и группировка этой логики по типу объекта, данные которого обрабатываются. Доменный сервис приведёт к тому, что у нас в конечном итоге появится один большой класс, предполагая, что логики обработки данных сущности много, тогда как методами расширений можно достичь независимости логики друг от друга и более удобного API.
Создатель - объект, создающий другие объекты. Паттерн определяет правила, которым должны следовать объекты, обладающие характеристикой создателя.