一文了解設計模式的常見面試知識點
- 2019 年 10 月 7 日
- 筆記
設計模式
這篇總結主要是基於我設計模式系列的文章而形成的的。主要是把重要的知識點用自己的話說了一遍,可能會有一些錯誤,還望見諒和指點。謝謝
更多詳細內容可以到我的cdsn部落格上查看: https://blog.csdn.net/a724888
最後,如果想要更好地完成這部分內容的學習,建議大家還是去看一下原文。
創建型模式
創建型模式 創建型模式的作用就是創建對象,說到創建一個對象,最熟悉的就是 new 一個對象,然後 set 相關屬性。但是,在很多場景下,我們需要給客戶端提供更加友好的創建對象的方式,尤其是那種我們定義了類,但是需要提供給其他開發者用的時候。
單例
單例模式保證全局的單例類只有一個實例,這樣的話使用的時候直接獲取即可,比如資料庫的一個連接,Spring里的bean,都可以是單例的。 單例模式一般有5種寫法。 第一種是餓漢模式,先把單例進行實例化,獲取的時候通過靜態方法直接獲取即可。缺點是類載入後就完成了類的實例化,浪費部分空間。 第二種是飽漢模式,先把單例置為null,然後通過靜態方法獲取單例時再進行實例化,但是可能有多執行緒同時進行實例化,會出現並發問題。 第三種是逐步改進的方法,一開始可以用synchronized關鍵字進行同步,但是開銷太大,而後改成使用volatile修飾單例,然後通過一次檢查判斷單例是否已初始化,如果未初始化就使用synchronized程式碼塊,再次檢查單例防止在這期間被初始化,而後才真正進行初始化。 第四種是使用靜態內部類來實現,靜態內部類只在被使用的時候才進行初始化,所以在內部類中進行單例的實例化,只有用到的時候才會運行實例化程式碼。然後外部類再通過靜態方法返回靜態內部類的單例即可。 第五種是枚舉類,枚舉類的底層實現其實也是內部類。枚舉類確保每個類對象在全局是唯一的。所以保證它是單例,這個方法是最簡單的。
工廠模式
簡單工廠一般是用一個工廠創建多個類的實例。 工廠模式一般是指一個工廠服務一個介面,為這個介面的實現類進行實例化 抽象工廠模式是指一個工廠服務於一個產品族,一個產品族可能包含多個介面,介面又會包含多個實現類,通過一個工廠就可以把這些綁定在一起,非常方便。
原型模式
一般通過一個實例進行克隆從而獲得更多同一原型的實例。使用實例的clone方法即可完成。
建造者模式
建造者模式中有一個概念叫做鏈式調用,鏈式調用為一個類的實例化提供便利,一般提供系列的方法進行實例化,實際上就是將set方法改造一下,將原本返回為空的set方法改為返回this實例,從而實現鏈式調用。 建造者模式在此基礎上加入了builder方法,提供給外部進行調用,同樣使用鏈式調用來完成參數注入。
結構型模式
結構型模式 前面創建型模式介紹了創建對象的一些設計模式。 這節介紹的結構型模式旨在通過改變程式碼結構來達到解耦的目的,使得我們的程式碼容易維護和擴展。
橋接模式
有點複雜。建議參考原文
適配器模式
適配器模式用於將兩個不同的類進行適配。 適配器模式和代理模式的異同 比較這兩種模式,其實是比較對象適配器模式和代理模式,在程式碼結構上, 它們很相似,都需要一個具體的實現類的實例。 但是它們的目的不一樣,代理模式做的是增強原方法的活; 適配器做的是適配的活,為的是提供「把雞包裝成鴨,然後當做鴨來使用」, 而雞和鴨它們之間原本沒有繼承關係。 適配器模式可以分為類適配器,對象適配器等。 類適配器通過繼承父類就可以把自己適配成父類了。 而對象適配器則需要把對象傳入另一個對象的構造方法中,以便進行包裝。
享元模式
享元模式的核心在於享元工廠類, 享元工廠類的作用在於提供一個用於存儲享元對象的享元池, 用戶需要對象時,首先從享元池中獲取, 如果享元池中不存在,則創建一個新的享元對象返回給用戶, 在享元池中保存該新增對象。
代理模式
我們發現沒有,代理模式說白了就是做 「方法包裝」 或做 「方法增強」。 在面向切面編程中,算了還是不要吹捧這個名詞了,在 AOP 中, 其實就是動態代理的過程。比如 Spring 中, 我們自己不定義代理類,但是 Spring 會幫我們動態來定義代理, 然後把我們定義在 @Before、@After、@Around 中的程式碼邏輯動態添加到代理中。
外觀模式
外觀模式一般封裝具體的實現細節,為用戶提供一個更加簡單的介面。 通過一個方法調用就可以獲取需要的內容。
組合模式
組合模式用於表示具有層次結構的數據,使得我們對單個對象和組合對象的訪問具有一致性。 直接看一個例子吧,每個員工都有姓名、部門、薪水這些屬性, 同時還有下屬員工集合(雖然可能集合為空), 而下屬員工和自己的結構是一樣的, 也有姓名、部門這些屬性, 同時也有他們的下屬員工集合。 class Employee { private String name; private String dept; private int salary; private List<Employee> subordinates; // 下屬 }裝飾者模式
裝飾者
裝飾者模式把每個增強類都繼承最高級父類。然後需要功能增強時把類實例傳入增強類即可,然後增強類在使用時就可以增強原有類的功能了。
和代理模式不同的是,裝飾者模式每個裝飾類都繼承父類,並且可以進行多級封裝。
行為型模式
行為型模式 行為型模式關注的是各個類之間的相互作用,將職責劃分清楚,使得我們的程式碼更加地清晰。
策略模式
策略模式一般把一個策略作為一個類,並且在需要指定策略的時候傳入實例,於是我們可以在需要使用演算法的地方傳入指定演算法。
命令模式
命令模式一般分為命令發起者,命令以及命令接受者三個角色。 命令發起者在使用時需要注入命令實例。然後執行命令調用。 命令調用實際上會調用命令接收者的方法進行實際調用。 比如遙控器按鈕相當於一條命令,點擊按鈕時命令運行,自動調用電視機提供的方法即可。
模板方法模式
模板方法一般指提供了一個方法模板,並且其中有部分實現類和部分抽象類,並且規定了執行順序。 實現類是模板提供好的方法。而抽象類則需要用戶自行實現。 模板方法規定了一個模板中方法的執行順序,非常適合一些開發框架,於是模板方法也廣泛運用在開源框架中。
觀察者模式和事件監聽機制
觀察者模式一般用於訂閱者和消息發布者之間的數據訂閱。 一般分為觀察者和主題,觀察者訂閱主題,把實例註冊到主題維護的觀察者列表上。 而主題更新數據時自動把數據推給觀察者或者通知觀察者數據已經更新。 但是由於這樣的方式消息推送耦合關係比較緊。並且很難在不打開數據的情況下知道數據類型是什麼。 知道後來為了使數據格式更加靈活,使用了事件和事件監聽器的模式,事件包裝的事件類型和事件數據,從主題和觀察者中解耦。 主題當事件發生時,觸發該事件的所有監聽器,把該事件通過監聽器列表發給每個監聽器,監聽得到事件以後,首先根據自己支援處理的事件類型中找到對應的事件處理器,再用處理器處理對應事件。
責任鏈模式
責任鏈通常需要先建立一個單向鏈表,然後調用方只需要調用頭部節點就可以了,後面會自動流轉下去。 比如流程審批就是一個很好的例子,只要終端用戶提交申請,根據申請的內容資訊,自動建立一條責任鏈,然後就可以開始流轉了。