Введение
Допустим, у меня есть три объекта домена:
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 наделяет класс Предложения слишком большой ответственностью.
У вас, ребята, есть предложения?