一、代理模式的作用
- 將主要業務與次要業務進行松耦合的組裝
二、代理模式本質
- 監控行為的特征
例子:
<input type="button" onclick="處理函式">
三、生活案例
案例:飯前便后要洗手
分析:
1.分析出主要業務和次要業務
【主要業務】:吃飯,上廁所
【次要業務】:洗手
2.JDK代理模式實作
2.1、介面角色:定義所有需要被監聽行為
BaseService.java
1 package com.chenyanbin.service;2 3 /*4 * 只有需要被監控的行為才有資格在這里宣告5 */6 public interface BaseService {7 public void Eat();8 public void Wc();9 }
2.2、介面實作類:中國人、印度人
Person.java
1 package com.chenyanbin.serviceImpl; 2 3 import com.chenyanbin.service.BaseService; 4 5 public class Person implements BaseService { 6 7 @Override 8 public void Eat() { //主要業務,代理模式要求開發任務只關心主要業務 9 System.out.println("使用筷子吃飯");10 }11 12 @Override13 public void Wc() {14 System.out.println("測驗地球重力是否存在");15 }16 }
2.3、通知類:1)次要業務進行具體實作 2)通知JVM,當前被攔截的主要業務方法與次要業務方法應該如何系結執行
Invaction.java
1 package com.chenyanbin.util; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 import com.chenyanbin.service.BaseService; 7 8 public class Invaction implements InvocationHandler { 9 private BaseService obj;// 具體被監控物件10 11 public Invaction(BaseService param) {12 this.obj = param;13 }14 15 /*16 * invoke方法:被監控行為將要執行時,會被JVM攔截,被監控行為和行為實作方會被作為引數輸送到invoke17 * ***通知JVM,這個被攔截方法是如何與當前次要業務方法系結實作 invoke方法三個引數 小明.Eat();//JVM攔截18 * Eat方法封裝為Method型別方法 Eat方法運行時所有的實參封裝到Object[] 將負責監控小明的代理物件作為invoke方法第一個引數19 * 20 */21 @Override22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {23 // 0.區域變數,接受主要業務方法執行完畢后回傳值24 Object value;25 // 1.確認當前被攔截行為26 String methodName = method.getName();27 // 2.根據被攔截行為不同,決定主要業務和次要業務如何系結執行28 if ("Eat".equals(methodName)) { // 飯前要洗手29 Wash();// 洗手30 value = https://www.cnblogs.com/chenyanbin/p/method.invoke(this.obj, args);// 當前主要業務31 } else { // 便后洗手32 value = https://www.cnblogs.com/chenyanbin/p/method.invoke(this.obj, args);// 當前主要業務33 Wash();// 洗手34 }35 return value; //回傳被攔截方法36 }37 38 // 次要業務39 public void Wash() {40 System.out.println("--------洗手--------");41 }42 }
2.4、監控物件(代理物件):1)被監控實體物件 2)需要被監控行為 3)具體通知類實體物件
ProxyFactory.java
1 package com.chenyanbin.util; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5 6 import com.chenyanbin.service.BaseService; 7 8 public class ProxyFactory { 9 /*10 * JDK動態代理模式下,代理物件的資料型別 應該由監控行為來描述 引數:Class檔案,監控類11 */12 public static BaseService build(Class classFile) throws Exception {13 //1.創建被監控實體物件14 BaseService obj = (BaseService) classFile.getDeclaredConstructor().newInstance();15 //2.創建通知物件16 InvocationHandler adviser=new Invaction(obj);17 //3.向JVM申請負責監控obj物件指定行為的監控物件(代理物件)18 /*19 * loader:被監控物件隸屬的類檔案在記憶體中真實地址20 * interfaces:被監控物件隸屬的類檔案實作介面21 * h:監控物件發現小明要執行被監控行為,應該由哪一個通知物件進行輔助22 */23 BaseService $proxy=(BaseService)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser);24 return $proxy;25 }26 }
測驗類
TestMain.java
1 import com.chenyanbin.service.BaseService; 2 import com.chenyanbin.serviceImpl.Person; 3 import com.chenyanbin.util.ProxyFactory; 4 5 public class TestMain { 6 7 public static void main(String[] args) throws Exception { 8 //mike.Eat(); 9 // Person mike=new Person();10 BaseService mike = ProxyFactory.build(Person.class);11 mike.Eat();12 }13 }
吃飯

上廁所

專案目錄結構

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/39954.html
標籤:設計模式
上一篇:通俗易懂設計模式決議——狀態模式
