23种设计模式——代理模式
- 學無止境 Java工程師的進階之旅
目錄
- 一、什么是代理
- 二、作用
- 三、靜態代理
- 3.1、簡介
- 3.2、實現步驟
- 3.3、缺點
- 四、動態代理
- 4.1、概念
- 4.2、分類
- 4.2.1、JDK動態代理
- 4.2.2、CGLIB動態代理
- 4.3、回顧Method類
- 4.4.、反射包
- 4.5、實現步驟
- 4.5.1、實現中間商賺差價
- 4.5.2、實現執行方法前后打印日志和執行事務
一、什么是代理
你想買件東西,但是直接去廠家廠家是不賣的,你可以在淘寶京東等購物商城購買,商家此時便充當代理的角色
專業點來講:
為其他對象提供一種代理以控制對這個對象的訪問,在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在兩者種起到中介的作用
A無法訪問C,B可以訪問C,A可以通過調用B調用C,此時B是C的代理
二、作用
- 功能增強:增加額外的功能,如日志記錄,事務(主要使用)
- 控制訪問:代理類不讓你訪問目標類,如商家不讓用戶訪問廠家
三、靜態代理
3.1、簡介
代理類手動創建,代理目標確定,實現簡單,容易理解
3.2、實現步驟
需求:模擬用戶從淘寶購買iphone,假設蘋果工廠不單獨賣給用戶
用戶:客戶類
商家:代理
廠家:目標類
用戶——》商家——》廠家
實現步驟
- 創建一個接口IphoneSell,定義賣iphone的方法sell,表示廠家和商家的行為
- 創建商家類TaoBao和廠家類AppleFactory,實現接口
- 創建客戶類,調用商家的方法購買
IphoneSell接口
public interface IphoneSell {float sell(int amount); }廠家類AppleFactory
package com.proxy.factory;import com.proxy.service.IphoneSell;public class AppleFactory implements IphoneSell {@Overridepublic float sell(int amount) {return 3299.0f;} }商家類TaoBao
package com.proxy.business;import com.proxy.service.IphoneSell; import com.proxy.factory.AppleFactory;public class TaoBao implements IphoneSell {private AppleFactory factory = new AppleFactory();@Overridepublic float sell(int amount) {//銷售時商家向廠家發送訂單,廠家發貨float price = factory.sell(amount);//加價銷售 增強功能return price + 700;} }main方法
package com.proxy;import com.proxy.business.TaoBao;public class ShopMain {public static void main(String[] args) {TaoBao taoBao = new TaoBao();float prcie = taoBao.sell(1);System.out.println(prcie);} }3.3、缺點
目標類增加,代理類成倍增加,接口修改所有實現類都得修改
四、動態代理
4.1、概念
程序執行時,使用jdk反射機制,創建代理類對象,并動態的指定要代理的目標類
4.2、分類
4.2.1、JDK動態代理
- 使用JDK的Proxy實現代理
- 反射包java.lang.reflect,三個類InvocationHandler,Method,Proxy
- 要求目標類與代理類實現相同的接口
- 若目標類不存在接口無法使用該方式(使用CGLIB)
4.2.2、CGLIB動態代理
- 第三方的工具庫,創建代理對象
- 生成目標類的子類,子類是增強過的,也就是代理對象,所有需要要求目標類能被繼承,且不能final
4.3、回顧Method類
public interface HelloService {void sayHello(String name);} public class HelloServiceImpl implements HelloService {@Overridepublic void sayHello(String name) {System.out.println("hello" + name);} } public class TestApp {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {HelloService target = new HelloServiceImpl();//getMethod("方法名","方法參數數據類型")Method method = HelloService.class.getMethod("sayHello", String.class);/*** 表示執行方法的調用* invoke(對象,方法執行參數)*/method.invoke(target, ":jiali"); //hello:jiali} }4.4.、反射包
代理類完成的功能:調用目標方法且增強功能
1、InvocationHandler接口:就一個方法invoke():表示代理對象要執行的功能代碼
2、Proxy類:不需要手動new對象,使用Proxy類的方法newProxyInstance()創建并返回代理對象
//ClassLoader 類加載器 a.getClass().getClassLoader() //Class<?>[] 接口,目標類實現的接口,也是反射獲取的 //InvocationHandler 代理類要完成的功能 public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException {}3、Method類:表示目標類中的方法,通過Method可以執行某個目標類的方法Method.invoke(目標對象,方法參數)
4.5、實現步驟
4.5.1、實現中間商賺差價
1、定義行為
public interface UsbSell {float sell(int amount); }2、定義目標類
public class UsbFactory implements UsbSell {@Overridepublic float sell(int amount) {return 100.0f;} }3、定義MySellHandler實現invocationHandler
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;public class MySellHandler implements InvocationHandler {private Object target = null;//傳入需要被代理的目標對象public MySellHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;//表示執行目標對象的方法的調用invoke(目標類,方法參數)result = method.invoke(target, args);//增強功能if (result != null) {Float price = (Float) result;price = price + 25;result = price;}//增強后的價格return result;} }4、測試
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy;public class MainShop {public static void main(String[] args) {//創建目標對象IphoneSell factory = new AppleFactory();//將目標對象交給InvocationHandlerInvocationHandler handler = new MySellHandler(factory);//創建代理對象實現功能增強UsbSell proxyInstance = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(),handler);System.out.println(proxyInstance.sell(1));//125.0} }4.5.2、實現執行方法前后打印日志和執行事務
public interface MyService {void doSome(); } public class MyServiceImpl implements MyService {@Overridepublic void doSome() {System.out.println("執行業務方法");} } import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;public class MyHandler implements InvocationHandler {Object target;public MyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//打印日志System.out.println("打印日志成功");//執行目標方法method.invoke(target, args);//提交事務System.out.println("提交事務成功");return null;} } public class Test {public static void main(String[] args) {MyService myService = new MyServiceImpl();InvocationHandler myHandler = new MyHandler(myService);MyService proxyInstance = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(), myService.getClass().getInterfaces(), myHandler);proxyInstance.doSome();} }總結
以上是生活随笔為你收集整理的23种设计模式——代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028全球与中国硅片清洗设备
- 下一篇: 2023上海海洋大学计算机考研信息汇总