Java設計模式很難嗎,這篇帶你熟悉設計模式

3。1 概述

可以發現,設計模式好像都是類似的。越看越感覺都著不多。其實都是類似面向介面程式設計的一種體現,只不過側重點不一樣或者說要體現的結果不一樣。

3。2 使用場景

問題一:應對可能變化的物件實現

方案:間接建立

模式:工廠模式

Java設計模式很難嗎,這篇帶你熟悉設計模式

問題二:為請求指定相應的操作(類似請假審批,不同時長對應不同職位的審批人)

方案:程式根據請求動態選擇操作

模式:責任鏈模式

Java設計模式很難嗎,這篇帶你熟悉設計模式

3。3 具體說明

3。3。1 策略模式

策略模式說明

Java設計模式很難嗎,這篇帶你熟悉設計模式

一個行為型模式,包含多個行為或職責的業務,透過策略模式簡化

public class StrategyContext { Strategy strategy; public StrategyContext(Strategy strategy) { this。strategy = strategy; } /** * */ public int context(int a, int b) { return strategy。operator(a,b); }}

策略模式的核心為StrategyContext上下文類,持有strategy物件,在context完成操作。

策略模式實踐

如何使用策略模式解決大量使用if else 或大量switch問題,策略模式+反射。

策略模式後好像使用都還是要用if else來決定呼叫哪個類,所以在引入策略模式後,在上下文類還要增加反射。

