【轉】視角的力量--再說OO設計原則

本文轉自:http://www.cnblogs.com/me-sa/archive/2008/04/15/1154014.html

 OO設計原則總結》一文中我提出了一個問題:如何更好的使用這些原則?怎樣在實踐中遵守這些原則,使用三種視角思考問題就是答案之一;

 

本文內容包括:

1.爲什麼我們過早的糾纏於細節?問題的本質是什麼?

2.救命稻草--Martin Fowler的三層視角理論

3.三層視角--回頭再說OO設計原則

 

爲什麼我們過早的糾纏於細節?問題的本質是什麼?
         做設計時過早的關注細節幾乎是多數程序員的泥沼,也是我自己的頑疾。就像我剛開始工作不久要做一個自動更新的系統,設計會議上開發組老大定了使用FTP協議完成,你知道我腦袋裏面想的是什麼?--Indy組件好像不支持中文”…...

      過早的關注細節,大體上可能有兩種原因:1.經驗豐富,舉一反三,綱舉目張,各種技術玄妙如數家珍 2.沒有什麼經驗,只知道點技術細節,難以跳出思維桎梏;我知道我是後者,以前是現在也是。

       人是有惰性的,人們習慣性的做自己熟練精通的事情。所以做設計的時候,當對大框架缺少把握能力的時候,潛意識裏我更願意去思考那些細節。這是在偷懶,所有的技術細節、問題都是沒有疑問的(我們不是做科研),或者是有疑問你可以很容易獲得解答無論是開發文檔還是在社區。細節的解決方案總是顯而易見,但並非肯定是最好的入手點。

       有時候我真的要做設計了,我想要避免陷入“細節泥沼”可是我還是無意中把細節扯進來,這是爲什麼?剖析自己,我知道這是因爲我的思考是平鋪的,是沒有層次的,所有的問題攪在一起,做設計的時候難免拖泥帶水,泥沙俱下。

       思考沒有層次這就是問題本質所在,我要做好設計,而思維方式上的缺陷成爲我的命門所在,我該怎麼辦?說實話我一直在走彎路,而且不知道現在的這條路是否對頭。
        “善良的人在追求的中縱然迷茫,卻終將意識到有一條正途.-----《浮士德》
 

救命稻草--Martin Fowler的三層視角理論

     Martin Fowler在他的著作 UML Distilled》中提到了三層視角(perspective):概念視角,規約視角,實現視角。

使用三種視角看軟件開發,我們可以得到這樣的描述:

概念視角:呈現所研究領域中的各種概念,得出概念模型的時候應該儘量少德或者不考慮它的實現,這個視角要回答的問題是:軟件要負責什麼?是策略性的結論

規約視角:我們現在考慮的是軟件,但是我們關注的是軟件的接口而不是實現。規約視角要回答的問題是:怎麼使用軟件?這個層次關注的是軟件各部分的交流。

實現:這時我們考慮的是代碼本身但是許多方面我們使用規約視角可能會更好,軟件在規約層交流在實現層執行。

 

視角幫助我們將問題劃分層次,隔離

        從上面的描述我們很明顯得看到“軟件開發”所設計牽扯的問題已經被劃分到三個不同的層次,在每一個層次我們都要有特定的思考成果。在高層沒有思考成熟的時候我們不往下一個層次進行,按照這樣一個原則,細節被隔離在思維的圍牆之外。
       下面一個問題就是,在設計中過程,三種視角對問題進行層次劃分能起到什麼作用?
 

三層視角--回頭再說OO設計原則

         
概念視角我們得到了領域的各種概念,對象要負責什麼?這是一個高層策略,它通常是高度抽象的,是一個策略性的結論,關鍵一點:它是穩定的。只要概念不變請求者就和細節的變化隔離開了;細節問題的處理應該儘可能的往後推遲。關注對象要做什麼,而不是怎麼做,將這些細節實現隱藏起來幫助我們免於過早的介入細節。關注對象要做什麼,就是在定義對象的責任,理解對象的最佳方式就是把它看作有責任的東西。

       規約視角,對象是一組可以被其它對象或對象自己調用的方法(也就是行爲,怎麼使用軟件?);對象是有責任的我只需要關注對象的公共接口-這是我要求對象完成某些工作的交流渠道。只要對象的接口告訴我們它可以完成某項職責,不關注對象是怎樣運行的。關注動機而非實現,是基本的OO設計原則,將實現隱藏在接口之後實際上是將對象的實現與它們的對象解耦了。

      實現視角,對象是代碼和數據,以及它們之間的計算交互(軟件怎麼履行自己的責任?);走到這裏我們纔開始討論實現細節。

      總結一下,Martin Fowler的三個視角來看對象:

