前言
設計模式在日常的工作中,是非常重要的一項技能,使用設計模式可以重構整體架構代碼、提交代碼復用性、擴展性、減少代碼冗余問題。這是每個 Java 工程師必備的技能!今日小編主要講的是設計模式之一的策略模式,小編會通過案例和面試題,帶你一步步由淺入深對策略模式進行解析。
小編分享的這份Java后端開發面試總結包含了JavaOOP、Java集合容器、Java異常、並發編程、Java反射、Java序列化、JVM、Redis、Spring MVC、MyBatis、MySQL數據庫、消息中間件MQ、Dubbo、Linux、ZooKeeper、 分布式&數據結構與算法等26個專題技術點,都是小編在各個大廠總結出來的面試真題,已經有很多粉絲靠這份PDF拿下眾多大廠的offer,今天在這里總結分享給到大家!【已完結】
完整版Java面試題地址:2021最新面試題合集集錦。
1.什么是設計模式
設計模式,是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程序的重用性。
2.為什么要學習設計模式
- 看懂源代碼:如果你不懂設計模式去看Jdk、Spring、SpringMVC、IO等等等等的源碼,你會很迷茫,你會寸步難行
- 看看前輩的代碼:你去個公司難道都是新項目讓你接手?很有可能是接盤的,前輩的開發難道不用設計模式?
- 編寫自己的理想中的好代碼:我個人反正是這樣的,對於我自己開發的項目我會很認真,我對他比對我女朋友還好,把項目當成自己的兒子一樣
3.設計模式分類

4.設計模式的六大原則
- 開放封閉原則(Open Close Principle)

- 里氏代換原則(Liskov Substitution Principle)

- 依賴倒轉原則(Dependence Inversion Principle)

- 接口隔離原則(Interface Segregation Principle)

- 迪米特法則(最少知道原則)(Demeter Principle)

- 單一職責原則(Principle of single responsibility)

5.單例模式
5.1 什么是單例
保證一個類只有一個實例,並且提供一個訪問該全局訪問點
5.2 哪些地方用到了單例模式
- 網站的計數器,一般也是采用單例模式實現,否則難以同步。
- 應用程序的日志應用,一般都是單例模式實現,只有一個實例去操作才好,否則內容不好追加顯示。
- 多線程的線程池的設計一般也是采用單例模式,因為線程池要方便對池中的線程進行控制
- Windows的(任務管理器)就是很典型的單例模式,他不能打開倆個
- windows的(回收站)也是典型的單例應用。在整個系統運行過程中,回收站只維護一個實例。
5.3 單例優缺點

5.4 單例模式使用注意事項:
- 使用時不能用反射模式創建單例,否則會實例化一個新的對象
- 使用懶單例模式時注意線程安全問題
- 餓單例模式和懶單例模式構造方法都是私有的,因而是不能被繼承的,有些單例模式可以被繼承(如登記式模式)
5.5 單例防止反射漏洞攻擊
private static boolean flag = false;
private Singleton() {
if (flag == false) {
flag = !flag;
} else {
throw new RuntimeException("單例模式被侵犯!");
}
}
public static void main(String[] args) {
}
5.6 如何選擇單例創建方式
如果不需要延遲加載單例,可以使用枚舉或者餓漢式,相對來說枚舉性好於餓漢式。 如果需要延 遲加載,可以使用靜態內部類或者懶漢式,相對來說靜態內部類好於懶韓式。 最好使用餓漢式
5.7 單例創建方式

1.餓漢式
- 餓漢式:類初始化時,會立即加載該對象,線程天生安全,調用效率高。
package com.lijie;
//餓漢式
public class Demo1 {
// 類初始化時,會立即加載該對象,線程安全,調用效率高
private static Demo1 demo1 = new Demo1();
private Demo1() {
System.out.println("私有Demo1構造參數初始化");
}
public static Demo1 getInstance() {
return demo1;
}
public static void main(String[] args) {
Demo1 s1 = Demo1.getInstance();
Demo1 s2 = Demo1.getInstance();
System.out.println(s1 == s2);
}
}




6.工廠模式
6.1 什么是工廠模式
它提供了一種創建對象的最佳方式。在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,並且是通過使用一個共同的接口來指向新創建的對象。實現了創建者和調用者分離,工廠模式分為簡單工廠、工廠方法、抽象工廠模式
6.2 工廠模式好處
- 工廠模式是我們最常用的實例化對象模式了,是用工廠方法代替new操作的一種模式。
- 利用工廠模式可以降低程序的耦合性,為后期的維護修改提供了很大的便利。
- 將選擇實現類、創建對象統一管理和控制。從而將調用者跟我們的實現類解耦。
6.3 為什么要學習工廠設計模式
不知道你們面試題問到過源碼沒有,你知道Spring的源碼嗎,MyBatis的源碼嗎,等等等 如果你想學習很多框架的源碼,或者你想自己開發自己的框架,就必須先掌握設計模式(工廠設計模式用的是非常非常廣泛的)
6.4 Spring開發中的工廠設計模式

6.5 工廠模式分類









