Не все так просто. ProcessType - это, скорее всего, объект уровня знаний - он определяет определенный процесс. С другой стороны, процесс - это экземпляр процесса, который называется ProcessType. Вероятно, вам действительно не нужны или не нужны двунаправленные отношения. Вероятно, процесс не является логическим потомком ProcessType. Обычно они принадлежат чему-то еще, например продукту, фабрике или последовательности.
Также по определению, когда вы удаляете совокупный корень, вы удаляете все члены совокупности. Когда вы удаляете процесс, я серьезно сомневаюсь, что вы действительно хотите удалить ProcessType. Если вы удалили ProcessType, вы, возможно, захотите удалить все процессы этого типа, но эта связь уже не идеальна, и есть вероятность, что вы не будете удалять объекты определения, как только у вас будет исторический процесс, который определяется ProcessType.
Я бы удалил коллекцию процессов из ProcessType и нашел более подходящего родителя, если он существует. Я бы оставил ProcessType членом Process, поскольку он, вероятно, определяет процесс. Объекты рабочего уровня (Process) и уровня знаний (ProcessType) редко работают как единый агрегат, поэтому я бы либо Process был агрегированным корнем, либо, возможно, нашел агрегированный корень, который является родительским для процесса. Тогда ProcessType будет внешним классом. Process.Type, скорее всего, избыточен, поскольку у вас уже есть Process.ProcessType. Просто избавься от этого.
У меня похожая модель в сфере здравоохранения. Есть процедура (операционный уровень) и ProcedureType (уровень знаний). ProcedureType - это отдельный класс. Процедура является потомком третьего объекта Encounter. Встреча - это совокупный корень для процедуры. У процедуры есть ссылка на ProcedureType, но это односторонний. Тип процедуры - это объект определения, он не содержит коллекции процедур.
ИЗМЕНИТЬ (потому что комментарии настолько ограничены)
Одна вещь, о которой нужно помнить при всем этом. Многие из них являются пуристами DDD и непреклонны в отношении правил. Однако, если вы внимательно прочитаете Эванса, он постоянно поднимает вероятность того, что часто требуются компромиссы. Он также очень подробно описывает логические и тщательно продуманные дизайнерские решения в сравнении с такими вещами, как команды, которые не понимают целей или обходят такие вещи, как агрегаты, ради удобства.
Важно понимать и применять концепции, а не правила. Я вижу много DDD, которые запихивают приложение в нелогичные и запутанные агрегаты и т. Д. Только потому, что применяется буквальное правило о репозиториях или обходе. брать.
Итак, каковы здесь ключевые концепции:
Агрегаты позволяют сделать сложную систему более управляемой, сводя поведение многих объектов к поведению ключевых игроков более высокого уровня.
Агрегаты предоставляют средства, гарантирующие, что объекты создаются в логическом и всегда допустимом состоянии, которое также сохраняет логическую единицу работы при обновлениях и удалениях.
Рассмотрим последний пункт. Во многих обычных приложениях кто-то создает набор объектов, которые не заполнены полностью, потому что им нужно только обновить или использовать несколько свойств. Приходит следующий разработчик, и ему тоже нужны эти объекты, и кто-то уже сделал где-то по соседству набор для другого назначения. Теперь этот разработчик решает просто использовать их, но затем обнаруживает, что у них нет всех необходимых ему свойств. Поэтому он добавляет еще один запрос и заполняет еще несколько свойств. В конце концов, потому что команда не придерживается ООП, потому что они придерживаются общей позиции, что ООП «неэффективно и непрактично для реального мира и вызывает проблемы с производительностью, такие как создание полных объектов для обновления одного свойства». В итоге они получают приложение, полное встроенного кода SQL и объектов, которые по существу случайным образом материализуются где угодно. Хуже того, эти объекты являются недействительными прокси-серверами. Процесс кажется процессом, но это не так, он частично заполняется различными способами в любой заданной точке в зависимости от того, что было необходимо. В итоге вы получаете множество запросов для постоянного частичного заполнения объектов в различной степени и часто много посторонней ерунды, например, нулевых проверок, которые не должны существовать, но требуются, потому что объект никогда не является действительным и т. Д.
Правила агрегирования предотвращают это, гарантируя, что объекты создаются только в определенных логических точках и всегда с полным набором допустимых отношений и условий. Итак, теперь, когда мы полностью понимаем, для чего нужны агрегированные правила и от чего они нас защищают, мы также хотим понять, что мы также не хотим злоупотреблять этими правилами и создавать странные агрегаты, которые не отражают то, что на самом деле представляет собой наше приложение, просто потому, что эти сводные правила существуют и должны соблюдаться всегда.
Поэтому, когда Эванс говорит создавать репозитории только для агрегатов, он говорит, что нужно создавать агрегаты в допустимом состоянии и сохранять их таким образом, вместо того, чтобы напрямую обходить агрегат для внутренних объектов. У вас есть процесс в качестве корневого агрегата, поэтому вы создаете репозиторий. ProcessType не является частью этого агрегата. Что вы делаете? Хорошо, если объект сам по себе и это сущность, это совокупность 1. Вы создаете для него репозиторий.
Теперь пуристы придут и скажут, что у вас не должно быть этого репозитория, потому что ProcessType - это объект значения, а не сущность. Следовательно, ProcessType вообще не является агрегатом, и поэтому вы не создаете для него репозиторий. Ну так что ты делаешь? Чего вы не делаете, так это втыкайте ProcessType в какую-то искусственную модель только по той причине, что вам нужно ее получить, поэтому вам нужен репозиторий, но чтобы иметь репозиторий, у вас должна быть сущность в качестве совокупного корня. Что вы делаете, так это внимательно рассматриваете концепции. Если кто-то говорит вам, что репозиторий неправильный, но вы знаете, что он вам нужен, и что бы они ни говорили, ваша система репозитория действительна и сохраняет ключевые концепции, вы сохраняете репозиторий как есть вместо того, чтобы искажать свою модель для удовлетворения догм.
Теперь в этом случае, если предположить, что я прав в отношении того, что такое ProcessType, как заметил другой комментатор, на самом деле это объект значения. Вы говорите, что это не может быть объект-значение. Это могло быть по нескольким причинам. Возможно, вы так говорите, потому что, например, используете NHibernate, но модель NHibernate для реализации объектов значений в той же таблице, что и другой объект, не работает. Таким образом, для вашего ProcessType требуется столбец и поле идентификации. Часто из соображений базы данных единственной практической реализацией является наличие объектов значений с идентификаторами в их собственной таблице. Или, может быть, вы так говорите, потому что каждый процесс указывает на один тип процесса по ссылке.
Не важно. Это объект-значение из-за концепции. Если у вас есть 10 объектов Process, которые имеют один и тот же ProcessType, у вас есть 10 членов и значений Process.ProcessType. Независимо от того, указывает ли каждый Process.ProcessType на одну ссылку или каждый получил копию, по определению все они должны быть в точности одинаковыми и полностью взаимозаменяемыми с любыми другими 10. ЭТО то, что делает его объектом значения. Человек, который говорит: «У него есть идентификатор, следовательно, он не может быть ценным объектом, который у вас есть», делает догматическую ошибку. Не делайте ту же ошибку, если вам нужно поле идентификатора, укажите его, но не говорите «это не может быть объект значения», когда на самом деле это тот, который по другой причине вам пришлось указать идентификатор к.
Так как же понять, что правильно, а что нет? ProcessType - это объект значения, но по какой-то причине у него должен быть идентификатор. Идентификатор сам по себе не нарушает правил. Вы понимаете это правильно, имея 10 процессов, каждый из которых имеет один и тот же ProcessType. Может быть, у каждого есть локальная глубокая копия, может быть, все они указывают на один объект. но все они идентичны в любом случае, например, каждый имеет Id = 2. Вы ошибаетесь, когда делаете это: каждый из 10 процессов имеет свой тип процесса, и этот тип процесса идентичен и полностью взаимозаменяем, ЗА ИСКЛЮЧЕНИЕМ теперь каждый также имеет свой собственный уникальный идентификатор. Теперь у вас есть 10 экземпляров одного и того же объекта, но они различаются только идентификатором и всегда будут отличаться только идентификатором. Теперь у вас больше нет объекта-значения не потому, что вы дали ему идентификатор, а потому, что вы дали ему идентификатор с реализацией, которая отражает природу сущности - каждый экземпляр уникален и отличается
Есть смысл?
person
Sisyphus
schedule
07.02.2011