2

介绍

假设我有三个域对象:

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;

因为 Proposition 不必加载,如果它没有加载,我们会得到一个异常。

选项 2a是有问题的,因为在执行 phase.LastTask.SetComplete() 之后,命题未处于正确状态。在任何可以访问 Phase 的代码中,“phase.LastTask.SetComplete()”可以在不对 Proposition 执行相关操作的情况下执行。

选项 2b与 2a 有同样的问题。

选项 3赋予 Proposition 类太多的责任。

你们有什么建议吗?

4

1 回答 1

1

我猜 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);
    }

Phase 应该处理 Task 的完成事件,当它被触发时,检查它是否是最后一个任务并通知 proorisiton 关闭自己。现在也许使用事件不是最好的实现,可能观察者模式更好,但主要思想是:

  • 您通过 Proposition 方法获得任务(因为 Proposition 是 AR)
  • 任务完成时通知阶段
  • 当最后一个任务完成时,Phase 会通知提议
  • 提议应检查是否没有任何阶段正在进行并自行关闭。
  • 在存储库中保存命题

想一想,这基本上是领域事件模式。

于 2012-02-15T10:48:28.160 回答