設計模式-2 結構型模式

一、代理模式

1、舉例

海外代購

2、代理基本結構圖

3、靜態代理

1、真實類實現一個接口,代理類也實現這個接口。

2、代理類通過真實對象調用真實類的方法。

4、靜態代理和動態代理的區別

1、靜態代理在編譯時就已經實現了,編譯完成后代理類是一個實際的class文件。

2、動態代理是在運行時動態生成的,即編譯完成后沒有實際的class文件,而是在運行時動態生成類字節碼,再加載到JVM中。

5、JDK動態代理實現

核心:構造代理對象,按JDK要求獲取參數,讓JDK生成代理對象。

// 生成代理對象 - 核心
Dinner proxy = (Dinner) Proxy.newProxyInstance(classLoader, interfaces, h);
package allwe.testProxy;/*** 定義一個晚餐接口*/
public interface Dinner {void eat(String foodName);void drink(String juiceName);
}
package allwe.testProxy;import lombok.Data;/*** 定義人 - 實現晚餐接口*/
@Data
public class Person implements Dinner {private String name;public Person(String name) {this.name = name;}@Overridepublic void eat(String foodName) {System.out.println(this.name + "吃" + foodName);}@Overridepublic void drink(String juiceName) {System.out.println(this.name + "喝" + juiceName);}
}
package allwe.testProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;/*** 我的調用處理器 - 設定增強規則*/
public class MyInvocationHandler implements InvocationHandler {private final Dinner dinner;public MyInvocationHandler(Dinner dinner) {this.dinner = dinner;}/*** 定義增強規則** Object proxy     代理對象* Method method    被代理的方法* Object[] args    被代理方法運行時的實參*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals("eat")) {System.out.println("前置增強===================飯前洗手");// 運行eat方法method.invoke(dinner, args);System.out.println("后置增強===================飯后洗碗");} else if (method.getName().equals("drink")) {System.out.println("前置增強===================打開瓶蓋");// 運行eat方法method.invoke(dinner, args);System.out.println("后置增強===================關上瓶蓋");} else {return method.invoke(dinner, args);}return null;}
}
package allwe.testProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;/*** 動態代理實現*/
public class TestProxy {// 通過Proxy動態代理獲取一個代理對象,在代理對象中,對某個方法增強public static void main(String[] args) {// 創建一個人 - 張三Dinner dinner = new Person("張三");// 被代理對象的類加載器ClassLoader classLoader = dinner.getClass().getClassLoader();// 被代理對象所實現的所有接口Class<?>[] interfaces = dinner.getClass().getInterfaces();// 執行處理器對象 - 專門用于定義增強的規則的InvocationHandler h = new MyInvocationHandler(dinner);// 生成代理對象 - 核心Dinner proxy = (Dinner) Proxy.newProxyInstance(classLoader, interfaces, h);// 使用代理對象調用Dinner接口的方法proxy.eat("饅頭");proxy.drink("可樂");}
}

6、Cglib動態代理實現

核心:構造代理對象,按CGLIB要求獲取參數,讓CGLIB生成代理對象。

// 1.創建一個Enhancer對象
Enhancer enhancer = new Enhancer();
// 2.設置真實對象的類
enhancer.setSuperclass(personClass);
// 3.設置增強邏輯
enhancer.setCallback(methodInterceptor);
// 4.創建代理對象
Person personProxy = (Person) enhancer.create();
package allwe.testCGLib;import lombok.Data;/*** 定義人*/
@Data
public class Person {private String name;// Cglib使用這個構造器創建真實對象public Person() {this.name = "張三";}public void eat(String foodName){System.out.println(this.name + "吃" + foodName);}
}
package allwe.testCGLib;import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** 我的方法攔截器 - 定義方法攔截規則*/
public class MyMethodInterceptor implements MethodInterceptor {/*** Object o                    生成之后的代理對象* Method method               父類中原本要執行的方法* Object[] objects            方法在被調用時接收的實參* MethodProxy methodProxy     子類中重寫的  父類方法*/@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("==========前置增強==========");// 執行子類對象方法   -->  son.super.method(args)Object res = methodProxy.invokeSuper(o, objects);System.out.println("==========后置增強==========");return res;}
}
package allwe.testCGLib;import org.junit.jupiter.api.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;public class TestCglib {@Testpublic void testCglib() {// 獲取被代理的類Class<? extends Person> personClass = Person.class;// 定義增強規則MethodInterceptor methodInterceptor = new MyMethodInterceptor();// 獲取一個Person的代理對象// 1.創建一個Enhancer對象Enhancer enhancer = new Enhancer();// 2.設置真實對象的類enhancer.setSuperclass(personClass);// 3.設置增強邏輯enhancer.setCallback(methodInterceptor);// 4.創建代理對象Person personProxy = (Person) enhancer.create();// 使用代理對象執行方法personProxy.eat("米飯");}
}

二、橋接模式

1、定義

在軟件開發中,橋接模式將兩個獨立變化的維度進行了解耦,不是將兩者耦合在一起,形成多繼承的結構。

2、舉例

毛筆和蠟筆,大中小號,12種顏色。

3、結構:實體與行為分離

4、核心

首先要識別出一個類所具有的兩個獨特的變化維度,將它們設計為兩個獨立的繼承等級結構,為兩個維度都提供抽象層,并建立抽象

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908222.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908222.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908222.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue+element-ui一個頁面有多個子組件組成。子組件里面有各種表單,實現點擊enter實現跳轉到下一個表單元素的功能。

一個父組件里面是有各個子組件的form表單組成的。 我想實現點擊enter。焦點直接跳轉到下一個表單元素。 父組件就是由各個子組件構成 子組件就像下圖一樣的都有個el-form的表單。 enterToTab.js let enterToTab {}; (function() {// 返回隨機數enterToTab.addEnterListener …

Open SSL 3.0相關知識以及源碼流程分析

Open SSL 3.0相關知識以及源碼流程分析 編譯 windows環境編譯1、工具安裝 安裝安裝perl腳本解釋器、安裝nasm匯編器(添加到環境變量)、Visual Studio編譯工具 安裝dmake ppm install dmake # 需要過墻2、開始編譯 # 1、找到Visual Studio命令行編譯工具目錄 或者菜單欄直接…

【Redis】筆記|第5節|Redisson實現高并發分布式鎖核心源碼

一、加鎖流程 1. 核心方法調用鏈 RLock lock redisson.getLock("resource"); lock.lock(); // 阻塞式加鎖? lockInterruptibly()? tryAcquire(-1, leaseTime, unit) // leaseTime-1表示啟用看門狗? tryAcquireAsync()? tryLockInnerAsync() // 執行Lua腳本 2…

基于React + TypeScript構建高度可定制的QR碼生成器

前言 在現代Web應用中&#xff0c;QR碼已成為連接線上線下的重要橋梁。本文將詳細介紹如何使用React TypeScript Vite構建一個功能強大、高度可定制的QR碼生成器&#xff0c;支持背景圖片、文本疊加、HTML模塊、圓角導出等高級功能。 前往試試 項目概述 技術棧 前端框架:…

【MATLAB代碼】制導——三點法,二維平面下的例程|運動目標制導,附完整源代碼

三點法制導是一種導彈制導策略,主要用于確保導彈能夠準確追蹤并擊中移動目標。該方法通過計算導彈、目標和制導站之間的相對位置關系,實現對目標的有效制導。 本文給出MATLAB下的三點法例程,模擬平面上捕獲運動目標的情況訂閱專欄后可直接查看源代碼,粘貼到MATLAB空腳本中即…

Ubuntu22.04 安裝 IsaacSim 4.2.0

1. 從官網下載 IsaacSim 4.2.0 安裝包 https://download.isaacsim.omniverse.nvidia.com/isaac-sim-standalone%404.2.0-rc.18%2Brelease.16044.3b2ed111.gl.linux-x86_64.release.zip 2. 查閱 Workstation Installation 安裝方式 Workstation Installation — Isaac Sim Do…

開源量子模擬引擎:Quantum ESPRESSO本地部署教程,第一性原理計算輕松入門!

一、介紹 Quantum ESPRESSO 是一個用于電子結構計算和納米尺度材料建模的開源計算機代碼集成套件&#xff0c;專門用于進行第一性原理&#xff08;第一性原理&#xff09;計算&#xff0c;涵蓋了電子結構、晶體學和材料性能的模擬。 Quantum ESPRESSO GPU 版本支持GPU加速&am…

PVE 虛擬機安裝 Ubuntu Server V24 系統 —— 一步一步安裝配置基于 Ubuntu Server 的 NodeJS 服務器詳細實錄1

前言 最近在基于 NodeJS V22 寫一個全棧的項目&#xff0c;寫好了&#xff0c;當然需要配置服務器部署啦。這個過程對于熟手來說&#xff0c;還是不復雜的&#xff0c;但是對于很多新手來說&#xff0c;可能稍微有點困難。所以&#xff0c;我把整個過程全部記錄一下。 熟悉我…

【JUC】深入解析 JUC 并發編程:單例模式、懶漢模式、餓漢模式、及懶漢模式線程安全問題解析和使用 volatile 解決內存可見性問題與指令重排序問題

單例模式 單例模式確保某個類在程序中只有一個實例&#xff0c;避免多次創建實例&#xff08;禁止多次使用new&#xff09;。 要實現這一點&#xff0c;關鍵在于將類的所有構造方法聲明為private。 這樣&#xff0c;在類外部無法直接訪問構造方法&#xff0c;new操作會在編譯…

2. 庫的操作

2.1 創建數據庫 語法&#xff1a; CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name # 字符集: 存儲編碼 [DEFAULT] COLLATE collation_name # 校驗集: 比較/選擇/讀…

道可云人工智能每日資訊|北京農業人工智能與機器人研究院揭牌

道可云人工智能&元宇宙每日簡報&#xff08;2025年6月3日&#xff09;訊&#xff0c;今日人工智能&元宇宙新鮮事有&#xff1a; 北京農業人工智能與機器人研究院揭牌 5月30日&#xff0c;北京市農業農村局、北京市海淀區人民政府、北京市農林科學院共同主辦北京農業人…

【JSON-to-Video】設置背景視頻片斷

目錄 設置bgVideo字段 1. 設置bgVideo.videoList字段 2. 設置randomPlay字段 3. 設置complete字段 4. 調用API&#xff0c;制作視頻 歡迎來到JSON轉視頻系列教程。今天要教大家如何添加背景視頻片斷&#xff0c;在視頻制作中&#xff0c;巧妙運用背景視頻&#xff0c;能為…

星閃開發之Server-Client 指令交互控制紅燈亮滅案例解析(SLE_LED詳解)

系列文章目錄 星閃開發之Server-Client 指令交互控制紅燈亮滅的全流程解析&#xff08;SLE_LED詳解&#xff09; 文章目錄 系列文章目錄前言一、項目地址二、客戶端1.SLE_LED_Client\inc\SLE_LED_Client.h2.SLE_LED_Client\src\SLE_LED_Client.c頭文件與依賴管理宏定義與全局變…

Linux shell練習題

Shell 1. 判斷~/bigdata.txt 是否存在&#xff0c;若已存在則打印出”該文件已存在“&#xff0c;如不存在&#xff0c;則輸出打印&#xff1a;”該文件不存在“ if [ -f ./bigdata.txt ];then echo "文件存在" else echo "文件不存在" fi2. 判斷~/bigd…

Linux基本指令(三)

接上之前的文章&#xff0c;咱繼續分享Linux的基本指令&#xff0c;Linux指令比較多&#xff0c;很難全部記住需要做筆記對常用的指令進行記錄&#xff0c;方便以后復習查找&#xff0c;做筆記也可以對知識理解更加深刻。 目錄 時間相關指令 date顯示 時間戳 cal指令 ?編…

WebRTC中sdp多媒體會話協議報文詳細解讀

sdp介紹 在WebRTC&#xff08;Web實時通信&#xff09;中&#xff0c;SDP&#xff08;Session Description Protocol&#xff09;是用來描述和協商多媒體會話的協議。它定義了會話的參數和媒體流的信息&#xff0c;如音視頻編碼格式、傳輸方式、網絡地址等。SDP是WebRTC中一個…

【MySQL】 約束

一、約束的定義 MySQL 約束是用于限制表中數據的規則&#xff0c;確保數據的 準確性 和 一致性 。約束可以在創建表時定義&#xff0c;也可以在表創建后通過修改表結構添加。 二、常見的約束類型 2.1 NOT NULL 非空約束 加了非空約束的列不能為 NULL 值&#xff0c;如果可以…

【.net core】【watercloud】樹形組件combotree導入及調用

源碼下載:combotree: 基于layui及zTree的樹下拉框組件 鏈接中提供了組件的基本使用方法 框架修改內容 1.文件導入&#xff08;路徑可更具自身情況自行設定&#xff09; 解壓后將文件夾放在圖示路徑下&#xff0c;修改文件夾名稱為combotree 2.設置路徑&#xff08;設置layu…

ES101系列07 | 分布式系統和分頁

本篇文章主要講解 ElasticSearch 中分布式系統的概念&#xff0c;包括節點、分片和并發控制等&#xff0c;同時還會提到分頁遍歷和深度遍歷問題的解決方案。 節點 節點是一個 ElasticSearch 示例 其本質就是一個 Java 進程一個機器上可以運行多個示例但生產環境推薦只運行一個…

CppCon 2015 學習:3D Face Tracking and Reconstruction using Modern C++

1. 3D面部追蹤和重建是什么&#xff1f; 3D面部追蹤&#xff08;3D Face Tracking&#xff09;&#xff1a; 實時檢測并追蹤人臉在三維空間中的位置和姿態&#xff08;如轉頭、點頭、表情變化等&#xff09;&#xff0c;通常基于攝像頭捕獲的視頻幀。3D面部重建&#xff08;3D…