20年過去了,重新審視設計模式

jianshu發表於2016-03-30

Design Patterns

  嫌太長就看這段:

  20年前,“Gang of Four”出版了設計模式的書。用了當時的主流語言(C++ 和 Smalltalk),當時的設計思想(比如強調繼承),儘管如此它仍然在業內引發了巨大的“運動”。然而,正如我們所知的歷史規律,這也是它要滅亡的標誌:所有在行業內成為“運動”的最終都會破滅。當它不能兌現它言過其實的承諾(實際上從來也沒有做到)就會成為眾矢之的。現在是時候讓我們回去用新的眼光重新審視23種設計模式,讓它和已經經過20年成長的語言對比,看看有什麼變化(劇透:初始的23種模式都很不錯,而且裡面有很多細微之處在我們第一次接觸的時候我們忽略了)。

  模式:到底是什麼?

  在早期模式“運動”中,當時模式還是一個新概念,我們沒有花什麼時間去真正的討論它。他們就是出現了。我們讀著設計模式的書頻頻點頭,感覺就像是之前一直處在程式碼世界的荒山野嶺裡,然後我們一如往常的寫著程式碼。接著我們覺得可以在一些地方可以用上設計模式,就像是世界開啟了一扇新的大門。我們感覺。。真是Cool。

  Gof似乎在一開始也覺得這是一門微妙的(subtle)藝術/科學。在書的最後一章(不幸的是基本沒人讀到這裡),他們說到:

也許有人會覺得這本書沒什麼了不起。畢竟它沒有展現任何一種新的演算法或者程式設計技術。它沒有為設計系統給出一套嚴格的方法,也沒有發明一種新的設計理論--它只是記錄了一些已經存在的設計。你可以總結說它是不錯的教程,也行,但是它顯然不能為一個有著成熟物件導向經驗的設計者提供太多東西。而且事實上:它就是沒什麼大不了。一個我認識的朋友說:設計模式:“使用指標的23種方式”。這也沒什麼大不了的。

  同樣的,如果一個經理/高階團隊leader/架構師給一個新手丟過去這本書,希望他們在讀完這本書之後突然“升級”,他們會大失所望。好處,似乎就更小了:

我們希望你用不同的方式思考。一份設計模式的目錄是重要的。它讓我們使用的一些技術有了通用的名字。如果我們不學習軟體裡的設計模式,我們就不能改進它們,如果出現新的模式我們解決起來就會更難。

  顯然,設計模式催生了一場運動,並且模式運動誕生在原始的23中GOF設計模式上。但是,事情慢慢變得更抽象並且高階了。模式變成了“模式語言”,然後變成了“元-模式”(meta-patterns)。接著人們開始記錄它的負面影響,稱作“反模式”(anti-patterns)。

  當人們察覺到這可以賺錢,於是相關的書就開始爛大街。

  很多出版社開始出版“模式”概念的書,但是離GOF最初的模型相差甚遠。模式的書成為“可複用的程式碼”的同義詞(不再是“reusable elements of design”)。IDE產商開始尋找方式整合模式:以程式碼生成器的方式。不知為什麼模式也成為了UML和其他設計的註解,某個目標是在UML想出怎樣建立出與之對應模式的可複用的設計模板(the goal at one point was to figure out how to create reusable design templates in UML that corresponded to patterns.)。

  就像上面提到這些事,模式開始變得流行並且吸引那些不知道模式是什麼的人。他們怎麼可能滿足這些人的期望呢?

  在2000年左右,模式開始成為一個不好的詞,發言人開始大範圍“清理”模式,說模式是人造的“爛語言”、“原始的思考方式”,應該“歸入好的語言”。(an artifact of “bad languages” and “primitive thnking” and “subsumed into good languages”.)

  模式顯然是沒用的。

  可是...他們依然持續出現。我們一直使用他們的術語(terms and lingo)。為什麼?GOF把它稱作回到1995(在書後面的同一章):

“設計模式為設計者提供了一套通用的詞彙表來交流,記錄文件或者探索設計。設計模式用一個更高的抽象創造了一個更簡單系統相比用程式語言描述一個設計思路。設計模式提高了你的設計和同事討論設計的高度。”(p389)

  還有:

 “理解這本書裡的設計模式可以讓你更容易的理解現有的系統。學習物件導向程式設計的人常抱怨他們使用了繼承的系統在流的控制上難以理解。很大的原因是因為他們沒有理解系統裡的設計模式。學習這些設計模式可以幫助你理解現有的物件導向系統。”(p389)

  還有:

