但一到實際的項目設計和開發的時候,每每都會陷入迷茫:要麼無從下手,不知道哪一個地方要用設計模式;要麼生搬硬套。胡亂使用設計模式。將方案和代碼搞得一團亂麻。設計模式
形而下者謂之器。形而上者謂之道。學習
---《易經·繫辭》編碼
正如很是多流行的技術(面向對象、UML等)同樣,差點兒大部分人都會宣稱本身「掌握、熟練掌握」,甚至「精通」。然而。真正掌握的或者精通的,實在是少之又少。spa
一種典型的現象是:很是多人能夠熟練背誦出全部的設計模式,能夠高速畫出各類設計模式的UML類圖。也能夠熟練的寫出《設計模式》一書中各個模式的例子代碼。.net
但一到實際的項目設計和開發的時候,每每都會陷入迷茫:要麼無從下手,不知道哪一個地方要用設計模式。要麼生搬硬套。胡亂使用設計模式,將方案和代碼搞得一團亂麻。翻譯
這是什麼緣由呢,難道是設計模式很差用,或者設計模式根本就是一個噱頭?設計
答案不在於設計模式自己是否實用,而是在於咱們沒有掌握正確的學習和應用設計模式的方法。orm
學習《設計模式》一書中的23個設計模式,僅僅是掌握了《設計模式》的「器」,但並無掌握設計模式的「道」。對象
就像一個工匠,鋸、鑽、錘、刨樣樣精通。但假設不知道什麼地方該用鋸,什麼地方該用鑽,確定是一個不合格的工匠。爲了能夠更好的學習和應用設計模式。咱們也需要掌握設計模式的「道」。blog
設計模式的「道」就是用來指導咱們何時用設計模式,爲何要用設計模式。23個設計模式僅僅是告訴了咱們how。而設計模式之道卻能夠告訴咱們why和where!
熟悉《設計模式》一書內容的同窗可能會想到:《設計模式》一書中,不是每個模式都有「適用性」的說明麼?這個事實上就是回答了where和why的問題啊!
好比:Facade模式的「適用性」說明例如如下(摘自《設計模式》中文版一書):
上面這一段文字,看起來回答了where和why的問題,但實際上我我的感受做用並不大。
首先。這段描寫敘述太長了:以上這段文字是否花了你幾分鐘的時間去閱讀和理解?
其次,這段描寫敘述比較抽象:什麼事複雜,什麼叫作簡單。什麼叫作很是大依賴性。。。。。。
可能每個人理解都不同。
再者,23個模式,全部的「適應性」條款加起來預計有幾十條條,你能夠背住麼?即便你能夠全部背住。你能夠全部理解麼?即便你能夠全部理解,當面對一個具體問題的時候,你知道幾十條裏面哪一條適應你的狀況麼?
因此,《設計模式》一書關於「適用性」的描寫敘述。實際上仍是太複雜,太多了,不具有很是強的實踐知道意義和可操做性。
咱們需要的是一個更簡單的指導思想,大道至簡,最好是一兩句話就行描寫敘述。
幸運的是,答案竟然就在《設計模式》一書中,但這個答案並不是那麼明顯!
《設計模式》一書的內容側重點是23個模式的具體闡述,大部分人可能都是直奔主題。逐一去研究每個模式。而對於開頭部分第1章和第2章的內容並無具體研讀和思考,或者對於這兩章僅僅是簡單的瀏覽。並未認真領會和思考。由此錯過了最重要的內容。再加上GoF在這2章的內容中。既要引入一個全新的概念,又要提綱挈領的介紹各個模式,還要引入實例進行分析,以致於大量的內容將真正核心的內容反而給淹沒或者沖淡了。
設計模式之道就隱藏在「2.6.2 封裝實現依賴關係」的最後一段,很是easy的一句話:
對變化的概念進行封裝(encapsulate the concept that varies)
你看到這句話可能有點失望,前面分析了那麼久,賣了那麼多的關子,結果就這麼簡簡單單一句話。這不是在忽悠麼?
你可千萬別小看了這句話,「大道至簡」,設計模式之道也不例外,但「簡」並不意味着沒用。相反,正因爲其「簡」,每個人的理解才一致,也更好掌握,實踐中才更好應用。正所謂:「真傳一句話。假傳萬卷書」。
GoF在《設計模式》一書中最先提出這個原則。後來不斷的有其它專家進行闡述,當中《設計模式精解》(《Design pattern explained》)一書的闡述我以爲是最精闢的:Find what varies and encapsulate it,翻譯一下即「找到變化,封裝變化」。
儘管含義和GoF描寫敘述的基本一致,但其更加容易理解。
正所謂:踏破鐵鞋無覓處,得來全不費工夫。
現在,讓咱們來深刻理解「找到變化,而後封裝變化」的設計模式之道。
首先。「找到變化」攻克了「在哪裏」使用設計模式的問題。即回答了「where」的問題。
「找到變化」看起來是比較抽象的一句話,但在實踐中很是好應用和操做,而且不一樣領域、不一樣行業的系統均可以完美的應用這句話。
儘管不一樣領域、不一樣行業變化的因素、方式、時機等都不同,但每個領域或者行業的需求分析人員、設計人員,對本身所處行業和領域的可能變化確定是有比較深入的理解的,什麼會變化、會如何變化、何時會變化。。。。
。。等等,確定均可以本身推斷,這樣的推斷並不需要什麼高深的技巧和知識水平。僅僅需要必定的經驗積累。
假設咱們剛接觸一個行業或者領域,經驗積累並不夠。那怎麼辦呢?是否就沒法「找到變化」了?
事實上也否則,有一個萬能的辦法,僅僅是要花費不少其它的精力了。
個人這個萬能辦法就是「惟一不變的是變化自己」,也就是說,假設你不知道什麼會變化,那麼就抱着懷疑一切的想法,一切均可能是變化的。
但光有這條指導原則還不行,假設咱們真的抱着「一切都是可能變化的」想法。而後封裝一切變化,那麼就會陷入變化的漩渦沒法自拔,因爲變化是會遞歸的。A可能變成B,B也可能繼續變化。因而這樣無窮無盡,系統是不可能作出來的。
因此咱們需要一個終止條件,避免陷入無窮無盡的變化遞歸漩渦。這個終止條件就是「有限時間內可能發生的變化」。這裏的「有限時間」隨行業和領域的不一樣而變化。好比(下面時間僅供參考):
互聯網行業能夠說:半年內可能發生的變化。。。。。
。
電信行業能夠說:1年內可能發生的變化。。。。
。。
金融行業能夠說:2年內可能發生的變化。。。
。
。。
政府行業能夠說:3年內可能發生的變化。
。。
。
。
。
有了這個指導原則後,你能夠這樣去問有經驗的前輩、大蝦、大牛等: XXX在1年內會發生變化麼?會如何變化?
就這樣,即便你是菜鳥,經過這麼一招「借花獻佛」。也能夠輕鬆發現「變化」的地方。
其次,「封裝變化」攻克了「爲何」使用設計模式的問題,即回答了「why」的問題。
爲何咱們要用設計模式,是因爲咱們要封裝變化!但咱們爲何要封裝變化呢?
答案很是明顯:變化很差!
固然這個「很差」不是從業務的角度來講的。而是從系統的角度來講的。從業務的角度來講。「變化」是好的,變化意味着新的機會;但從系統的角度來講,變化並很差,因爲變化一定要求系統修改,修改就意味着風險!
儘管變化給系統帶來風險,但咱們不能所以而「拒絕變化」,因爲拒絕變化就意味着失去了機會,簡單來講。賺不到錢的系統,設計再優美,功能再強大。系統再穩定。也只是是一堆沒用的擺設:
客戶給你提了新需求,你不作。能拿到合同麼。
。
。。。。
行業正在興起新的流行功能,你不作,你的系統有人用麼。。。。。
。
一項創新帶來了新的機遇,你不作。能搶佔市場麼。
。。。。。
因此咱們要「擁抱變化」,但咱們又不能讓變化帶來太大的風險,因此就提出了「封裝變化」。「封裝變化」意味着將變化的影響範圍控制最小,將風險降到最低。
咱們來看看,變化會帶來哪些問題和風險:
1)開發者需要編碼以適應變化,設計很差的方案將致使大量的編碼工做量、自測工做量。
2)測試人員不單要測試因變化而新增的那部分,還要測試受影響的部分,設計很差的方案,牽一髮而動全身,致使測試工做量大大添加。
3)假設爲了適應某個變化而對系統作了比較大的修改,則系統的質量風險將上升。很是可能致使上線失敗,或者上線後出現各類問題;
所以。咱們要儘可能下降變化帶來的工做量和風險,而下降的最有效方法就是將變化的影響範圍縮小,即:將變化封裝起來。使其僅僅在有限的範圍內有影響。
就像一個武林高手有了深厚的內功。天下萬物皆可成爲手中的利器,而沒必要拘泥於具體的武器和招數同樣。掌握了設計模式之道後。咱們事實上也全然能夠不拘泥於僅僅是用《設計模式》一書中的23個設計模式,能夠依據需要選擇最合適的方案。
好比:
不一樣的業務有不一樣的規則排列組合。規則引擎能夠封裝各類變化的規則。。
。。。
。
類之間的依賴是變化的。Spring使用XML配置文件來封裝這樣的變化。
。
。。。。
每個銀行的卡都不同,銀聯封裝了這樣的變化,使得不一樣銀行能夠互通。。。。。
。
總之。你可使用類和設計模式來封裝變化,你也可使用配置文件和模塊來封裝變化,你也可使用一個系統來封裝變化。。
。。
。。
================================================
轉載請註明出處:http://blog.csdn.net/yunhua_lee/article/details/38315995
================================================