Я думаю, что ваш «новый способ» ошибочен, поскольку модель представления не должна создавать исключение, которое «каким-то образом» распространяется обратно в модель предметной области. Модель предметной области должна решить это сама.
Сети: как их смоделировать, используя агрегированные корни?
Ответы (2)
Итак, в этом случае (привязка 1 к 1) вы можете использовать события в модели предметной области, чтобы
NodeA.connect ("порт1") .to (NodeB) .on ("порт3");
NodeA резервирует «порт1» для себя.
NodeA отправляет «portConnectionRequest» в NodeB.
NodeB связывает «порт 3», если он доступен.
NodeB отправляет «portConnectionConfirmed» или «portConnectionDenied».
NodeA получает событие и действует соответственно.
Вышеупомянутое предполагает надежный обмен сообщениями, который легко достигается в JVM, но намного сложнее в распределенной среде, но именно там вам это нужно больше. Если надежная система обмена сообщениями не может быть предоставлена, я думаю, у вас возникнет проблема Византийского соглашения на рука или его часть.
Хорошо, я прочитал и подумал еще об этом, и я думаю, это "правильный" способ сделать это:
Теперь сделайте еще один шаг. Сети. Отношения "многие ко многим" между эквивалентными партнерами. Как вы можете смоделировать это, не нарушая границы транзакции в ваших совокупных корнях?
Взгляните на этот широко применимый пример:
У меня есть сеть с узлами. Каждый узел имеет ограниченное количество портов. Один порт может быть подключен только к одному порту на другом узле. Я должен иметь возможность добавлять и удалять соединения между узлами, используя порты.
Интуитивным подходом к этому было бы моделирование узлов как совокупных корней, содержащих порты. Соединения кажутся объектами значений, и один порт может иметь одно соединение. Я мог бы реализовать метод Node.ConnectTo (nodeId, portId), который добавляет соединение (между портом X на узле A и портом Y на узле B) в совокупный корень, узел A. Предпочтительно, я бы вызвал этот метод дважды, один раз на Узел A и один раз на узле B и заверните его в транзакцию. Однако это нарушит границу транзакции, поэтому я решил сохранить его только на узле A.
Чтобы увидеть соединение на узле B на клиенте приложения, потребуется отдельная модель чтения. Но это не проблема, архитектура CQRS предоставляет нам эти возможности. Таким образом, добавление, удаление и просмотр соединений не является проблемой.
Проблема возникает, когда я хочу проверить, свободен ли порт, прежде чем добавлять соединение к порту. Результатом соблюдения границ нашей транзакции является то, что (в модели записи) тот факт, что порт уже подключен, может быть неизвестен совокупному корню, но может быть сохранен в любом другом совокупном корне.
Конечно, вы могли бы доверяйте проверке вашего клиента, продолжайте и добавьте соединение, если это нормально для узла, к которому вы его добавляете, и полагайтесь на процесс, выполняющий проверки согласованности, для выполнения компенсирующих действий для недопустимых соединений. Но это кажется мне большим делом по сравнению с обертыванием транзакции вокруг двух вызовов ConnectTo ...
Это заставило меня подумать, что возможно, мои совокупные корни были выбраны неправильно. И я начал думать об узлах и сетях как о совокупных корнях, где сеть - это совокупность подключений. Преимущество агрегата сети в том, что вы всегда можете проверить добавление или удаление соединений. За исключением случаев, когда новое соединение приведет к объединению двух существующих сетей ... И ваша совокупность может стать большой, что может привести только к одной огромной сети. Это тоже неосуществимо.
Как вы думаете, как это следует смоделировать? Видите ли вы решение, в котором вы уважаете совокупные корни как границы транзакций, вы можете проверять свою сеть и не рискуете хранить всю свою сеть как единый агрегат? Или я прошу здесь все 3 CAP и разве это просто невозможно? - person Jochen; 02.06.2012
Перед выполнением метода ConnectTo на узле A вы проверяете, свободен ли порт на узле B, используя в конечном итоге согласованную модель представления в качестве источника данных (а не модель домена, которая не может эффективно проверить это, см. Выше).
- ConnectTo запускается только на узле A, поэтому границы транзакции не нарушаются.
- Если модель представления не может подключить порт на узле B, потому что он уже используется, произошло истинное исключение параллелизма, и о нем необходимо сообщить. Необходимо предпринять какие-то действия (либо вмешательство вручную, либо автоматический процесс). Вероятность этого исключения параллелизма обычно очень низкая.
- вам нужно сделать ваш вопрос более читаемым