“設計模式提供了一種能更多的說明“為什麼”這麼設計而不只是記錄你決定的結果。一個設計模式的Applicability, Consequences, 和Implementation幫助指導你應該做出什麼樣的選擇。”

  還有:

“開發可複用軟體的一個問題是它常需要重新組織或者重構。設計模式幫助你決定怎麼重新組織設計,可以減少今後你需要重構的次數。”

  (是的。在重構流行很久以前他們就在討論重構了。)

  最重要的是,他們準確的預言了模式會作為一個整體衰敗的原因:

“最簡單的對待模式就是把它當做一種解決方案,作為一項可以被適用、重用的技術。難的是發現它什麼時候合適--最佳的解決面對的問題和所處的上下文的方案。通常看出某個人做了什麼比為什麼這麼做容易,為什麼這麼做對於一個模式就是它要解決的問題。知道一個模式的目的也非常重要,因為它是我們選擇這個模式的原因。它也幫助我們理解這個系統的設計。一個模式的作者必須查明和刻畫出這個模式解決的問題,即使在你已經發現了這個解決方案後。” (p393)

  太多短視的人看到了“解決方案”,他們急著發現可以重用的程式碼,他們忘記了去思考“為什麼”,結果就是他們會犯下一些非常愚蠢的錯誤。

  一個模式是什麼?

  關於這點的討論已經有很多年了,但是我會用下面這句話終結這個問題:

  一個模式是一個解決方案:一個在特定上下文裡並且有著可預見的影響變化的問題的解決方案。(A pattern is a solution to a problem within a certain context that has a set of predictable consequences.)

  就這麼多。沒有什麼神奇的、神祕的或者非常學院派的描述。如果你能描述這四個部分(問題、上下文、可預見的影響變化、解決方案),你就有了一個模式。把它寫下來,然後發表到某個地方。當我們遇見一些相似的問題,我們可以開始找出其中的共性,然後取一個好聽的名字,然後它就可以加入“詞彙表”了。

  GOF釋出了其中的23個。在這此外存在著更多的模式。大部分都非常有用。尤其是最初的23個,因為它從一大堆不同的語言裡提煉出來(之後出現的很多模式和某種特定語言繫結在一起)。

  為什麼我們再次討論?

  上一句,引出了另外一個重要的地方:太多的模式社群花了太多時間爭論它們,給出的這個是不是一個模式,或者某段程式碼是這個模式還是那個模式,或者...

  可以從三點考慮這些問題:

  圍繞一個模式的構成的辯論對於模式所提供的好處是重要的。這就是為什麼模式的社群總是說“除非被發現了三次它才是一個模式”或者“一個模式除非在模式會議上研討過否則就不是一個真正的模式”。這樣做不是為了增加神祕感,或者讓社群裡的人能夠知道。這樣的目的是為了通過在思維上的辯論提煉這個模式的本質,保證它的高品質。 一旦人們開始說“Pfffft”已經避免了這些受爭議的步驟,就會突然間什麼都成為了一個模式。如果突然我們開始管本地變數叫做一個模式,我們所有的關於設計高度抽象的工具箱和術語就失去了意義。如果任何人都可以稱任何東西是一個“模式”,那麼我們就會這麼做,在交談中模式就失去了它原本的語義。如果模式只是在本地團隊裡產生的,那就無法和團隊外的人交流它。科學需要嚴謹,這就是模式社群希望帶來的東西。

  這個地方使用的是什麼模式就是一場哲學的辯論。很多人會沉溺在和其他團隊成員討論某些程式碼是什麼模式。我都想不出更無聊的活動了,除非這個討論能在這個模式上引出新的洞見。在這個問題上討論會消耗很多人與人之間的善意。

  一個好的設計不需要全是模式。 你可以有一個好的設計而不是任何一個已知的模式。

  是時候把它們拿回來了

  20過去了,我覺得是時候了重新開始討論了。我不會想象通過我自己重建整個運動,但是至少,我可以這些老東西的灰塵擦乾淨,希望把它帶進21世紀裡我們使用的語言。作者最後大概說會重新把最初的23種模式整理成適合現代語言的樣子。也就是第一段中提到和經過20年發展裡的語言的對比。

  原文:Reclaiming Design Patterns (20 Years Later)

相關文章