Единственная ответственность (причина изменения) организации должна заключаться в том, чтобы однозначно идентифицировать себя, иными словами, ее ответственность должна быть обнаруживаемой.
DDD книга Эрика Эвана, стр. 93:
основная ответственность Сущностей заключается в установлении преемственности, с тем чтобы поведение могло быть четким и предсказуемым. Они делают это лучше всего, если их держать запасными. Вместо того, чтобы фокусироваться на атрибутах или даже поведении, разделите определение объекта Entity до наиболее внутренних характеристик, особенно тех, которые его идентифицируют или обычно используются для его нахождения или сопоставления. Добавьте только поведение, которое необходимо для концепции и атрибутов, которые требуются для этого поведения.
Помимо этого, обратите внимание на удаление поведения и атрибутов в другие объекты, связанные с основной сущностью Entity. Помимо проблем идентификации, сущности стремятся выполнять свои обязанности, координируя операции объектов, которыми они владеют.
1.
... обрезать определение объекта ENTITY до самых внутренних характеристик, особенно тех, которые его идентифицируют или обычно используются для его нахождения или сопоставления. Добавьте только поведение, которое необходимо для концепции ...
Как только объекту присваивается уникальный идентификатор , его личность устанавливается, и поэтому я предполагаю, что такому объекту не нужно какое-либо поведение, чтобы поддерживать свою идентичность или помогать ему идентифицировать себя . Таким образом, я не понимаю , что такое поведение является автор со ссылкой на (помимо find
и match
операции ) с « поведением , что имеет существенное значение для концепции »?
2.
... обрезать определение объекта ENTITY до самых внутренних характеристик, особенно тех, которые его идентифицируют или обычно используются для его нахождения или сопоставления. ... Помимо этого, обратите внимание на удаление поведения и атрибутов в другие объекты, связанные с ядром ENTITY.
Таким образом, любое поведение, которое не помогает идентифицировать сущность, но мы все равно охарактеризовали бы это поведение как внутреннюю характеристику этой сущности (то есть лай присущ собакам, полет присущ самолетам, откладка яиц присущ птицам). .), должны ли быть помещены в другие объекты, связанные с этой сущностью (пример: мы должны поместить поведение лая в объект, связанный с сущностью собаки)?
3.
Помимо этого, посмотрите, чтобы удалить поведение и атрибуты в другие объекты, связанные с ядром ENTITY.
а) MyEntity
делегирует обязанности A_resp
и B_resp
объектам a
и b
, соответственно.
Хотя большинство A_resp
и B_resp
работа выполняется , a
и b
случаи, клиенты по - прежнему служили A_resp
и B_resp
через MyEntity
, что означает , что с точки зрения клиента две обязанности принадлежат MyEntity
. Таким образом, разве это не означает, что MyEntity
также имеет A_resp
и B_resp
обязанности и как таковое нарушает SRP ?
б) Даже если мы предположим, что A_resp
и B_resp
не принадлежим MyEntity
, по- MyEntity
прежнему несет ответственность AB_resp
за координацию операций объектов a
и b
. Так что не MyEntity
нарушает ли SRP, поскольку как минимум у него есть две обязанности - однозначно идентифицировать себя, а также AB_resp
?
class MyEntity
{
private A a = ...
private B b = ...
public A GetA()
{ ... }
public B GetB()
{ ... }
/* coordinates operations of objects a and b */
public int AworkB()
{ ... }
}
/* A encapsulates a single responsibility resp_A*/
/* A is value object */
class A
{ ... }
/* B encapsulates a single responsibility resp_B*/
/* B is value object */
class B
{ ... }
ОБНОВИТЬ:
1.
Поведение в этом контексте относится к семантическому поведению. Например, свойство класса (т. Е. Атрибут объекта домена), которое используется для однозначной идентификации, имеет поведение. Пока это не представлено в коде напрямую. Ожидаемое поведение заключается в том, что для этого свойства не будет повторяющихся значений.
Таким образом, в коде нам практически никогда не потребуется реализовывать поведение (т. Е. Операцию), которое каким-то образом будет поддерживать идентичность объекта, поскольку, как вы объяснили, такое поведение существует только как концепция в модели предметной области (в форме атрибута ID объект), но когда мы переводим этот атрибут ID в код, часть его семантики теряется (т. е. часть, которая неявным образом обеспечивает уникальность значения идентификатора, теряется)?
2.
Кроме того, такое свойство, как Age, не имеет контекста вне Entity Entity, и, как таковое, не имеет смысла перемещаться в другой объект ... Однако эта информация может легко храниться в отдельном месте, в котором находится уникальный идентификатор, следовательно, запутанная ссылка на поведение. Возраст может быть лениво загруженным значением.
а) Если Age
свойство загружено с отложенной загрузкой, то мы можем назвать его поведением, даже если семантически Age
это просто атрибут?
3.
Вы могли бы легко иметь операции, специфичные для Адреса, такие как проверка того, что это действительный адрес. Вы можете не знать об этом во время разработки, но вся эта концепция состоит в том, чтобы разбивать объекты на их мельчайшие части.
Хотя я согласен, что мы потеряли бы контекст, перейдя Age
в другой объект, контекст не был бы потерян, если бы мы переместили DateOfBirth
свойство в другой объект, но мы обычно не перемещаем его.
Какова основная причина, по которой мы бы переместились Address
в другой объект, но нет DateOfBirth
? Потому что DateOfBirth
это более присуще Person
сущности или потому что есть меньше шансов, что где-то в будущем нам может понадобиться определить операции, специфичные для DateOfBirth
?
4. Я должен сказать , что я до сих пор не знаю, MyEntity
есть также A_resp
и B_resp
обязанности и почему MyEntity
же то , AB_resp
не считается нарушением SRP
EULERFX
1)
Поведения, на которые ссылается автор, - это поведения, связанные с сущностью. Это поведения, которые изменяют состояние объекта
а) Если я вас правильно понимаю, вы говорите, что сущность должна содержать только те поведения, которые изменяют ее атрибуты (то есть ее состояние )?
б) А как насчет поведения, которое не обязательно изменяет состояние объекта , но все же рассматривается как внутренняя характеристика этого объекта (пример: лай будет внутренней характеристикой Dog
объекта, даже если он не изменяет его) Собачье состояние )? Должны ли мы включить эти поведения в объект или они должны быть перемещены в другие объекты?
2)
Что касается перемещения поведения к другим объектам, автор имеет в виду конкретно объекты значения.
Хотя моя цитата не включает его, но автор упоминает в том же абзаце, что в некоторых случаях поведение (и атрибуты ) также будут перемещены в другие сущности (хотя я понимаю преимущества переноса поведения в ВО)
3) Если предположить MyEntity
(см вопрос 3. в моей должности) не нарушает SRP, бы мы говорим , что ответственность в MyEntity
это помимо всего прочего , также состоящих из:
а. A_resp
+ B_resp
+ AB_resp
( AB_resp
координаты объектов a
и b
)
или
б. AB_resp
+ делегирование A_resp
и B_resp
объектам ( a
и b
) связанным с MyEntity
?
4) DDD книга Эрика Эвана, стр. 94:
CustomerID - это единственный идентификатор Клиента ENTITY (рисунок 5.5), но номер телефона и адрес часто используются для поиска или сопоставления Клиента. Имя не определяет личность человека, но оно часто используется как часть средств его определения.
В этом примере атрибуты телефона и адреса перенесены в Customer, но в реальном проекте этот выбор будет зависеть от того, как клиенты домена обычно сопоставляются или различаются. Например, если у клиента много контактных телефонных номеров для разных целей, тогда этот номер телефона не связан с идентификационной информацией и должен оставаться в контакте с отделом продаж.
а)
CustomerID - это единственный идентификатор Клиента ENTITY (рисунок 5.5), но номер телефона и адрес часто используются для поиска или сопоставления Клиента. Имя не определяет личность человека, но оно часто используется как часть средств его определения.
Quote состояния , что только атрибуты , связанные с идентичностью должны оставаться в сущности . Я предполагаю, что автор означает, что сущность должна содержать только те атрибуты , которые часто используются для поиска или сопоставления этой сущности , тогда как ВСЕ другие атрибуты должны быть перемещены?
б) Но как / куда следует перемещать другие атрибуты ? Например (здесь предполагается, что атрибут address не используется для поиска или сопоставления, Customer
и поэтому мы хотим вывести атрибут адреса из Customer
):
если вместо того, чтобы Customer.Address
(типа string
) мы создали свойство Customer.Address
типа Address
, мы перенесли бы атрибут адреса в связанный объект VO (который имеет тип Address
) или мы бы сказали, что он Customer
все еще содержит атрибут адреса ?
с)
В этом примере атрибуты телефона и адреса перенесены в Customer, но в реальном проекте этот выбор будет зависеть от того, как клиенты домена обычно сопоставляются или различаются. Например, если у клиента много контактных телефонных номеров для разных целей, тогда этот номер телефона не связан с идентификационной информацией и должен оставаться в контакте с отделом продаж.
Не автор в неправильном здесь, так как если мы предположим , каждый из многочисленных контактных телефонов , которые Customer
имеют только принадлежу к этому частности Customer
, то я бы сказал , что эти телефонные номера связаны с идентичностью так же , как тогда , когда Customer
был только один номер телефона ?
5)
Причина, по которой автор предлагает сократить сущность, заключается в том, что при первоначальном создании сущности «Клиент» существует тенденция к заполнению ее любым атрибутом, который можно представить связанным с покупателем. Это ориентированный на данные подход, который игнорирует поведение, в конечном итоге приводящее к модели анемичной области.
По теме, но я думал , что анемия модели предметной области результатов от перемещения поведения из - за сущности , в то время как ваш пример заполнением в объект с большим количеством атрибутов , которые привели бы Customer
иметь слишком много поведения (так как мы, вероятно , также включаем в Customer
тех поведениях , которые изменить эти дополнительные атрибуты ) и, следовательно, в нарушение SRP?
Благодарность
Ответы:
Поведение в этом контексте относится к семантическому поведению. Например, свойство класса (т. Е. Атрибут объекта домена), которое используется для однозначной идентификации, имеет поведение. Пока это не представлено в коде напрямую. Ожидаемое поведение заключается в том, что для этого свойства не будет повторяющихся значений. Нечто, такое как Адрес, которое может иметь свою собственную идентичность, но не существует вне контекста сущности «Человек», все равно должно быть перемещено в его собственный объект. Таким образом, продвижение сущности в совокупный корень.
Кроме того, такое свойство, как Age, не имеет контекста вне сущности Person и, как таковое, не имеет смысла перемещаться в другой объект. Контекст будет потерян, и, следовательно, вы можете с уверенностью определить, что это значение, которое необходимо для сущности человека. В противном случае вы не можете найти значение. Однако эта информация может быть легко сохранена в отдельном месте, что уникальный идентификатор, отсюда и запутанная ссылка на поведение . Возраст может быть лениво загруженным значением.
Итак, чтобы ответить на ваш вопрос. Нет, это не нарушает принцип единой ответственности. Я просто заявляю, что у Человека должен быть только личный материал, а не что-то вроде Адреса, более сложное и связанное с человеком, должно существовать как его собственная сущность.
Вы могли бы легко иметь операции, специфичные для Адреса, такие как проверка того, что это действительный адрес. Вы можете не знать об этом во время разработки, но вся эта концепция состоит в том, чтобы разбить объекты на их мельчайшие части, чтобы что-то подобное было относительно простым, если это сделано после факта.
Обновление: 1) В большинстве случаев проверка личности выполняется после сохранения объекта в хранилище данных. Это означает, что код, представляющий проверку сущности, существует, но существует в другом месте. Обычно он существует с кодом, который отвечает за выдачу значения идентификатора. Вот почему я утверждаю, что уникальность не представлена непосредственно в коде для сущности.
2) Правильное утверждение было бы, что
Age
это атрибут, который имеет поведение. Вам нужно будет задокументировать тот факт, что Age загружен с отложенной загрузкой, чтобы разработчик, использующий это свойство, мог принять точное решение о том, как использовать это свойство.3)
DateOfBirth
обычно это другой объект; Объект даты, который уже имеет предопределенные операции над ним. В некоторых языках для объекта date уже определена целая модель домена. Например, в c # вы можете указать часовой пояс, если дата UTC, добавить и вычесть даты, чтобы получить временной интервал. Так что ваше предположение о переездеDateOfBirth
было бы правильным.4) Если единственное, что
MyEntity
делает, это делегирование и согласование, то нет, это не нарушает ПСП. Его сингл ответственности делегировать и координировать и будет обозначаться как на фасаде рисунокисточник
Очень хороший вопрос SRP не следует воспринимать так буквально. Идентификация / поиск не является обязанностью организации в отношении SRP. Кто-то другой отвечает за присвоение ему идентификатора (а именно магазина) и за его поиск (а именно хранилища ).
Основная цель объекта состоит в представлении концепций, раскрытых моделью. Единственная разница между сущностью и объектом значения заключается в том, что сущность имеет значение за пределами своих неидентифицирующих атрибутов. Например, если человек меняет свое имя, он все тот же человек, просто с другим именем.
источник
Если идентичность установлена, тогда да, объекту больше ничего не нужно идентифицировать. Поведения, на которые ссылается автор, - это поведения, связанные с сущностью. Это поведения, которые изменяют состояние объекта. Например,
Customer
сущность может иметьMakePreferred
поведение. Причина, по которой автор предлагает сократить сущность, заключается в том, что когда изначально создаетсяCustomer
сущность, существует тенденция заполнять ее любым атрибутом, который можно представить связанным с клиентом. Это ориентированный на данные подход, который игнорирует поведение, в конечном итоге приводящее к модели анемичной области.Что касается перемещения поведения к другим объектам, автор имеет в виду конкретно объекты значения. Причина, по которой стоит перенести поведение в виртуальные организации, заключается в том, что виртуальные сервисы, как правило, «меньше», чем объекты, и поэтому более сфокусированы. Более того, такие аспекты, как неизменность и закрытие операций, упрощают рассуждения о коде, а также делают его более твердым .
Вместе с ВО объект является своего рода якорем, который координирует различные ВО, которые реализуют его поведение.
Что касается SRP, ваша путаница не является необоснованной. Одной из проблем со стереотипным ООП-реализацией сущностей является соотношение идентичности и состояния. Действительно, с поведенческой точки зрения личность не имеет ничего общего с поведением. Другими словами, идентичность сущности не требуется ни для одного из ее поведений. Существуют реализации, где устраняется эта путаница, например, AggregateSource или функциональный подход, который я описываю здесь .
Другая проблема заключается в том, что в некоторой степени SRP может быть качественной мерой. Любой может придумать определение единственной ответственности, которую нарушает какой-то класс. Можно сказать, что ответственность субъекта заключается в реализации поведения, требуемого от этого субъекта. В этом смысле он несет единственную ответственность. Кроме того, когда объект делегирует поведение составляющим ВО, это не нарушает SRP. SRP не запрещает состав такого рода. Он предостерегает от необходимости сводить связь между объектами до абсолютного минимума, поддерживать интерфейс как можно более чистым и т. Д.
ОБНОВИТЬ
Да, хотя есть исключения ...
Для сущностей допустимо содержать фабричные методы для создания экземпляров сущностей, которые фактически являются дочерними сущностями, но там, где ссылки на объекты не используются для обхода. В этом случае дочерняя сущность должна сохраняться службой приложений. Служба приложений использует родительский объект для создания дочернего объекта.
Вы смотрите на ответственность с точки зрения реализации. Вместо этого рассмотрите сущность как своего рода черный ящик с обязанностями. То, как он справляется с этим, не представляет интереса для вас, как человека, смотрящего со стороны. Распределение обязанностей между ВО или даже другими организациями является проблемой реализации.
Более конкретно, атрибуты, которые не требуются ни для поведения, ни для поиска, не должны быть частью сущности. Зачем беспокоиться? Более того, с чем-то вроде шаблона чтения-модели , сущностям не нужно ничего, кроме атрибутов, необходимых для поведения.
Да, по сути, нет разницы между строковым адресом или адресом VO-адреса.
Я не на 100% намерен автором, но я думаю, что он просто описывает, как требования к поиску сущностей могут изменить то, как сущность и ее соответствующие виртуальные организации являются структурами.
Много атрибутов не подразумевает много поведения. На самом деле это обычно говорит об обратном. Много атрибутов с геттерами и сеттерами, но без инкапсулирующего поведения.
источник
TL; DR: ты слишком обдумал это. Тем не менее, мне было весело думать об этом вместе с вами. Так пристегнуться ....
Нет, это не правильно. Единственная ответственность организации - преемственность.
Идентичность является новым следствием преемственности. Моделирование идентичности как отдельной идеи - это оптимизация производительности.
Вот пример: патрон ресторана дает машину камердинеру. Через час патрон ресторана просит машину. Должен ли камердинер дать это?
Легко сказать, что камердинер должен отдать машину, если покровитель «тот же». Но что это на самом деле означает? Правильный способ определить это - начать с «теперь» патрона и поискать в истории этого патрона задом наперед, чтобы увидеть, является ли передача автомобиля камердинеру частью этой истории.
Конечно, мы не можем этого сделать. У нас есть проблемы с отслеживанием нашей собственной истории точно, не говоря уже об истории чего-то, что не было с нами все время. Таким образом, вместо использования истории покровителя, мы берем короткие пути. Есть ли у патрона заглушка билета с тем же номером, что и у тега, привязанного в настоящее время к ключам? Соответствует ли водительское удостоверение в кошельке патрона имени, указанному в названии на DMV, изображение на водительских правах напоминает лицо патрона. И т.п.
Вкратце: вместо проверки истории посетителя мы проверяем текущее состояние посетителя, чтобы увидеть, соответствует ли текущее состояние истории, которая охватывает период между прибытием автомобиля и запросом на его возврат.
При моделировании сущностей мы используем аналогичную оптимизацию. Мы даем всем организациям общую ответственность
Я не описываю здесь вторую ответственность организации; Сущность по-прежнему отвечает за преемственность - следит за тем, чтобы история была последовательным повествованием. Обязанности идентификатора - это просто подмножество, общее для всех объектов.
У нас пока нет принудительного применения уникальности. Это невозможно в пределах одной сущности, потому что уникальность требует доступа к состоянию всех сущностей; где один объект имеет доступ только к своему.
Еще раз, проверка всех идентификаторов каждый раз не практична, поэтому вместо этого мы удовлетворяем уникальность простым способом: код, который генерирует следующий идентификатор, никогда не должен повторяться.
В конце концов, это означает, что мы можем проверить непрерывность, протестировав эквивалентность двух разных частей состояния в памяти, сэкономив много времени при попытке запроса ациклических графов.
Вы также, кажется, перепутали Принцип Единой Ответственности (который является действительно хорошей идеей) с принципом атомарной ответственности. Разложение ответственности на более мелкие, более легко управляемые части совместимо с SRP.
источник
Ну, это зависит от того, как вы хотите посмотреть на это.
Другой способ: «Является ли принцип единой ответственности нарушением сущности домена?»
Оба являются руководящими принципами. В разработке программного обеспечения нет «принципа». Однако есть хорошие дизайны и плохие дизайны. Обе эти концепции могут быть использованы по-разному, чтобы добиться хорошего дизайна.
источник