Как разработать модель данных, которая имеет дело с (реальными) контрактами? - PullRequest
2 голосов
/ 30 марта 2010

Я искал несколько советов по разработке модели данных для администрирования контрактов. Таким образом, общий жизненный цикл контракта:

  • Контракт создан и находится в «черновом» состоянии. Это доступно для внутреннего просмотра, и в него могут быть внесены изменения.
  • Контракт отправляется продавцу, статус установлен как «в ожидании»
  • Контракт отклонен продавцом. В этом состоянии ничего нельзя сделать с договором. В коллекцию нельзя добавлять статусы.
  • Договор принят продавцом. В этом состоянии ничего нельзя сделать с договором. В коллекцию нельзя добавлять статусы.

Я, очевидно, хочу избежать ситуации, когда договор будет принят и, скажем, сумма будет изменена. Вот мои занятия:

[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, но это всего лишь предположение.

Это может быть раскалывание волос, но это первый настоящий грандиозный проект корпоративного программного обеспечения, который мы сделали. Любой совет будет оценен!

Ответы [ 3 ]

1 голос
/ 13 марта 2012

Две вещи для рассмотрения;

1) Вы действительно хотите использовать одну и ту же объектную модель для запроса контракта и действующего контракта. Разве к ним не применяются другие варианты использования?

2) Если вы хотите использовать один и тот же объект, это может быть хорошим вариантом, чтобы использовать шаблон состояния для управления действиями, действительными для текущего состояния.

0 голосов
/ 13 марта 2012

Не. Напишите тесты, описывающие поведение, которое вам нужно. Модель данных выполняется, когда вы написали тест для всех ваших вариантов использования (и подвергались рефакторингу).

0 голосов
/ 30 марта 2010

Тот факт, что правила не применяются до тех пор, пока вызывающие не попытаются сохранить экземпляр VendorContract, вероятно, повышает вероятность ошибок и затрудняет использование этих классов, поскольку они не описывают свое собственное поведение или ограничения.

Иными словами, сосредоточив внимание на одной функции: отклоненные и принятые контракты не должны даже иметь установленный метод доступа для Amount.

Звучит так, что вы, возможно, движетесь к модели анемичной области (иногда известной под наименовательным наименованием ' постоянная модель ') где ваши доменные объекты - это просто контейнеры без бизнес-логики. Это не всегда плохо , но в системах с большим количеством бизнес-логики такой стиль рискует дублировать код и распространять правила на слишком много объектов, что делает его чрезвычайно трудным для понимания (и поддерживать и изменять) правила, регулирующие сущности вашего домена.

...