轉載https://www.imooc.com/article/282435
設計模式常見面試知識點總結
你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,了解一下Markdown的基本文法知識。
單例
單例模式保證全局的單例類隻有一個執行個體,這樣的話使用的時候直接擷取即可,比如資料庫的一個連接配接,Spring裡的bean,都可以是單例的。
單例模式一般有5種寫法。
第一種是餓漢模式,先把單例進行執行個體化,擷取的時候通過靜态方法直接擷取即可。缺點是類加載後就完成了類的執行個體化,浪費部分空間。
第二種是飽漢模式,先把單例置為null,然後通過靜态方法擷取單例時再進行執行個體化,但是可能有多線程同時進行執行個體化,會出現并發問題。
第三種是逐漸改進的方法,一開始可以用synchronized關鍵字進行同步,但是開銷太大,而後改成使用volatile修飾單例,然後通過一次檢查判斷單例是否已初始化,如果未初始化就使用synchronized代碼塊,再次檢查單例防止在這期間被初始化,而後才真正進行初始化。
第四種是使用靜态内部類來實作,靜态内部類隻在被使用的時候才進行初始化,是以在内部類中進行單例的執行個體化,隻有用到的時候才會運作執行個體化代碼。然後外部類再通過靜态方法傳回靜态内部類的單例即可。
第五種是枚舉類,枚舉類的底層實作其實也是内部類。枚舉類確定每個類對象在全局是唯一的。是以保證它是單例,這個方法是最簡單的。
單例模式應用的場景一般發現在以下條件下:
(1)資源共享的情況下,避免由于資源操作時導緻的性能或損耗等。如上述中的日志檔案,應用配置。
(2)控制資源的情況下,友善資源之間的互相通信。如線程池等。
工廠模式
簡單工廠一般是用一個工廠建立多個類的執行個體。
工廠模式一般是指一個工廠服務一個接口,為這個接口的實作類進行執行個體化
抽象工廠模式是指一個工廠服務于一個産品族,一個産品族可能包含多個接口,接口又會包含多個實作類,通過一個工廠就可以把這些綁定在一起,非常友善。
原型模式
一般通過一個執行個體進行克隆進而獲得更多同一原型的執行個體。使用執行個體的clone方法即可完成。
建造者模式
建造者模式中有一個概念叫做鍊式調用,鍊式調用為一個類的執行個體化提供便利,一般提供系列的方法進行執行個體化,實際上就是将set方法改造一下,将原本傳回為空的set方法改為傳回this執行個體,進而實作鍊式調用。
建造者模式在此基礎上加入了builder方法,提供給外部進行調用,同樣使用鍊式調用來完成參數注入。
結構型模式
結構型模式
前面建立型模式介紹了建立對象的一些設計模式。
這節介紹的結構型模式旨在通過改變代碼結構來達到解耦的目的,使得我們的代碼容易維護和擴充。
擴充卡模式
擴充卡模式用于将兩個不同的類進行适配。
擴充卡模式和代理模式的異同
比較這兩種模式,其實是比較對象擴充卡模式和代理模式,在代碼結構上,
它們很相似,都需要一個具體的實作類的執行個體。
但是它們的目的不一樣,代理模式做的是增強原方法的活;
擴充卡做的是适配的活,為的是提供“把雞包裝成鴨,然後當做鴨來使用”,
而雞和鴨它們之間原本沒有繼承關系。
擴充卡模式可以分為類擴充卡,對象擴充卡等。
類擴充卡通過繼承父類就可以把自己适配成父類了。
而對象擴充卡則需要把對象傳入另一個對象的構造方法中,以便進行包裝。
享元模式
享元模式的核心在于享元工廠類,
享元工廠類的作用在于提供一個用于存儲享元對象的享元池,
使用者需要對象時,首先從享元池中擷取,
如果享元池中不存在,則建立一個新的享元對象傳回給使用者,
在享元池中儲存該新增對象。
代理模式
我們發現沒有,代理模式說白了就是做 “方法包裝” 或做 “方法增強”。
在面向切面程式設計中,算了還是不要吹捧這個名詞了,在 AOP 中,
其實就是動态代理的過程。比如 Spring 中,
我們自己不定義代理類,但是 Spring 會幫我們動态來定義代理,
然後把我們定義在 @Before、@After、@Around 中的代碼邏輯動态添加到代理中。
外觀模式
外觀模式一般封裝具體的實作細節,為使用者提供一個更加簡單的接口。
通過一個方法調用就可以擷取需要的内容。
組合模式
組合模式用于表示具有層次結構的資料,使得我們對單個對象群組合對象的通路具有一緻性。
直接看一個例子吧,每個員工都有姓名、部門、薪水這些屬性,
同時還有下屬員工集合(雖然可能集合為空),
而下屬員工和自己的結構是一樣的,
也有姓名、部門這些屬性,
同時也有他們的下屬員工集合。
class Employee {
private String name;
private String dept;
private int salary;
private List subordinates; // 下屬
}
裝飾者模式
裝飾者
裝飾者模式把每個增強類都繼承最進階父類。然後需要功能增強時把類執行個體傳入增強類即可,然後增強類在使用時就可以增強原有類的功能了。
和代理模式不同的是,裝飾者模式每個裝飾類都繼承父類,并且可以進行多級封裝。
行為型模式
行為型模式
行為型模式關注的是各個類之間的互相作用,将職責劃厘清楚,使得我們的代碼更加地清晰。
政策模式
政策模式一般把一個政策作為一個類,并且在需要指定政策的時候傳入執行個體,于是我們可以在需要使用算法的地方傳入指定算法。
指令模式
指令模式一般分為指令發起者,指令以及指令接受者三個角色。
指令發起者在使用時需要注入指令執行個體。然後執行指令調用。
指令調用實際上會調用指令接收者的方法進行實際調用。
比如遙控器按鈕相當于一條指令,點選按鈕時指令運作,自動調用電視機提供的方法即可。
模闆方法模式
模闆方法一般指提供了一個方法模闆,并且其中有部分實作類和部分抽象類,并且規定了執行順序。
實作類是模闆提供好的方法。而抽象類則需要使用者自行實作。
模闆方法規定了一個模闆中方法的執行順序,非常适合一些開發架構,于是模闆方法也廣泛運用在開源架構中。
觀察者模式和事件監聽機制
觀察者模式一般用于訂閱者和消息釋出者之間的資料訂閱。
一般分為觀察者和主題,觀察者訂閱主題,把執行個體注冊到主題維護的觀察者清單上。
而主題更新資料時自動把資料推給觀察者或者通知觀察者資料已經更新。
但是由于這樣的方式消息推送耦合關系比較緊。并且很難在不打開資料的情況下知道資料類型是什麼。
知道後來為了使資料格式更加靈活,使用了事件和事件監聽器的模式,事件包裝的事件類型和事件資料,從主題和觀察者中解耦。
主題當事件發生時,觸發該事件的所有監聽器,把該事件通過監聽器清單發給每個監聽器,監聽得到事件以後,首先根據自己支援處理的事件類型中找到對應的事件處理器,再用處理器處理對應事件。
責任鍊模式
責任鍊通常需要先建立一個單向連結清單,然後調用方隻需要調用頭部節點就可以了,後面會自動流轉下去。
比如流程審批就是一個很好的例子,隻要終端使用者送出申請,根據申請的内容資訊,自動建立一條責任鍊,然後就可以開始流轉了。