2010-10-21 80 views
1

我有一個函數可以返回給定期間的訂單。我創建了一個Period對象,可以確保在指定日期範圍時,開始日期爲< =到結束日期。同樣,如果處理一個月的時間段,則該時間段的開始日期和結束日期應分別爲該月的第一天和最後一天。OOP/OOD耦合問題

我的問題是這樣的:

我認爲,在面向對象的設計原則,聯軸器是壞的。我是否通過讓Order類在其方法之一中使用Period類作爲參數來引入Order和Period類之間的耦合?

我的猜測是肯定的,但這樣做的好處是,即一旦定義了對象,就不必每次將句點作爲參數傳遞給不同的方法時都執行相同的參數驗證檢查Orders類。

此外,Microsoft是否不經常將一種類型的非內在對象傳遞給其他對象?
避免耦合聽起來像避免重複使用我,這是面向對象應該促進。這聽起來像是相互競爭的目標。

有人可以澄清。

Public Class Order 

    Public Shared Function GetOrders(ByVal customerId As Integer, 
            ByVal forPeriod As Period) As Orders 

     **'Should the param object MonthPeriod be replaced with 2 date params? 
     'Would I be "reducing coupling" by doing so, a good thing.** 

    End Function 

End Class 

Public Class Period 

    Property FromDate As Date 
    Property ToDate As Date 

    Public Sub New(ByVal fromDate As Date, ByVal toDate As Date) 

     If fromDate > ToDate Then 
      Throw New ArgumentException("fromDate must be less than Or equal toDate") 
     End If 

     _FromDate = fromDate 
     _ToDate = toDate 

    End Sub 

End Class 

Public Class MonthPeriod : Inherits Period 


    Public Sub New(ByVal fromDate As Date, ByVal toDate As Date) 

     MyBase.New(fromdate, toDate) 

     If fromDate.Date <> New Date(fromDate.Year, fromDate.Month, 1) Then 
      Throw New ArgumentException("fromDate must be the first day of the month") 
     End If 

     If toDate.Date <> New Date(toDate.Year, toDate.Month, Date.DaysInMonth(toDate.Year, toDate.Month)) Then 
      Throw New ArgumentException("fromDate must be the last day of the month") 
     End If 

    End Sub 

End Class 

回答

1

.Net中的所有東西都是一個對象,然而對象很少存在於隔離中,因此會存在一定程度的耦合班是。你需要問的問題是緊密耦合,有些耦合或鬆散耦合的類。緊密耦合的類會形成一個脆弱的架構,因爲這些變化可能會在整個模型或系統中產生連鎖反應。隨着時間的推移,課程的維護會變得越來越困難。讓你的課程更鬆散耦合傾向於緩解其中的一些問題。在東西是否是鬆耦合還是沒有(從here)方面:

耦合是指 直接知識一類具有 另一個程度。這並不意味着將 解釋爲封裝而對 解釋爲非封裝。它不是一個 引用一個類的知識 另一個類的屬性或 的實現,而是知識 其他類本身。強 當依賴類 包含直接指向提供 所需行爲的 具體類的指針時發生耦合。依賴關係 無法替換,或者其 「簽名」已更改,無需對相關類進行更改 。鬆散 當依賴的 類包含僅指向 接口的指針時,會發生耦合,然後該接口可能由 類實現,該類由一個或多個具體的 類實現。

在你的例子中,你介紹了Order類和Period類之間的一些耦合。您可能需要將兩個相關日期傳遞給Order方法,並且您選擇創建一個Period類來完成此操作。爲什麼?因爲你有兩個日期;從日期到現在;並且您想驗證您的代碼中的一個且僅有一個點的到期日期晚於。這是DRY principle的應用;這是一件好事。的DRY原則的應用,而相關的,從代碼複用(從here)不同:

一些特性,這使得 軟件更容易重複使用的是 模塊化,鬆耦合,高 凝聚力,信息隱藏和 關注點分離。

鬆耦合只是使代碼重用的幾個特徵之一。代碼重用在某種程度上可以讓你在你的代碼的其他地方使用Period類,而不僅僅是Order類。如果您要添加一個接口來抽象使用Period類,那麼這會讓您的Order類和Period類更加鬆散地耦合,但這不會消除代碼重用的能力(您可以在別處使用Period類在你的代碼中)。

+0

優秀的答案。謝謝 – ChadD 2010-10-22 02:08:47

+0

Definetly同意...優秀的答案。謝謝(我多次閱讀這些內容,但是當你看到如此精細的評論時(爲什麼/何時/細節),那麼在你的代碼中應該選擇哪種方式。謝謝史蒂夫。 – ramnz 2012-11-20 17:03:55

1

鬆耦合和重用確實是競爭的概念。在設計軟件時,你必須不斷平衡兩者的使用。

+0

好的,根據你的回答,我想我理解了這些概念。 – ChadD 2010-10-21 19:59:00

1

系統中的服務(如GetOrders)可以依賴小而易於創建的Value對象(如Period)。這可以讓您的服務對象根據您所在的域進行交談,而不是始終使用基本類型。

因此,我想說在這種情況下將Period傳入GetOrders是正確的。它提高了抽象級別。 GetOrders對所有Period類感興趣,所以你不會不必要地限制GetOrders知道的概念範圍(它只是以不同的形式)。如果Period是一個包含一堆其他東西的更大的類,那麼耦合將是一個更大的問題。

第二個因素,使得這個好,是創建一個Period對象很容易。如果它需要你創建一系列其他對象,那麼耦合將是一個問題。這就是爲什麼你沒有你的價值對象發送電子郵件並將自己保存到數據庫等。

1

應該避免不必要的耦合,但在你的場景中,Period只是用來定義一個值類型,它聚集了一些關於你的域的概念,所以它一點都不差。如果它超出了數值類型的使用範圍,則需要使用像依賴注入(DI)和控制反轉(IoC)這樣的技術來解耦它們。

就測量設計而言,涉及到依賴關係時,您必須超越類級別,但更多的是在名稱空間或程序集級別。就你而言,如果Period存在於相同的命名空間或程序集中,那麼你的包中的類型之間仍然有很好的關係凝聚力。在上面的場景中,您的命名空間的傳出和傳入耦合仍然保持不變/較低。