Я искал несколько советов по разработке модели данных для администрирования контрактов. Таким образом, общий жизненный цикл контракта:
- Контракт создан и находится в «черновом» состоянии. Это доступно для внутреннего просмотра, и в него могут быть внесены изменения.
- Контракт отправляется продавцу, статус установлен как «в ожидании»
- Контракт отклонен продавцом. В этом состоянии ничего нельзя сделать с договором. В коллекцию нельзя добавлять статусы.
- Договор принят продавцом. В этом состоянии ничего нельзя сделать с договором. В коллекцию нельзя добавлять статусы.
Я, очевидно, хочу избежать ситуации, когда договор будет принят и, скажем, сумма будет изменена. Вот мои занятия:
[EnforceNoChangesAfterDraftState]
public class VendorContract
{
public virtual Vendor Vendor { get; set; }
public virtual decimal Amount { get; set; }
public virtual VendorContact VendorContact { get; set; }
public virtual string CreatedBy { get; set; }
public virtual DateTime CreatedOn { get; set; }
public virtual FileStore Contract { get; set; }
public virtual IList<VendorContractStatus> ContractStatus { get; set; }
}
[EnforceCorrectWorkflow]
public class VendorContractStatus
{
public virtual VendorContract VendorContract { get; set; }
public virtual FileStore ExecutedDocument { get; set; }
public virtual string Status { get; set; }
public virtual string Reason { get; set; }
public virtual string CreatedBy { get; set; }
public virtual DateTime CreatedOn { get; set; }
}
Я опустил класс файлового хранилища, который в основном является поиском по ключу / значению, чтобы найти документ на основе его guid.
VendorContractStatus отображается в Nhibernate как множество к одному.
Затем я использую пользовательский валидатор, как описано здесь . Если в коллекции VendorContractStatus возвращается что-то кроме черновика, изменения не допускаются. Кроме того, VendorContractStatus должен следовать правильному рабочему процессу (вы можете добавить отклоненное после ожидания, но вы не можете добавить что-либо еще в коллекцию, если отклонено или принято и т. Д.).
Все звучит хорошо? Что ж, коллега утверждал, что мы должны просто добавить свойство bool "IsDraft" в VendorContract и не принимать обновления, если IsDraft имеет значение false. Затем мы должны установить метод внутри VendorContractStatus для обновления статуса, если что-то добавляется после черновика, он устанавливает для свойства IsDraft VendorContract значение false.
Мне это не нравится, так как мне кажется, что я загрязняю POCO и добавляю логику, которая должна сохраняться в области проверки, что в этих классах не должно быть никаких правил, и они не должны знать о своих состояниях.
Есть какие-нибудь мысли по этому поводу и что является лучшей практикой с точки зрения DDD?
С моей точки зрения, если в будущем нам понадобятся более сложные правила, мой путь будет более понятным в долгосрочной перспективе. Скажем, у нас есть контракты на определенную сумму, которые должны быть одобрены менеджером. Я думаю, что было бы лучше иметь сопоставление один-к-одному с классом VendorContractApproval, а не добавлять свойства IsApproved, но это всего лишь предположение.
Это может быть раскалывание волос, но это первый настоящий грандиозный проект корпоративного программного обеспечения, который мы сделали. Любой совет будет оценен!