低耦合(Low-Coupling)與高內聚力(High Cohesion)的設計原則

物件導向設計有一個很重要的原則就是盡量達到低耦合(Low-Coupling)與高內聚力(High-Cohesion)的結果。最近看到一篇文叫作【Two powerful principles to improve the design】的文章用很簡潔的方式介紹了這樣設計的好處。

假設我們的需求有三個:

1.Get Data from a file
2.Process
3.Print Result

一開始的設計是這樣,我們在一個類別中,透過Main方法去呼叫DataProcessor方法,分別做這三件事情,一切就結束了。


但是這樣的設計有幾個缺點:

1.Low Cohesion:DataProcessor做了太多了事情,所以我們沒辦法把它抽出來給別的類別使用。
2.High Coupling:這樣的設計,處理的過程很依賴於如何取得data。

顯然這樣設計雖然很直覺,但是對於重用、避免重複造輪子來說並不是一個漂亮的作法,因此我們需要來從High Cohesion和Low Coupling這兩個角度來重新思考。

  • High Cohesion:為了達到高的內聚力,我們每個類別所作的事情應該要很明確。在這裡我們需要建立三個類別:

  • 1.FileProvider:負責取得資料
    2.DataProcessing:負責處理資料的邏輯
    3.ResultReporter:負責將處理的結果呈現出來

如此一來每個類別的責任就很清楚,未來如果取得資料的方法不是從檔案而是從資料庫,我們也只需要修改FileProvider那隻程式就好了。

  • Low Coupling: 一開始我們的設計會相當依賴如何取得data這個方法,為了要降低依賴程度,我們定義一個叫做IDataProvider的interface,這個interface裡面有一個getData的方法,但我們都知道interface不需要提供實作,因此,當我們需要從從檔案中取得data時,只要寫一個FileDataProvider去實作IDataProvider這個interface,並且將取檔案的邏輯寫好就可以了。

同樣的邏輯可以用在DataProcessing和ResultReporter這兩個類別上,因此,我們的設計就會變成如下圖所示:


看起來不錯,但好還可以更好。在上面的設計中,IDataProvider、IDataProcessor和IReportResult這三個物件的instance都是由Main方法來產生的。

為了提高內聚力,我們可以把物件產生instance的工作交給一個factory class來處理(可以參考factory design pattern)。接著,我們把啟動工作的責任交給一個Controller Class來處理,如此一來,如果我們這些程序要被其他的程式使用,就可以比較容易的移轉過去,不會被Main給綁死。




【相關閱讀】
Two powerful principles to improve the design

Share this post!

Bookmark and Share

1 意見:

匿名 提到...

寫文寫一半的喔