在概念層次上,對象是一組責任

規約層次上,對象是一組可以被其他對象或者對象自己調用的方法

在實現層次上對象是代碼和數據,以及它們的計算交互

 

到這裏我們需要對OO基本原則做一個再思考了:

        從概念層到規約層我們的思考成果都是抽象的,他們是一個個抽象的概念,是一個個的行爲;我們在概念層是對象的責任清晰化,在規約層我們看擁有不同責任的對象之間是怎樣協作的。協作方式就是一種對象與對象之間的契約。對象的責任怎麼劃分?對象應該對自己負責,對象的責任應該儘量單一,這就是SRP原則。規約層我們定義的是對象間的交互契約,也就是接口,關注接口而非實現,我們做到了。

       概念層是最穩定的,規約層次之,實現是最不穩定的。所以高層模塊不應該依賴低層模塊,兩者都應該依賴於抽象。細節應該依賴於抽象,這就是DIP原則。這個原則隱含的意思是:對象之間只在概念層次存在耦合,在實現層次不能耦合!

       我們定義的所有交互都是使用基類,那如果實現的時候某一個子類不能完全代替基類呢?那是不是所有的交互契約都出現問題了?一個從基類派生的子類應該支持基類的所有行爲,子類必能替換基類,這就是LSP原則。

        可以看出對象的責任和交互被儘早的定義出來,這個過程中我們沒有考慮具體對象在什麼時期創建,映射到我們的設計過程中,創建型設計模式的應用往往是在設計的後期。

 

       結論:

OO設計原則總結》一文中我提出了一個問題:如何更好的使用這些原則?怎樣在實踐中遵守這些原則,使用三種視角思考問題就是答案之一; 做設計時,注意力首先要放在高層關係上;  在面對對象設計開發過程中以概念 規約 實現三個視角類思考問題能提高我們的設計能力,避免過早陷入細節泥沼。

 

附: Martin Fowler著作 UML Distilled》提到三種視角(perspective)的段落:
 

Following the lead of Steve Cook and John Daniels (1994), I say that there are three perspectives you can use in drawing class diagrams- or indeed any model, but this breakdown is most noticeable in connection with class diagrams.

  • Conceptual.  
    If you take the conceptual perspective, you draw a diagram that represents the concepts in the domain under study. These concepts will naturally relate to the classes that implement them, but there is often no direct mapping. Indeed, a conceptual model should be drawn with little or no regard for the software that might implement it, so it can be considered language-independent. (Cook and Daniels call this the essential perspective.)
  • Specification.  
    Now we are looking at software, but we are looking at the interfaces of the software, not the implementation. Object-oriented development puts a great emphasis on the difference between interface and implementation, but this is often overlooked in practice because the notion of class in an OO language combines both interface and implementation. This is a shame, because the key to effective OO programming is to program to a class's interface rather than to its implementation. There is a good discussion of this in the first chapter of Gamma, Helm, Johnson, and Vlissides (1995). You often hear the word "type" used to talk about an interface of a class; a type can have many classes that implement it, and a class can implement many types.
  • Implementation.  
    In this view, we really do have classes and we are laying the implementation bare. This is probably the perspective used most often, but in many ways the specification perspective is often a better one to take.

Understanding perspective is crucial to both drawing and reading class diagrams. Unfortunately, the lines between the perspectives are not sharp, and most modelers do not take care to get their perspective sorted out when they are drawing. Although I've found that this often does not matter too much between the conceptual perspective and the specification perspective, it is very important to separate the specification perspective and the implementation perspective.

As I talk about class diagrams further, I will stress how each element of the technique depends heavily on the perspective.

Perspective is not part of the formal UML, but I have found it extremely valuable when modeling and when reviewing models. The UML can be used with all three perspectives. By tagging classes with a stereotype (see page 79), you can provide an indication of the perspective. You mark classes with <<implementation class>> to show the implementation perspective, and with <<type>> for the specification and conceptual perspectives.

 

UML Distilled Second Edition A Brief Guide to the Standard Object Modeling Language

Martin Fowler   Kendall Scott

Publisher: Addison Wesley

                Second Edition August 18, 1999

                ISBN: 0-201-65783-X, 224 pages


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章