2012-04-20 38 views
0

比方說,我有一個簡單的todolist的:強制執行涉及多個項目的業務規則

interface ITodoList 
{ 
    ITodoItem Create(title); 
    IEnumerable<ITodoItem> Items {get;} 
} 
interface ITodoITem 
{ 
    void StartTrackTime(); 
    void StopTrackTime(); 
} 

現在,我想在一個時間(每用戶)執行,這樣時間只跟蹤一個項目。

我應該創建一個域名事件,如StartTrackTime生成的ItemTimeTrackingStarted。該事件將被ITodoService拾取,其檢查當前用戶是否有任何其他時間跟蹤項目(並停止它們)。還是有更好的方法?

+0

IMO,ITodoService將被命名爲ITodoPolicy,因爲它試圖強制執行的規則,而不是執行事務。如果跟蹤的TodoItem是第一個進入TodoList,那麼您正在使用FIFO集合,對吧? – lcardosobr 2012-04-20 14:41:33

+0

是不是缺少像TodoList.AssignItemTo(用戶用戶)或UserTimeTracking.StartTrackingTimeFor(TodoItem項目)的東西? – 2012-04-29 12:23:33

回答

1

好,如果你有項目之間的依賴關係,在這種情況下是檢查,我的建議是將軌道方法移動到待辦事項列表對象,並遠離項目。

因此,您請求對包含所有待辦事項的對象進行更改,並且在那裏您還找到了檢查。

+0

是不是有點不合邏輯?因爲這不是時間追蹤的清單嗎? – jgauffin 2012-04-20 10:29:32

+1

我同意馬丁的做法。 「TodoList」是聚合。它應該執行不變量。 – 2012-04-20 10:32:22

+0

請添加一個顯示您如何構造實體的示例。 – jgauffin 2012-04-20 10:40:36

1

IMO我不喜歡這樣,我不知道上下文的所有細節,但這裏這個特定的功能,它會

public interface ITrackTime 
{ 

    void StartTrackTime(); 
    void StopTrackTime(); 
} 
public interface ITodoItem 
{ 
    int Id {get;} 
    //other stuff 
} 

public TodoItem:ITodoITem, ITrackTime {} 

public class TodoList:ITodoList,ITrackItem 
{ 
    ITodoItem Create(title) 
    { 
     //create item and add it to collection 
    } 
     TodoItem _currentlyTracking; 

    void StartTrackTime(int itemId) 
    { 

     if (_currentlyTracking == null) 
     { 
      // getItem and call method for item .. 
      item.StartTrackTime(); 
      _currentlyTracking=item; 
     } 
     else{ 
      //get item and check to see if it is the same id 
      //throw exception if it is not, ignore it if it is 
      } 
     } 
} 

var list = new TodoList(); 
ITodoItem item= list.Create("titel"); 
list.StartTrackingTime(item.Id); 
list.StartTrackingTime(otherId); //should throw or whatever handling 

一切都包含在AR(TodoList的)之內。再次,這是一個粗略的草案,因爲我沒有完全意識到上下文和領域。

0

如上所述,ToDoList應強制約束,因爲約束是在ToDoList級別定義的。 (除非在用戶級別上定義,在這種情況下責任將在那裏轉移)。您可以將該方法留在該項目上,但可以引用父級待辦事項列表。代碼看起來是這樣的:

public class ToDoList 
{ 
    public IList<ToDoListItem> Items { get; private set; } 

    // factory method creates items as required by ToDoList 
    public ToDoListItem Create(string title) 
    { 
    var item = new ToDoListItem(this, title); 
    this.Items.Add(item); 
    return item; 
    } 

    ToDoListItem currentItem; 

    public void StartTrackTimeFor(ToDoListItem item) 
    { 
    if (this.currentItem != null) 
     throw new Exception(); 
    // could also throw different exception if specified item is current item being tracked 
    // start time tracking logic. 
    this.currentItem = item; 
    } 

    public void StopTrackTimeFor(ToDoListItem item) 
    { 
    if (this.currentItem != item) 
     throw new Exception(); 
    // stop time tracking logic.  
    this.currentItem = null; 
    } 
} 

public class ToDoListItem 
{ 
    public ToDoListItem(ToDoList list, string title) 
    { 
    this.ToDoList = list; 
    this.Title = title; 
    } 

    public ToDoList ToDoList { get; private set; } 

    public string Title { get; private set; } 

    public void StartTrackTime() 
    { 
    this.ToDoList.StartTrackTimeFor(this); 
    } 

    public void StopTrackTime() 
    { 
    this.ToDoList.StopTrackTimeFor(this); 
    } 
}