7.代理模式
7.1 什么是代理模式
- 通過代理控制對象的訪問,可以在這個對象調用方法之前、調用方法之后去處理/添加新的功能。(也就是AO的P微實現)
- 代理在原有代碼乃至原業務流程都不修改的情況下,直接在業務流程中切入新代碼,增加新功能,這也和Spring的(面向切面編程)很相似
7.2 代理模式應用場景
Spring AOP、日志打印、異常處理、事務控制、權限控制等
7.3 代理的分類
- 靜態代理(靜態定義代理類)
- 動態代理(動態生成代理類,也稱為Jdk自帶動態代理)
- Cglib 、javaassist(字節碼操作庫)
7.4 三種代理的區別
1.靜態代理:簡單代理模式,是動態代理的理論基礎。常見使用在代理模式
- jdk動態代理:使用反射完成代理。需要有頂層接口才能使用,常見是mybatis的mapper文件是代理。
- cglib動態代理:也是使用反射完成代理,可以直接代理類(jdk動態代理不行),使用字節碼技術,不能對 fifinal類進行繼承。(需要導入jar包)
7.5 用代碼演示三種代理
7.5.1靜態代理
什么是靜態代理
由程序員創建或工具生成代理類的源碼,再編譯代理類。所謂靜態也就是在程序運行前就已經存在代理類的字節碼文件,代理類和委托類的關系在運行前就確定了。









8.建造者模式
8.1 什么是建造者模式
- 建造者模式:是將一個復雜的對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的方 式進行創建。
- 工廠類模式是提供的是創建單個類的產品
- 而建造者模式則是將各種產品集中起來進行管理,用來具有不同的屬性的產品

8.2 建造者模式的使用場景

8.3 代碼案例



9.模板方法模式
9.1 什么是模板方法
模板方法模式:定義一個操作中的算法骨架(父類),而將一些步驟延遲到子類中。 模板方法使得子類可以不改變一個算法的結構來重定義該算法的
9.2 什么時候使用模板方法
實現一些操作時,整體步驟很固定,但是呢。就是其中一小部分需要改變,這時候可以使用模板方法模式,將容易變的部分抽象出來,供子類實現。
9.3 實際開發中應用場景哪里用到了模板方法
- 其實很多框架中都有用到了模板方法模式
- 例如:數據庫訪問的封裝、Junit單元測試、servlet中關於doGet/doPost方法的調用等等
9.4 現實生活中的模板方法

9.5 代碼實現模板方法模式



10.外觀模式
10.1 什么是外觀模式
- 外觀模式:也叫門面模式,隱藏系統的復雜性,並向客戶端提供了一個客戶端可以訪問系統的接口。
- 它向現有的系統添加一個接口,用這一個接口來隱藏實際的系統的復雜性。
- 使用外觀模式,他外部看起來就是一個接口,其實他的內部有很多復雜的接口已經被實現
10.2 外觀模式例子




11.原型模式
11.1 什么是原型模式
- 原型設計模式簡單來說就是克隆
- 原型表明了有一個樣板實例,這個原型是可定制的。原型模式多用於創建復雜的或者構造耗時的實 例,因為這種情況下,復制一個已經存在的實例可使程序運行更高效。
11.2 原型模式的應用場景

11.3 原型模式的使用方式

11.4 代碼演示


12.策略模式
12.1 什么是策略模式
- 定義了一系列的算法 或 邏輯 或 相同意義的操作,並將每一個算法、邏輯、操作封裝起來,而且使它們還可以相互替換。(其實策略模式Java中用的非常非常廣泛)
- 我覺得主要是為了 簡化 if...else 所帶來的復雜和難以維護
12.2 策略模式應用場景

12.3 策略模式的優點和缺點
優點:
1、算法可以自由切換。
2、避免使用多重條件判斷。
3、擴展性非常良好。
缺點:
1、策略類會增多。
2、所有策略類都需要對外暴露。
12.4 代碼演示
模擬支付模塊有微信支付、支付寶支付、銀聯支付
- 定義抽象的公共方法



13.觀察者模式
13.1 什么是觀察者模式
- 先講什么是行為性模型,行為型模式關注的是系統中對象之間的相互交互,解決系統在運行時對象之間的相互通信和協作,進一步明確對象的職責。
- 觀察者模式,是一種行為性模型,又叫發布-訂閱模式,他定義對象之間一種一對多的依賴關系,使得當一個對象改變狀態,則所有依賴於它的對象都會得到通知並自動更新。
13.2 模式的職責
觀察者模式主要用於1對N的通知。當一個對象的狀態變化時,他需要及時告知一系列對象,令他們做出相應。
實現有兩種方式:
- 推:每次都會把通知以廣播的方式發送給所有觀察者,所有的觀察者只能被動接收。
- 拉:觀察者只要知道有情況即可,至於什么時候獲取內容,獲取什么內容,都可以自主決定。
13.3 觀察者模式應用場景
- 關聯行為場景,需要注意的是,關聯行為是可拆分的,而不是“組合”關系。事件多級觸發場景。
- 跨系統的消息交換場景,如消息隊列、事件總線的處理機制。
13.4 代碼實現觀察者模式




