設計模式,先看名字,設計,模式,目的是為了設計,為了設計給出一些定義出來的,總結出來的,抽象出來的辦法,叫做模式。
設計是什么?軟件構建中的設計,承前(需求分析、產品定義、架構選擇),啟后或者伴隨(編碼、測試),包含結構、包、類、子程序,而模式講的就是這些東西。
# 設計模式是一種思想
這次關于設計模式的分享不是純技術,是思想。
思想的東西,很難講,需要聽眾具備恰當的理解層次,而這種層次的進化,遠比一種技術或者工具的進步難以捉摸,有時十年循環不如一夕頓悟。
設計模式是一種思想,是與語言強相關的。
在低級語言(機器、匯編)中,不會有模式;在未來的高級語言中,會從語法層面實現模式(模式本身是語義層面的);在當前廣泛使用的高級語言(Java)中,模式被基于解決特定場景的問題,抽取出來,大行其道,廣泛使用。
低級語言和高級語言,沒有一條分界線,是逐漸進化的。每個程序員都處于其所在的層次上(或者叫境界),處于一個層次,能理解低層次的落后(比如機器語言),但無法理解高層次的先進。這就是《黑客與畫家》中所說的Blub困境。
引申到職場、人生和世界觀,每個人也都活在自己的抽象層次中,能看懂低層次的落后,但無法理解高層次先進在何處。從境界高低來講,是有對錯的,但如果沒有進化到一個層次,也是無法從根本上被說服的,需要到達,才能認知。
# 面向對象的三大特征
面向對象三大特性:封裝、繼承、多態。
封裝,往往和抽象、高內聚、一致的抽象層次等概念聯系在一起。
繼承是一條豎線,在編程中很常用,但更常用的是包含("has a"),從廣義上來說,甚至可以認為"has a",也是一種適配器模式。能用包含,則不用繼承,因為繼承引入了繼承體系上的復雜性。
多態是繼承基礎上的重寫,加上父類變量對子類對象的引用。可以認為多態,是Java這種靜態類型語言,向動態類型語言(比如ruby/python),邁出的一小步。
抽象:
抽取事物最本質形成概念。
并運用概念進行推理、判斷的思維活動。
抽象交流。
模擬能力,想象能力。
表達能力(口頭,文字,文言文和瓊瑤劇)。
字、詞、句、段.
# 單例
單例是最重要的一種設計模式。是無狀態的邏輯。無狀態是業務層實現高可用和可伸縮的重要手段。

