Дизайн, управляемый доменом - мне сложно найти решение для такой бизнес-логики - PullRequest
2 голосов
/ 14 февраля 2012

Введение

Допустим, у меня есть три объекта домена:

Proposition
Phase
Task

Предложение может иметь одну или несколько фаз. Фаза может иметь одну или несколько задач.

Если я выполнил последнее задание на последнем этапе, предложение должно быть установлено на «Закрыто».

В коде я создал что-то вроде этого, чтобы завершить последнюю задачу фазы

//My Business Layer does this:
--------------------------------------
pseudo:
var phase = _phaseRepository.GetById(id);
phase.LastTask.SetComplete();


// My Domain Entities look like this:
------------------------
public class phase()
{
   public Task LastTask { get; set; } // not real code of course
}

public class Task()
{
   public Phase Phase { get; set; }

   public void SetComplete()
   {
      Phase.IsFinished = true;
   }
}

Вопрос

Куда мне поместить код для установки предложения в «Закрыто»?

Опции

Я думаю, есть несколько вариантов:

1) В доменном объекте: Task.SetComplete

public class Task()
{
   public Phase Phase { get; set; }

   public void SetComplete()
   {
      Phase.IsFinished = true;
      Phase.Proposition.IsClosed = true;
   }
}

2a) На бизнес-уровне

var phase = _phaseRepository.GetById(id);
phase.LastTask.SetComplete();

var proposition = _propositionRepository.GetById(phase.PropositionId);
proposition.IsClosed = true;

2b) На бизнес-уровне, может быть, немного приятнее:

var phase = _phaseRepository.GetByIdIncludingProposition(id);
phase.LastTask.SetComplete();
phase.proposition.SetClosed();

3) Пусть все пройдет через предложение:

//My Business Layer:
var proposition = _propositionRepository.GetById(id);
proposition.CompleteTask(taskId);

// Domain Object:
public class Proposition()
{
   public List<Phase> Phases { get; set; }

   public void CompleteTask(long taskId)
   {
      var task = // psuedo: select relevant task from Phases.Tasks, using taskid
      task.SetComplete();
      task.Phase.SetFinished();

      //psuedo: if task.Phase is last phase in proposition
      Phase.Proposition.IsClosed = true;
   }
}

Об опциях

Вариант 1 проблематичен на линии

Phase.Proposition.IsClosed = true;

потому что предложение не нужно загружать, а если оно не загружено, мы получаем исключение.

Опция 2a проблематична, потому что после выполнения phase.LastTask.SetComplete () предложение не находится в правильном состоянии. И везде в коде, где есть доступ к Phase, «phase.LastTask.SetComplete ()» может выполняться без выполнения соответствующих операций в предложении.

Опция 2b имеет ту же проблему, что и 2a.

Вариант 3 наделяет класс Предложения слишком большой ответственностью.

У вас, ребята, есть предложения?

1 Ответ

1 голос
/ 15 февраля 2012

Я предполагаю, что Proposition - это совокупный корень. В конце концов, задача является частью предложения, и я думаю, что Tssk должен уведомить о завершении, я бы попробовал этот подход (в основном вариант 3 немного изменен)

public class Proposition()
{
  public Task GetTask(int taskId)
  {
      //find and return task
  } 
}

//in business layer 
var p= _repository.GetProposition(id);
p.GetTask(taskId).SetComplete();

public class Task
{
  public event Action<Task> Completed;       


   public void SetComplete()
   {
        if (Completed!=null) Completed(this);
    }

Фаза должна обрабатывать завершенное событие Задачи и, когда оно запускается, проверять, является ли это последним заданием, и уведомлять о пропорции для закрытия. Теперь, может быть, использование событий - не лучшая реализация, возможно, шаблон Observer лучше, но основные идеи:

  • Вы получаете задачу с помощью метода Proposition (поскольку Proposition - AR)
  • Задачи уведомляют об окончании фазы
  • Фаза уведомляет предложение, когда последнее задание выполнено
  • Предложение должно проверить, нет ли в стадии выполнения каких-либо этапов, и закрыть себя.
  • сохранить предложение в хранилище

Если подумать, это в основном шаблон событий домена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...