常用設計模式

来源:https://www.cnblogs.com/LiuZhen/archive/2022/04/20/16133111.html
-Advertisement-
Play Games

外觀(門面)模式 化零為整,把零碎的功能拼成一個整體,對外提供一個統一介面,用來訪問子系統中的多個介面。 總結 解耦,不需要一個個對接,使用簡單。 單例模式 負責創建對象,同時確保只有單個對象被創建。 餓漢式 線程安全,在類載入時就會進行初始化,訪問時直接使用。 public class Stude ...


外觀(門面)模式

化零為整,把零碎的功能拼成一個整體,對外提供一個統一介面,用來訪問子系統中的多個介面。

總結

解耦,不需要一個個對接,使用簡單。

 

單例模式

負責創建對象,同時確保只有單個對象被創建。

餓漢式

線程安全,在類載入時就會進行初始化,訪問時直接使用。

public class Student {

    private static final Student student = new Student();
    private Student() {}

    public static Student getInstance() {
        return student;
    }
}

在類載入的時候便完成了實例化。

飽漢(懶漢)式

需要使用時才會去創建實例。

public class Student {

    private volatile static Student student;
    private Student() {}

    public static Student getInstance() {
        if (student == null) { 
            synchronized (Student.class) {
                if (student == null) {
                    student = new Student();
                }
            }
        }
        return SINGLETON;
    }
}

如果要保證線程安全,需要添加雙重鎖,當兩個線程同時執行 getInstance 時,結果都為 true,會導致一起進入排隊狀態,從而重覆創建新的對象;

所以需要雙重判斷,預防多線程重覆創建。

靜態內部類

public class Student {

    private Student() {}
    private static class Instance {
        private static final Student student = new Student();
    }

    public static Student getInstance() {
        return Instance.student;
    }
}

線程安全,只有使用時才會創建實例,不會造成資源浪費的問題。

枚舉式

public class Student {

    private enum StudentEnum {
        INSTANCE;
        private final Student instance;
  
        StudentEnum() {
            instance = new Student();
        }
        private Student getInstance() {
            return instance;
        }
    }

    private Student() {}
    public static Student getInstance() {
        return StudentEnum.INSTANCE.getInstance();
    }

}    

線程安全,只會裝載一次,無論是序列化、反序列化、反射還是克隆都不會新創建對象。

 

簡單工廠 & 抽象工廠

工廠模式將對象的創建和使用分離,屬於一個產品系列,而抽象工廠是多個產品系列一個工廠類。

//寶馬系列
BMWCar bmBean = CarFactory.create(Car.BMW); BMWX1 x1 = bmBean.getX1();
x1.drive();
BMWZ4 z4 = bmBean.getZ4();
z4.drive();
//賓士系列 BenZCar benZBean
= CarFactory.create(Car.BenZ);
BenZSUV suvBean = benZBean.getSUV(); suvBean.speed(); suvBean.stop();

總結

解耦,提高擴展,但是每次新增需要修改原代碼。

 

構鍵者模式

用於一步步創建複雜對象,一般分產品類,構鍵類和組裝類,通常用於配置工具類使用。

 

代理模式

為兩者之間提供一個代理對象(攔截層),並且目標對象只能被代理對象訪問,調用目標對象都要先通過代理對象。

靜態代理

目標對象和代理對象實現共同的介面或繼承相同的父類,在不修改目標對象的前提下進行擴展。

平時接手代碼,就可以在不修改原代碼的基礎上擴展原有功能。

總結

代理對象需要與目標對象實現一樣的介面,一對一模式,會導致代理類比較多;

介面修改後,目標對象與代理對象都要修改,維護成本高,適合目標類比較少的情況。

動態代理

一對多模式,一個代理類可利用反射機制代理多個委托類,並且是在運行時創建動態代理類。

JDK介面動態代理

代理對象不需要實現介面,目標對象必須實現介面

Proxy.newProxyInstance(classLoader 類載入器, classInterfaces[] 介面列表, InvocationHandler 攔截處理類);

總結

可以將代理類的創建推遲到運行時期,代理類通過 JDK 的 API 動態在記憶體中創建,這樣就可以大大減少代理類的創建和維護,但前提是目標類必須實現介面。

Cglib子類動態代理

不強制實現介面,在記憶體中動態的創建一個目標類的子類對象,從而實現對目標類的代理。

總結

通過 ASM 框架轉換位元組碼並生成新類,不能使用 final 修飾代理方法。

可以直接生成二進位 class 文件,也可以在類被載入到 Java 虛擬機之前改變類行為。

 

責任鏈模式

請求在鏈上一個個傳遞,直到鏈中某個對象處理。

總結

可以控制請求順序,新增不用修改原代碼,邏輯解耦,單一職責,效率不高,比較複雜,符合多個認證或者校驗等場景。

 

享元模式

共用基本的單元、元件,提升已有元件的復用率,減少重覆製造開銷。

代碼中主要分元件跟工廠類,工廠中編寫獲取方法,方法判斷該元件是否存在,如果不存在新建元件,存入共用池中,如果存在直接從池中獲取返回,類似單例。

總結

減少了資源的使用,但是增加了代碼的複雜程度。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Xamarin作為微軟提供的移動服務多系統開發平臺,成為很多開發者首選的應用開發平臺。AppGallery Connect(以下簡稱AGC)也在逐步的支持Xamarin的SDK。今天就手把手教大家如何快速接入Xamarin版遠程配置服務。 接入步驟 安裝Xamarin環境 Xamarin的御用開發平 ...
  • HMS Core廣告服務開髮指南中提到“xxxx為測試專用的廣告位ID,App正式發佈時需要改為正式的廣告位ID”,那麼今天咱們就來說說,怎麼獲取正式的廣告位ID。 測試廣告位ID和正式廣告位ID有什麼區別? 測試廣告位ID:不區分應用和條件,在中國大陸和非中國大陸都可以請求廣告,有利於開發者在集成 ...
  • 這幾天電腦有點問題,一直在弄,而且論文也逼近了也在時間弄那個 ,前面node有一個大項目,已經做完了,我現在是準備把上次複習斷下的繼續複習一直到這個項目,然後就開始vue了。 1. 首先是函數的一個進階,要明白函數也是對象,所以是可以通過new的方法來創建實例的。 然後是調用函數的三個方法:call ...
  • 作者:zxg_神說要有光 原文鏈接:https://juejin.cn/post/7087172219226292237 React 的 hooks 是在 fiber 之後出現的特性,所以很多人誤以為 hooks 是必須依賴 fiber 才能實現的,其實並不是,它們倆沒啥必然聯繫。 現在,不止 re ...
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="wi ...
  • 註釋快捷鍵——ctrl+/ 標題標簽H1-H6 H1-H6屬性:align="left/center/right" 左 中 右 段落標簽 <p></p> <p></p>屬性:align="left/center/right" 左 中 右 換行標簽<br> 分割線<hr> &nbsp:空格 一個漢字占 ...
  • 說到防抖和節流相信大家都不陌生,這兩個東西大家可能多多少少都有用到過,最少也有聽。簡單來說,防抖和節流都是用來減少函數執行的頻率,以達到優化項目性能或者實現特定功能的效果。 ...
  • 最近項目中用到可視化地圖,正好這幾天有空整理下以方便以後快速上手使用的記錄。 不廢話~ 我們項目是用的uinapp 剛開是也是npm 裝包 npm install echarts -S //或 cnpm install echarts -S 你隨意。 window.wx = undefined; 這 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...