談談設計原則DIP
3/21本人寫了一篇文章介紹OCP設計原則 (意即:要延伸一個類別時不能要求修改該類別) ,多少引起一些反應,現在我們利用這篇短文來輕鬆談談,另外一項重要的軟體設計原則:「依存反向原則」(Dependency Inversion Principle - DIP)。
首先我們談談何謂軟體「設計原則」,在軟體發展的領域中,所謂設計原則是:「在發展軟體系統的動作中,一種可接受的規則或方法,也就是說可使用的工作原則」(http://dictionary.reference.com/),好的設計原則必須是能夠協助發展者產生設計主意(idea),而且可以讓設計者能夠透過設計意涵來思考其實際的設計(Rebecca J. Wirfs-Brock 2009),依據這樣的定義,我們所要談的設計原則是可實地應用的,不過原則並非嚴格的設計規則,有如設計樣式(design patterns)一樣,僅在某種環境中使用,過份使用設計原則,可能會增加程式的負擔與工作量,因此,如果你確定類別的功能將來不致改變,則不一定要去使用設計原則,不過大部分的設計原則,都是將實作(implementation)引藏起來,以保持設計的彈性,如OCP或本文即將介紹的DIP。
DIP的定義可見諸於各類設計樣式的書本或網頁,簡言之就是:『抽象不能依存於細節,而細節必須依存於抽象』(Abstraction shouldn't depend on details. Details should depend on abstraction - Rebecca J. Wirfs-Brock 2009),這是何意?我們舉一個簡單的例子:一家公司顧有許多員工,也就是說公司就必須直接依存於這些員工,以軟體結構語言來說,公司是屬於「高階模組」(high-level module),就是上述DIP定義所謂的「抽象」,而員工則屬於「低階模組」(low-level modeule),也就是定義所說的「細節」,如果公司因業務需要必須增聘具有高強能力或專長的員工(也許稱之為super employee),而沒想到使用DIP,則必須修改複雜的公司模組內容,這種修改將影響公司模組的結構,這樣就違反DIP,如果希望增加任何員工而不想影響到公司模組,DIP告訴我們,可以在公司模組與員工模組之間介入一種「抽象層」(abstract layer),公司模組與員工模組都依存於這個抽象層,如此不論如何增聘員工都不致於影響公司模組本身,這種抽象層一般都是一種介面,下面左圖是反DIP的設計,右圖是依循DIP的設計:
首先我們談談何謂軟體「設計原則」,在軟體發展的領域中,所謂設計原則是:「在發展軟體系統的動作中,一種可接受的規則或方法,也就是說可使用的工作原則」(http://dictionary.reference.com/),好的設計原則必須是能夠協助發展者產生設計主意(idea),而且可以讓設計者能夠透過設計意涵來思考其實際的設計(Rebecca J. Wirfs-Brock 2009),依據這樣的定義,我們所要談的設計原則是可實地應用的,不過原則並非嚴格的設計規則,有如設計樣式(design patterns)一樣,僅在某種環境中使用,過份使用設計原則,可能會增加程式的負擔與工作量,因此,如果你確定類別的功能將來不致改變,則不一定要去使用設計原則,不過大部分的設計原則,都是將實作(implementation)引藏起來,以保持設計的彈性,如OCP或本文即將介紹的DIP。
DIP的定義可見諸於各類設計樣式的書本或網頁,簡言之就是:『抽象不能依存於細節,而細節必須依存於抽象』(Abstraction shouldn't depend on details. Details should depend on abstraction - Rebecca J. Wirfs-Brock 2009),這是何意?我們舉一個簡單的例子:一家公司顧有許多員工,也就是說公司就必須直接依存於這些員工,以軟體結構語言來說,公司是屬於「高階模組」(high-level module),就是上述DIP定義所謂的「抽象」,而員工則屬於「低階模組」(low-level modeule),也就是定義所說的「細節」,如果公司因業務需要必須增聘具有高強能力或專長的員工(也許稱之為super employee),而沒想到使用DIP,則必須修改複雜的公司模組內容,這種修改將影響公司模組的結構,這樣就違反DIP,如果希望增加任何員工而不想影響到公司模組,DIP告訴我們,可以在公司模組與員工模組之間介入一種「抽象層」(abstract layer),公司模組與員工模組都依存於這個抽象層,如此不論如何增聘員工都不致於影響公司模組本身,這種抽象層一般都是一種介面,下面左圖是反DIP的設計,右圖是依循DIP的設計:
實際運用DIP原則來設計類別時則可依照:『高階模組 → 抽象層 → 低階模組』的流程,Christopher Alexamder稱為"complexification",就是從概念(conceptual)再漸漸增加細節與功能,日常生活中處理各種事務時大致也是依循這種原則,DIP或complexification是有些設計樣式的基本中心原則,例如Factory Method,Abstract Factory,Prototype等,尤其Template設計樣式就是應用DIP原則,這一點有機會再來討論。總之,設計時如能時常將DIP放在心上,則發展高階模組之前不要去發展低階模組,這就是由上而下(top-down)的發展方式,這種方式可適用在從事設計與實作時,我想,善用設計原則將可使你/妳設計的軟體更具彈性而容易保養。
附註:上右圖可以以下列Java程式來表示。
受教了,非常的精闢的解說。謝謝老師!
回覆刪除Inverstion 拼錯了.
回覆刪除非常抱歉,"Inverstion"拼錯,已改正為"Inversion",謝謝指正。
回覆刪除近來許多知名的框架,例如做網頁的 Spring, 就是用此設計技巧,的確是很重要的一種方式。
回覆刪除