JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Software Design  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to postflat modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 不如甭相識 [精華]
qing



版主

發文: 90
積分: 1
於 2004-10-01 18:12 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我們可以從設計模式的型錄中找到許許多多的設計模式,許多模式都是千錘百鍊之後精華,對於各種經常會發生的設計問題,都能夠提供一些不錯的解法。最近參加了一些關於設計模式的討論,我發現有些設計者會太執著於某些型錄中,在字面上對於設計模式的詮釋或定義。這些型錄,尤其是GoF聖經本上所言,隱隱然成為不可打破的定律或法則。對設計者而言,這當然是不好的一個想法。William在GoF聖經本中譯本中的序裡,就提醒了大家:「招式是死的,人是活的」-而這正是笑傲江湖一書中,風清揚提醒令狐沖之言。

你應當再注意一些原理層次的事情。事實上,在遍覽各種模式後,你會自然而然的發現許多的設計模式,它們儘管要解決的問題本身不同,但是解決問題是想要達到的目標卻是共通的。我想,許多設計模式共通的目標中,最重要的一個莫過於design for change了。什麼叫design for change?意思就是現在所做的設計,是為了日後可能的變動而做準備的。Design for change包括兩種層次,一種是設計本身已經可以兼顧日後可能會有的變動,也就是說,即使日後某些條件或需求改變了,仍然不需要變更設計本身。而另一種層次,則是現行的設計本身雖然不見得能容納日後的變動,但是現行的設計可以很輕易的演化成下一版本的設計,而讓下一個版本的設計來吸收變動所造成的衝擊。這兩種層次的design for change都會時常的被運用到,而它們同時也反映出設計的彈性與可擴展性(extensibility)。

其實你可以想想XP(eXtreme Programming)的精神,就是一種要因應變動的開發方法,就和design for change的第二種層次極為相像。並不企圖一次達到極高的彈性,而是每次都保留一點彈性,讓自己有機會可以順利的前進到下一個iteration去。由於change通常都是一點一滴的打到我們的系統,每次的造成的變化都不會太大,所以保留適當的彈性通常就已經足夠,但必須持續的讓每個設計的版本,都能夠有前進到下一階段足夠的彈性。這種方式,相較於一開始就想要做一個可容納所有變動、包山包海的設計來說,可以避免over-engineering(過度設想)所造成的問題。

Design for change是許多設計模式想要達到的共通目標,它會反映在許多的面向上。而我這次要想談的,便是design for change的概念,是如何反映在物件與物件的關係上。

設計模式的作用之一,便是能夠告訴設計者應該如何處理類別和類別之間,或物件和物件之間的關係。許多設計的巧妙之處,便是表現在此類關係上的制定。

類別和類別之間可以存在多種不同的關係,例如,繼承、實作、聚合、關聯、等等。我喜歡把類別和類別之間的關係視為一個有向(directional)網絡。在網絡中的每個結點都是一個類別,倘若某類別與另一個類別存在某種關係時,那麼對映到網絡中的兩個節點之間,便存在一條連結。事實上,我們可以說此種網絡是UML圖示中class diagram的退化版本,因為它將所有類型的關係都簡化成一種。

建構此一網絡的目的,在於協助我評估類別與類別之間的相關程度。而評估類別與類別之間相關程度,有一個很簡單的量化方式,就是在網絡中兩個節點的最短距離的倒數,就是所對映兩個類別的相關程度。

為什麼我需要了解兩類別之間的相關程度呢?因為我想要知道當一個類別發生了變動時,這個變動可能會影響的範圍會有多大。當兩個類別A在網絡中與B直接相連時,這意謂當B的介面改變時,便可能對A產生衝擊。當A與B直接相連,而B與C直接相連,且A未與C直接相連時,當C的介面改變時,首當其衝的是B。當B的確被此一改變波及時,B也許調整其實作,毋需改變其介面,便能夠吸收掉C所造成的change impact。但如果情況再糟一點,B需要改變其介面,才能夠化解change impact時,便可能進一步往後再影響到A。類似的情況可以一直往後再套用下去。從這裡,可以觀察出來,兩類別距離愈遠,某一類別的改變,對另一個類別造成影響的機會就會愈低。換句話說,兩個類別的相關程度愈低時,一個類別的改變,就比較可能不會影響到另一個類別。這就是我的防火牆理論。

設計模式告訴我們要「針對介面而寫,不要針對實作」。在我的防火牆理論中,類別的設計發生了改變,是一件不好的事情,就跟屋子裡頭著了火一樣。火勢會試著往外漫延,如果不加以控制,燃燒的範圍就會愈來愈大。在設計中,每隔出一層的介面,就等於在類別與類別之間隔出一防火牆(firewall)。火勢遭到防火牆的阻隔,可能被擋下來,也可能穿透,但無論如何,存在愈多道的防火牆,就愈有可能擋住火勢。