public class StrategyContext { Strategy strategy; public StrategyContext(String type) throws Exception { Class clazz = Class。forName(type); this。strategy = (Strategy) clazz。newInstance(); } /** * */ public int context(int a, int b) { return strategy。operator(a,b); }

當然這裡的type可以用個列舉來解決。感覺代價非常大是不是沒必要,不過程式碼的可讀性還是增強了。

p。s。 在框架裡策略模式中的Context一般不會直接出現,類似spring中直接在使用時就透過註解給設定了

3。3。2、裝飾器模式

描述:原介面Shape不變,方法數量不變,在

方法實現中

增加修飾

場景:

場景一:一個類功能簡單,滿足不了我們的需求

場景二:給原方法增加日誌功能,不改變原方法,新的實現類去實現此功能,帶入的物件為介面物件

Java設計模式很難嗎,這篇帶你熟悉設計模式

特點

原介面Shape不動,增加新的裝飾類ShapeDecorator

原方法名不變,只是增加或修飾此方法體

ColorShapeDecorator裝飾類持有原物件,只是增加了修飾

public class ColorShapeDecorator extends ShapeDecorator { public ColorShapeDecorator(Shape shape) { super(shape); } @Override public void draw() { setColor(); shape。draw(); } private void setColor() { //設定畫圖顏色 }}

3。3。3 代理模式

設定一箇中間代理來控制訪問原目標物件,達到

增強

原物件的功能和

簡化

訪問方式的目的

場景:

場景一:不改變原方法,對原方法增加耗時的計算

場景二:rpc遠端呼叫,client端進行動態代理類似耗時計算一樣,使用者不用關心client的具體實現

分類

靜態代理模式

動態代理模式

說明

Java設計模式很難嗎,這篇帶你熟悉設計模式

靜態代理模式

/** * 與介面卡模式的區別,介面卡模式主要改變所考慮物件的介面, * 而代理模式不能改變所代理類的介面。與裝飾器模式的區別, * 裝飾器模式是為了增強功能,代理模式是為了加以控制 */public class ProxySigntureService implements SigntureService { private SigntureService signatureService; /** * Default constructor */ public ProxySigntureService(SigntureService signatureService) { this。signatureService = signatureService; } public void sign() { //控制對這個物件的訪問 // 實現電子簽名 }}

動態代理模式

public class DynamicProxySignatureService implements InvocationHandler { private Object obj; public DynamicProxySignatureService(Object obj) { this。obj = obj; } @Override public Object invoke(Object proxyObj, Method method, Object[] objects) throws Throwable { return method。invoke(obj,objects); }}

參考文章:https://blog。csdn。net/liujiahan629629/article/details/19428485

3。3。4 介面卡模式

描述:

原介面不變,增加

方法數量

場景:

場景一:原介面不變,在基礎上增加新的方法。

場景二:介面的抽象方法很多,不想一一實現,使用介面卡模式繼承原實現類,再實現此介面

Java設計模式很難嗎,這篇帶你熟悉設計模式

介面卡模式適合需要

增加一個新介面的需求

,在原介面與實現類基礎上需要增加新的介面及方法。類似原介面只能method01方法,需求是增加method02方法,同時不再使用之前介面類。

新介面

public interface Targetable { /** * */ public void method01(); /** * */ public void method02();}

原介面實現類

public class Source { public void method01() { // TODO implement here }}

介面卡類,用於實現新介面。繼承原實現類,同時實現新介面。

public class Adapter extends Source implements Targetable { /** * */ public void method02() { // TODO implement here }}

測試類

public class AdapterTest { public static void main(String[] args) { Targetable targetable = new Adapter(); targetable。method01(); targetable。method02(); }}

3。3。5 單例模式

保證被建立一次,節省系統開銷。

1)單例實現方式

餓漢式

懶漢式

懶漢式+synchronized

雙重校驗

靜態內部類

列舉(推薦方式)

2)實現程式碼

餓漢式

package com。hanko。designpattern。singleton;/** * 餓漢式 (餓怕了,擔心沒有吃,所以在使用之前就new出來) *優點:實現簡單,安全可靠 *缺點:在不需要時,就已例項化了 * @author hanko * @version 1。0 * @date 2020/9/14 18:50 */public class HungrySingleton { //特點一 靜態私有變數 直接初始化 private static HungrySingleton instance = new HungrySingleton(); //特點二 建構函式私有 private HungrySingleton(){ } public static HungrySingleton getInstance(){ return instance; } public void doSomething(){ //具體需要實現的功能 }}

懶漢式

package com。hanko。designpattern。singleton;/** * 懶漢式(非常懶,所以在要使用時再去new) *優點:簡單 *缺點:存線上程安全問題 * @author hanko * @version 1。0 * @date 2020/9/14 18:50 */public class SluggardSingleton { //特點一 靜態私有變數,先不初始化 private static SluggardSingleton instance; //特點二 建構函式私有 private SluggardSingleton(){ } //特點三 null判斷,沒有例項化就new public static SluggardSingleton getInstance(){ if(instance == null){ instance = new SluggardSingleton(); } return instance; } public void doSomething(){ //具體需要實現的功能 }}

懶漢式+Synchronized

package com。hanko。designpattern。singleton;/** * 懶漢式(非常懶,所以在要使用時再去new) *優點:簡單 *缺點:存線上程安全問題 * @author hanko * @version 1。0 * @date 2020/9/14 18:50 */public class SluggardSingleton { //特點一 靜態私有變數,先不初始化 private static SluggardSingleton instance; //特點二 建構函式私有 private SluggardSingleton(){ } //特點三 null判斷,沒有例項化就new public static synchronized SluggardSingleton getInstance(){ if(instance == null){ instance = new SluggardSingleton(); } return instance; } public void doSomething(){ //具體需要實現的功能 }}

雙重校驗

package com。hanko。designpattern。singleton;/** * 雙重校驗 *對懶漢式單例模式做了執行緒安全處理增加鎖機制 * volatile變數級 * synchronized 類級 * @author hanko * @version 1。0 * @date 2020/9/15 9:53 */public class DoubleCheckSingleton { //特點一 靜態私有變數,增加volatile變數級鎖 private static volatile DoubleCheckSingleton instance; //特點二 建構函式私有 private DoubleCheckSingleton(){ } //特點三 雙重null判斷 synchronized類級鎖 public static DoubleCheckSingleton getInstance(){ if (instance == null){ synchronized(DoubleCheckSingleton。class){ if (instance == null){ instance = new DoubleCheckSingleton(); } } } return instance; }}

靜態內部類

package com。hanko。designpattern。singleton;/** * 內部靜態類方式 *優點:靜態內部類不會在InnerStaticSingleton類載入時載入, * 而在呼叫getInstance()方法時才載入 *缺點:存在反射攻擊或者反序列化攻擊 * @author hanko * @version 1。0 * @date 2020/9/15 10:03 */public class InnerStaticSingleton { //特點一:建構函式私有 private InnerStaticSingleton(){ } //特點二:靜態內部類 private static class InnerSingleton{ private static InnerSingleton instance = new InnerSingleton(); } public InnerSingleton getInstance(){ return InnerSingleton。instance; } public void doSomething(){ //do Something }}

列舉(推薦方式)

package com。hanko。designpattern。singleton;/** * 列舉實現單例簡單安全 * * @author hanko * @version 1。0 * @date 2020/9/14 19:01 */public enum EnumSingleton { INS; private Singleton singleton; EnumSingleton() { singleton = new Singleton(); } public void doSomething(){ singleton。。。 //具體需要實現的功能 }}EnumSingleton。INS。doSomething();

3。3。6 工廠模式

(簡單工廠、抽象工廠):解耦程式碼。

簡單工廠:用來生產同一等級結構中的任意產品,對於增加新的產品,無能為力。

工廠方法:用來生產同一等級結構中的固定產品,支援增加任意產品。

抽象工廠:用來生產不同產品族的全部產品,對於增加新的產品,無能為力;支援增加產品族。

參考文章:https://zhuanlan。zhihu。com/p/248497545

3。3。7 觀察者模式

定義了物件之間的一對多的依賴,這樣一來,當一個物件改變時,它的所有的依賴者都會收到通知並自動更新。

3。3。8 外觀模式

提供一個統一的介面,用來訪問子系統中的一群介面,外觀定義了一個高層的介面,讓子系統更容易使用。

3。3。9 狀態模式

允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類。與策略模式類似,策略模式側重點在一個事的不同實現方式抽離出來,而狀態模式是一個事的不同狀態抽離出來(開始、進行中、結束),每次狀態完成自己的業務邏輯。

3。4 總結:

介面卡模式(原功能不變,增加新功能)、裝飾器模式(裝飾原功能)、代理模式(控制原功能)

策略模式側重點在一個事的不同實現方式抽離出來,而狀態模式是一個事的不同狀態抽離出來(開始、進行中、結束),每次狀態完成自己的業務邏輯。