Я не рассматриваю использование геттеров как шаг к анемичной модели.Или, по крайней мере, как и все в программировании, это зависит.
Недостатком анемичной модели является то, что каждый компонент, обращающийся к объекту, может мутировать его без какого-либо принудительного применения его инвариантов (открытие для возможной несогласованности в данных),это можно легко сделать с помощью методов установки.
(я буду использовать термины команда и запрос, чтобы указать методы, которые изменяют состояние объектов и методы, которые просто возвращают данные, ничего не меняя)
Точка наличия агрегата / объектадля принудительного применения инвариантов объекта, поэтому он предоставляет «командные» методы, которые не отражают внутреннюю структуру объекта, а вместо этого «ориентированы на домен» (используя «вездесущий язык» для именования), раскрывая его «поведение домена»(рекомендуется избегать именования get / set, потому что они являются стандартными именами для представления внутренней структуры объекта).
Это то, что касается методов set , а как насчет get ?
Поскольку методы набора могут рассматриваться как «команда» агрегата, вы можетевоспринимайте геттеры как методы «запроса», используемые для запроса данных к агрегату.Запрашивать данные для агрегата вполне нормально, если это не нарушает ответственность агрегата за соблюдение инвариантов.Это означает, что вы должны следить за тем, что возвращает метод запроса.
Если результатом метода запроса является значение объект, то есть неизменяемый, вполне нормально иметь его.Таким образом, кто запрашивает агрегат, он возвращает что-то, что может быть только прочитано.
Таким образом, у вас могут быть методы запроса, выполняющие вычисления с использованием внутреннего состояния объекта (например, метод int missingStudents()
, который вычисляет количество пропавших учеников дляLesson
сущность, которая имеет totalNumber
студентов и List<StudentId>
во внутреннем состоянии), или простые методы, такие как List<StudentId> presentStudent()
, которые просто возвращают список во внутреннем состоянии, но что отличается от List<StudentId> getStudents()
его простоимя).
Таким образом, если метод get возвращает что-то неизменное, использующее его, не может нарушить инварианты агрегата.
Если метод возвращает изменяемый объект, который является частью агрегатного состояния, любой, кто имеет доступобъект может запрашивать этот объект и теперь может изменять что-то, что остается внутри агрегата, не пропуская правильные методы команд, пропуская проверку инвариантов (если это не то, что нужно и управляется).
Другая возможность состоит в том, что объект создается намуха во время запроса и не является частью агрегатаУкажите, поэтому, если кто-то получит к нему доступ, а также, если он будет изменчивым, агрегат будет безопасным.В конце концов, методы get и set кажутся уродливыми, если вы экстремист DDD, но иногда они также могут быть полезны, будучи стандартным соглашением об именах, и некоторые библиотеки работают над этим соглашением об именах, поэтому я не вижу их плохими, если они не нарушают совокупные / юридические обязанности.
И, наконец, когда вы говорите В ситуации, когда мы хотим работать с несколькими сущностями, мы вводим Сервис. , это правда, но сервис также должен работать (изменять, сохранять)на одном агрегате, но это уже другая тема ?.