學習設計模式以前最好先了解一下設計模式的設計原則:java
1. 開閉原則(open close principle)git
開放即指對擴展開放,對修改關閉 簡而言之,就是擴展功能的時候應該儘可能的不修改原有的代碼。github
2. 里氏代換原則(liskov substitution principle)編程
能夠簡單理解爲派生類與基類的替換關係,一旦程序中出現基類,那麼這個基類如果唄派生類替換了,也應該是合適的,而且對程序功能不受影響,該原則其實是開閉原則的補充。 基類能真正複用,派生類也可以在基類的基礎上增長新的行爲。實現開閉原則的關鍵步驟就是抽象化,而基類與子類的繼承關係就是抽象化的具體實現,因此里氏代換原則是對實現抽象化的具體步驟的規範。設計模式
3. 依賴倒轉原則(dependence inverse principle)緩存
這個原則是開閉原則的基礎,具體內容:針對接口編程,依賴於抽象而不依賴於具體。安全
4. 接口隔離原則(Interface Segregation Principle)多線程
使用多個隔離的接口,比使用單個接口要好,該模式出發點在與大一點的軟件設計架構,便於維護升級,下降耦合度。架構
5.迪米特法則,又稱最少知道原則(Demeter Principle)性能
一個實體應當儘可能少地與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。
6. 合成複用原則(Composite Reuse Principle)
儘可能使用合成/聚合的方式,而不是使用繼承。
隱藏建立對象的建立邏輯,提供建立對象的接口,而非使用new關鍵字進行建立。
隱藏建立的對象的邏輯,經過共同對的接口建立對象。
實現demo結構以下圖,實現demo代碼點這裏這是我學習的時候寫的demo
這個模式是工廠的共工廠 叫超級工廠模式還比較貼切,在抽象工廠模式中,接口是負責建立一個相關對象的工廠,不須要顯式指定它們的類。每一個生成的工廠都能按照工廠模式提供對象。
一個類負責建立本身的對象,同時確保只有單個對象被建立。這個類提供了一種訪問其惟一的對象的方式,能夠直接訪問,不須要實例化該類的對象
public class Singleton_unsupport_multithread { private Singleton_unsupport_multithread() { // TODO Auto-generated constructor stub **} private static Singleton_unsupport_multithread instance; public static Singleton_unsupport_multithread getSingleton() { if (instance == null) { instance = new Singleton_unsupport_multithread(); } return instance; } public void println() { System.out.println("In unsupport_multithread"); } }
public class Singleton_support_multithread { private Singleton_support_multithread() { // TODO Auto-generated constructor stub } private static volatile Singleton_support_multithread instance; /** * 第一個判斷能夠減小鎖住對象的狀況 若是不爲空直接返回 效率更高 * 第二個判斷就是懶加載的判斷 * * @return */ public static Singleton_support_multithread getInstance() { if (instance == null) { synchronized (Singleton_support_multithread.class) { if (instance == null) instance = new Singleton_support_multithread(); } } return instance; } }
/** * * @author Vincent * 線程安全 可是容易產生垃圾對象,沒有加鎖執行效率會比較高 * 但不是懶加載 類一加載的時候就進行初始化 浪費內存 * */ public class Singleton_hungry_man { private Singleton_hungry_man() { // TODO Auto-generated constructor stub } private static Singleton_hungry_man instance = new Singleton_hungry_man(); public static Singleton_hungry_man getInstance() { return instance; } }
/** * * @author Vincent * 登記註冊式 單例 * 這裏其實與前面的餓漢單例模式有點相似 可是因爲利用了ClassLoaderDe特性 * 使在不調用的getInstance的時候不會初始化instance 實現了懶加載 * */ public class Singleton_register { private static class SingletonHolder { private static Singleton_register instance = new Singleton_register(); } private Singleton_register() { // TODO Auto-generated constructor stub } public static final Singleton_register getInstance() { return SingletonHolder.instance; } }
/** * * @author Vincent * 講道理哦 這個方式最方便的單例模式 * 利用枚舉 自帶支持 序列化機制 防止反序列化屢次建立對象 能夠適應多線程 然而卻不怎麼受待見 大多數人不用這個方式 可能和習慣有關係吧 = = * */ public enum Singleton_enum { Instance; }
使用多個簡單的對象一步一步構建成一個複雜的對象。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。值得一說的是感受是這個設計模式 感受更加註重內部對象的細節,內部零件裝配的順序。
用於建立重複的對象,同時又能保證性能
這種模式是實現了一個原型接口,該接口用於建立當前對象的克隆。當直接建立對象的代價比較大時,則採用這種模式。
這個模式感受一通常和工廠模式一塊兒使用的比較多 比較方便
這些設計模式關注類和對象的組合。繼承的概念被用來組合接口和定義組合對象得到新功能的方式。
將一個類的接口轉換成客戶但願的另一個接口。適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
是用於把抽象化與實現化解耦,使得兩者能夠獨立變化,目的就是爲了抽象與實現分離,均可以有獨立的變化,用抽象類依賴實現類來實現。
這裏簡單說一下橋接模式與適配器模式的區別:從名字來理解比較容易理解,適配器嘛 那就是已經有了一些功能類,可是須要一個新的功能,這個時候不必寫重複的或者說如今有可重用的功能,就須要適配器了,打個比方,你如今有一個type-c接口的手機,還有一個圓孔耳機,手機是能夠不必再「鑽」一個圓孔耳機孔,而耳機也不能錘扁爲type-c,這個時候type-c轉接頭就來了,這就是一個適配器;可是橋接模式中,有一個根本的區別就是橋接模式一開始設計就是這樣的架構,是爲了可擴展,而不是設配器模式是爲了解決問題而誕生的,這是一種設計最初就存在的模式,橋接模式通常是一個抽象實體類,而後內部擁有功能接口的引用,這種結構很方便功能實現類的擴展,還有實體類的擴展。
這個模式容許開發人員使用不一樣的標準過濾一組對象,經過該邏輯運算易解耦合的方式把他們鏈接起來,經過結合多個標準來得到一個標準。
把一組類似的對象看成一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及總體層次,建立了對象組的樹形結構,建立了一個包含本身對象組的類,該類提供修改對象組的方式。
容許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是做爲現有的類的一個包裝。
這種模式建立了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。
該模式會隱藏系統複雜性,向現有的系統添加了一個接口。好比 電腦來說,開啓電腦的是會同時開啓CPU,硬盤,內存,可是咱們只管開啓電腦而不須要知道其中內部的實現。
爲了減小建立對象的數量來減小內存的佔用提升性能,是對現有的對象嘗試重用,若是沒找到匹配的對象,則建立新的對象。好比:在String類中,會把建立多的字符串放在字符串緩存池裏邊。
注意:
1.要區別出對象的內部狀態與外部狀態,不然容易有引發一些線程問題 1.通常與工廠模式混合使用,便於對象的管理
在代理模式中,咱們建立具備現有對象的對象,以便向外界提供功能接口,爲其餘對象提供一個代理以控制對這個對象的訪問。主要是爲了隱藏被代理類的內部實現。
這些設計模式特別關注對象之間的通訊
請求建立了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發送者和接收者進行解耦在這種模式中,一般每一個接收者都包含對另外一個接收者的引用。若是一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。
一種數據驅動的設計模式,請求以命令的形式包裹在對象中,並傳給調用對象。調用對象尋找能夠處理該命令的合適的對象,並把該命令傳給相應的對象,該對象執行命令
提供了餘元的語法或表達式的方式,屬於行爲模式,這種模式實現了一個表達式接口,該接口解釋一個特定的上下文,通常用於SQL解析,符號處理解析引擎之類。這個模式通常比較少見。
這個模式用於順序訪問集合對象的元素,而不須要知道底層對象的表示。
用於下降多個對象和類之間的通訊複雜性。提供了中介類,這個中介類負責處理不一樣類之間的通訊,使系統降耦合。
適用場景:系統對象之間存在比較複雜的引用關係,致使他們之間的依賴關係結構混亂難以複用;或者想經過一箇中間類封裝多個類中的行爲,而又不想生成太多的子類。
當對象存在一對多的關係時候,好比:一個對象被修改的時候,就會通知他它的依賴對象。<br/>
實現方式:在抽象類裏使用觀察者列表。
注意事項: 使用的時候不要循環引用
類的行爲是根據其狀態而定的,在狀態模式中,一般建立的表示狀態的對象和一個行爲隨着狀態對象改變而改變的context對象。
容許對象在內部狀態發生改變的時候改變它的行爲。
一個可能空對象取代null對象的例的檢查,null對象不是檢查空值,而是反應一個不作任何動做的關係,這樣的null對象也能夠在數據不可用的時候提供默認的行爲。
空對象模式中,一般建立一個指定各類要執行的操做的抽象類和擴展該類的實體類,而後建立未對該類作任何實現的空對象類,該類能夠無縫的使用在須要檢查空值的地方。
這些設計模式特別關注表示層。這些模式是由 Sun Java Center 鑑定的。