2009-04-14 44 views
4

您的工作是設計一個支持跟蹤任務的項目計劃類庫(類似於MS Project的工作方式)。這個類庫有一個Task對象(等等)。.NET對象層次結構 - 事件或不事件

Task對象具有EstimatedHoursDouble),StartDateDateTime),和EndDateDateTime)屬性,等等。 A Task對象可以有一個父項Task和幾個子項Task對象。 EstimatedHours,StartDateEndDate具有子項(是父項)的Task的屬性取決於其直接子項的屬性。父母TaskStartDate是其子女最早的StartDate。母公司TaskEndDate是其子女的最新EndDate。父母TaskEstimatedHours是其子女EstimatedHours的總和。因此,在有孩子的Task上更改這些屬性是無效的。

如何處理EstimatedHours,StartDate或EndDate在具有父項的任務中更改的用例?(父母的屬性是其子女的反映,因此對子女的任何更改都可能需要對父母的屬性進行調整以適當反映這些更改)

一種選擇是在每個屬性更改時都有一個事件。父母Task會在其直接子女Task對象上偵聽這些事件,並在發生這些事件時對其自己的屬性進行適當更改。這是一個好方法,還是有更好的方法? 怎麼辦?

這裏是一個什麼樣的Task對象可能看起來像一個基本思想:

Public Class Task 

    Private mChildren As List(Of Task) 

    Private mEndDate As DateTime = DateTime.MinVlue 
    Public Property EndDate() As DateTime 
    Get 
     Return mEndDate 
    End Get 
    Set(ByVal value As DateTime) 
     mEndDate = value 
     'What to do here? 
    End Set 
    End Property 

    Private mEstimatedHours As Double = 0.0 
    Public Property EstimatedHours() As Double 
    Get 
     Return mEstimatedHours 
    End Get 
    Set(ByVal value As Double) 
     mEstimatedHours = value 
     'What to do here? 
    End Set 
    End Property 

    Private mStartDate As DateTime = DateTime.MinVlue 
    Public Property StartDate() As DateTime 
    Get 
     Return mStartDate 
    End Get 
    Set(ByVal value As DateTime) 
     mStartDate = value 
     'What to do here? 
    End Set 
    End Property 

End Class 

回答

1

我不會考慮這個型號的責任的一部分,而是在它上面的控制器。

將事件或觀察者模式添加到模型會增加其他領域的複雜性,例如序列化,這些都是您想要避免的。

使它成爲修改類的責任,而不是模型本身。記住:模型的責任是包含信息,而不是暗示業務規則。

1

請記住,當事件鏈中的一個事件引發異常時,將不會調用以下事件。因此,如果有其他事件註冊到數據,它可能可能是可能的,您的事件將不會被調用。

如果對於您的應用程序來說基礎任務與其子代永遠不會脫節,那麼請不要使用事件。

1

我會首先構建對象模型,以便它可以即時計算值。我要給你C#作爲我最comftorble它(我也使用領域,而不是性能,以保持樣品小):

public class Task 
{ 

    public List<Task> Children=new List<Task>(); 
    public Task Parent; 
    private int _duration; 

    public int Duration 
    { 

     get 
     { 
      if (Children.Count>0) 
      { 
       return SumChildrenDuration(); 
      } 

      return _duration; 
     } 

     set 
     { 
      if (children.Count>0) 
       throw new Exception("Can only add to leaves"); 
      _duration=value; 
     } 
    } 
} 

一旦你有這地方,你現在有你的所有代碼需要運行你的系統。您可能會發現系統運行良好,並保持這種狀態。否則,您可以添加其他功能來緩存結果,然後在對象更改時重置緩存。不管你做什麼,一定要仔細分析它,因爲你想確保你的緩存和過期並不昂貴,然後只是在即時計算。

2

我不確定這是如何實際做到這一點,但這裏有一個不同的選擇:使用兩個對象,一個Task和一個實現ITask接口的TaskSet,而不是允許任務有孩子。一個任務會有自己的StartDate,EndDate和EstimatedHours,但是一個TaskSet會動態地從它的子任務中計算出這些值。使用服務將孩子添加到ITask並將其刪除。對於添加,當添加第一個子項時,它會將Task轉換爲TaskSet。對於刪除,當將最後一個孩子刪除並將最後一個孩子的值設置爲屬性時,它會將TaskSet轉換回Task。

0

我告訴我的ASP.NET開發人員:「事件監督。方法完成工作。」

事件應該比IFblocks調用方法多一點。沒有嘗試/捕獲等。
方法做所有的數據訪問/操縱/驗證/計算等。
這在我的開發人員也創建了「可重用的代碼」心態。

它保持事物分離。
它也很好地與MVC概念相似。

控制器對事件做出反應。他們監督。他們稱之爲模型方法。
模型做的工作。

這不是一個完美的平行。
的確,這很簡單,但它爲非常好的指導方針。