### 單例一:基礎
演示了一個最簡單的單例、延遲初始化的單例,以及雙重檢查機制的單例的代碼寫法。
對于雙重檢查機制的單例,減小了線程間的碰撞(synchronized),只有前幾個線程才可能碰撞,鎖的力度小了,性能提高了,線程也安全了。
對于雙重檢查單例,沒有實際意義,只有歷史意義,增加Java程序員對于所犯錯誤的洞察力,如果寫單例,有最簡單的寫法就夠了。
過去陳舊的JDBC操作數據庫編碼過程中,有代碼Class.forName("com.mysql.jdbc.Driver"),目的是把類裝載到JVM的PermGen區域,這樣類的靜態方法就可以使用了,這和類的初始化沒關系。
顯式API初始化也有好處,比如web系統,init寫到監聽里面去。把初始化放到init里面。清晰了。
### 單例二:Spring
Java生態中,除了JDK之外,最基礎的框架是Spring。Spring框架的高層抽象很多,幫我們解決了很多場景下的技術問題。
Spring的基礎的、底層的思想是控制反轉(Invest Of Control)、依賴注入(Dependency Injection),可以認為是單例的一種表現形式。說的是兩個單例對象之間的關系。
控制反轉,反轉的控制權,原來是誰用誰有控制權;控制反轉的思想是,你可以用,但是我依然有初始化自己的控制權。
依賴注入,誰要用(就是誰依賴),誰負責把別的類引入進來。
寫簡簡單單的3個類,能解釋Spring的思想。讀取配置文件或者掃描Spring注解,利用反射實例化類,放置到一個Map中,這就是Spring IOC的基礎過程了。
結合《Spring技術內幕:深入解析Spring架構與設計原理》,花費1個星期簡要看看Spring源碼,發現就是這樣的。
### 單例三:狀態和線程安全
參考文章:[http://www.iteye.com/topic/960532](http://www.iteye.com/topic/960532)
有狀態:有狀態就是有數據存儲功能。
無狀態:無狀態的都是功能操作,對象是線程安全的。
幾個概念:維護全局狀態、控制狀態讀寫、線程安全。
以上指的是狀態的線程安全。對于HashMap的解釋,如果從狀態的線程安全絕度解釋,也是說的通的,HashMap里面有數組,也是有狀態的。
### 單例四:數據庫
狀態固化的單例:其實就是數據庫,每一行可以看作一個單例,它是系統唯一的,也可以是線程安全的。
跨JVM的單例:實現方式有很多,只要滿足有鎖的持久化即可。
多進程安全的單例:說的是數據庫鎖。
以上都是分布式的思想。
自從有了數據庫,程序員就變得廉價了。
# 其他的創建模式
工廠、抽象工廠、建造者、原型。
工廠:創建對象很復雜,所以需要一個創建對象的工廠。
建造者:比如耐克工廠,有鞋幫,有鞋帶,合起來之后是一個完整的整體,這就是建造者模式。
什么時候用單例,什么時候用單一狀態(類的單一狀態)。
為什么不全部用static,而用單例?有一種解釋是:控制反轉、依賴注入,這種思想。保留了初始化自己的控制權。如果完全的工具類,沒有初始化的需求,static就滿足了。
# 結構模式
開閉原則:對修改封閉,對擴展開放。
包裝(Composite):不想改變原代碼,又想實現某些功能。
代理(Proxy):舉了一個監護人的例子,讓吃才能吃。不改變語義,前前后后做點東西出來。
適配(Adapter):adapter比proxy更牛逼一些,它改變了語義,些許進行改造。
外觀(Facade):和代理先比,結構相似,語義不同。
繼承是標簽,接口表現了具備什么能力。
**面向對象一直爭論的問題:**
是用包含(用你的能力,但不打你的標簽,"has a"),還是用繼承("is a")。一種觀點認為,繼承對于軟件設計,引入了復雜性。
# 行為模式
行為模式,描述的是對象的動作。局限性,必須順序執行。???
模板:高層的流程抽象。
責任鏈:演示一個通過注解定義執行順序的歷程。好處:1.動態的組織流程;2. 代碼控制流程的執行;深化一下,就是工作流。
以上兩種模式,是重構的利器,加上反射,就可以寫通用功能的中間件了。
# 不是結束
設計模式是很枯燥的,記住三件事:創建一個對象、包裝一個對象、根據當前的場景,信手拈來。
農夫山泉:我們不生產水,我們只是大自然的搬運工。程序員不能成為農夫山泉,不能只是jar包的搬運工。要學會創造,一邊搬磚的時候,一邊想一想,如何創造出更優秀的東西。
單例/靜態、線程安全、無狀態,是從3個維度對軟件問題的描述,單例/靜態是思想角度(單例是設計模式,是語義層面的思想,靜態是編程語言從語法角度固化的思想),線程安全是技法角度(是一種基于現代的硬件基礎的、常見的、需要解決的,重要的問題場景),無狀態是數據角度(無狀態的類,實際就是不具備數據存儲能力的類)。
# 大師的話(linus)
爛程序員關心的是代碼。好程序員關心的是數據結構和它們之間的關系。
面向對象語言以對象為核心,加一些相關聯的方法,簡直是囈語。
重要的東西應該是數據結構,對象本身有啥重要?
真正有意思的,是在不同類型的不同對象交互而且有鎖規則的時候。
但是,即使是這時候,封裝什么“對象接口”也絕對錯誤,因為不再是單一對象的問題了。
他的結論是,面向對象解決的都是一些小問題。
這位大師是寫操作系統的,從他的角度來看,自然是正確的,即使不從他的角度,我們也可以認識到數據結構的重要性。
[http://www.csdn.net/article/1970-01-01/2824040](http://www.csdn.net/article/1970-01-01/2824040)
- 前言
- Java之旅--如何從草根成為技術專家
- 《深入理解Java虛擬機》學習筆記
- 《Spring3.X企業應用開發實戰》學習筆記--IoC和AOP
- 《Tomcat權威指南》第二版學習筆記
- Java之旅--多線程進階
- Java之旅--Web.xml解析
- 《Spring3.X企業應用開發實戰》學習筆記--DAO和事務
- 《Spring3.X企業應用開發實戰》學習筆記--SpringMVC
- Java之旅--定時任務(Timer、Quartz、Spring、LinuxCron)
- Spring實用功能--Profile、WebService、緩存、消息、ORM
- JDK框架簡析--java.lang包中的基礎類庫、基礎數據類型
- JDK框架簡析--java.util包中的工具類庫
- JDK框架簡析--java.io包中的輸入輸出類庫
- Java之旅--通訊
- Java之旅--XML/JSON
- Java之旅--Linux&java進階(看清操作系統層面的事)
- Java之旅--硬件和Java并發(神之本源)
- Java之旅--設計模式
- jetty