當兩個類別A與B之間直接相連時,它們之間是沒有任何防火牆的存在。然而,如果我們隔出了一層介面C,而A是透過C去連接到B,C就可以做為一個緩衝,來隔離B可能會發生的改變。當這中間的緩衝愈多時,就愈能吸收改變所造成的衝擊。

當然,介面的使用會提高間接程度(indirection level),可能會造成兩個不好的效應,一個是效率可能因此降低,另一個則是設計本身可能較難理解。究竟會不會真的發生效率與可讀性的問題,倒不一定,最終仍是視設計而定。

所以明白了相依程度跟改變是這麼的息息相關後,應當就能明白,為什麼像Façade這樣子的設計模式,會希望所有的client對某個sub-system的存取,一律從單一窗口進入,而不要直接存取背後所有相關的服務。當client只直接關聯至Façade類別時,Façade類別就做為一道防火牆。當子系統實作或內部設計改變時,Façade便有機會吸收這些改變。倘若沒有Façade的存在,而放任client直接存取構成sub-system的諸類別時,那麼sub-system的變動,可能會同時造成多個sub-system中的類別需要改變,同時因為client拉了許多條連結到各個類別上,所以各個類別的改變,都會反映到client得同時做出許多的因應與調整。這當然是一件很糟的事情。本文所提的這種網絡,愈是交錯複雜,愈是代表所做設計可能很容易受到改變而影響深遠。

再轉一個角度看,倘若某類別與另一類別之間存在關係,便會造成兩類別相依。但是什麼叫「某類別與另一類別之間存在關係」?其實可以很簡單的說,如果某個類別A「認識(knows)」類別B,那麼它們之間便存在某種關係。在這裡我用了一個很抽象的詞彙,就是「認識」。類別和類別之間,其實就跟人際社會一樣,有著認識和不認識的分別。更簡單的說,當類別A的原始碼中,出現類別B的名稱時,A就「認識」B了。所以前文所提的這種網絡,就可以被視為是物件社會中的關係網絡,當兩個類別A、B之間存在一連結時,代表A認識了B。

舉生成模式(creational pattern)為例,所有的生成模式都不希望client直接以「new」關鍵字(對C++、Java、C#而言)來生成類別的物件。因為當你在原始碼中直接這麼撰寫時,會在「new」關鍵字後附上所欲生成的類別名稱,這麼一來,這一個類別就「認識」了另一個類別,二者也就發生了關係。當被「認識」的類別發生了變動時,火勢就有可能會燃燒過來。

做為一個系統架構的設計者,是物件世界的主宰者。道德經裡說「古之善為道者,非以明民,將以愚之。民之難治,以其智多。」可見,做為一個統治者(姑且不論民主思潮),讓被統治者知道的愈多,都不是什麼好事。讓物件知道的太多,同樣也不是一件好事。物件導向的設計要領之一,便是平均分擔每個類別所擔負的責任,而不要製造出super class(超級類別,擁有超強能力因此負起超重責任的類別)。做為一個獨裁的統治者,眼中又豈能容得了另一個能力超凡的領袖呢?當你所設計的架構中,出現了Charisma時,這代表你所設計的架構非它不可,也就是代表著,當它發生了變動時,你所設計的架構,整體受到影響的機會就會很高。對於design for change這個原則來說,自然要盡量避免這件事情。

擁有愈多的能力或責任,代表類別知道的愈多。同樣的,當類別「認識」其他的類別愈多時,知道的事情同樣的也變多了。當類別A認識類別B時,類別B的變動,便有可能波及到類別B。回想在由珊卓布拉克所主演的「網路上身(The Net)」這部電影中,珊卓布拉克完全過著與世隔絕的日子,認識她的人屈指可數,因此,要從社會中將她的身份整個抽離時,變得十分的容易。因為沒有人認識她,即使她從社會上消失了,也不會對社會人群中的其他人造成影響。這件事情回歸到物件的社會上亦然,當一個類別被太多的類別認識時,它豐富的社交關係,會使得它身上所發生的改變,十分容易的影響到整個物件社會。反之,如果每個類別都只認識極少數的類別,那麼,這樣子的系統設計,就應該具備較高抵抗變動的能力。

如果你打算design for change,而且希望你所做的設計,能夠具備較高抵抗變動的能力,你應該把「不如甭相識」這句話記在心裡。在任一個類別中,能少認識一個類別,就盡量少認識一個,因為「相識即相依」。


reply to postreply to post
話題樹型展開
人氣 標題 作者 字數 發文時間
5163 [精華] 不如甭相識 qing 3802 2004-10-01 18:12
» JWorld@TW »  Software Design

reply to postflat modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8