Java描述設計模式(16):代理模式


本文源碼:GitHub·點這里 || GitEE·點這里

一、生活場景

1、場景描述

在電商高速發展的今天,快遞的數量十分龐大,甚至出現了快遞代理行業,簡單的說就是快遞的主人沒有時間收快遞,會指定一個快遞的代收點,比如快遞櫃,快遞驛站等,然后等有時間的時候再過去取,下面使用代碼對這個場景進行簡單的描述。

2、場景圖解

3、源碼實現

public class C01_InScene {
    public static void main(String[] args) {
        /*自己收快遞的測試方式*/
        GetExpress getExpress = new GetExpress();
        getExpress.sureInfo();
        getExpress.signName("張三");
        /*代收快遞的測試方式*/
        ExpressAct getUser = new GetExpress();
        ExpressAct getProxy = new ProxyExpress(getUser);
        getProxy.sureInfo();
        getProxy.signName("李四");
    }
}
/**
 * 接收一個快遞的動作接口:確認信息,簽名
 */
interface ExpressAct{
    void sureInfo();
    void signName(String name);
}
/**
 * 定義一個類接收快遞:自己去拿快遞
 */
class GetExpress implements ExpressAct{
    @Override
    public void sureInfo() {
        System.out.println("請確認你的個人信息!");
    }
    @Override
    public void signName(String name) {
        System.out.println("你的名字是:"+name);
    }
}
/**
 * 定義一個類接收快遞:找人代領快遞
 */
class ProxyExpress implements ExpressAct{
    private ExpressAct expressAct=null;
    public ProxyExpress(ExpressAct expressAct){
        this.expressAct = expressAct;
    }
    @Override
    public void sureInfo() {
        this.expressAct.sureInfo();
    }
    @Override
    public void signName(String name) {
        this.expressAct.signName(name);
    }
}

二、代理模式

1、概念描述

代理模式是對象的結構模式。代理模式給某一個對象提供一個代理對象,並由代理對象控制對原對象的引用。所謂代理,就是一個對象代表另一個對象執行相應的動作程序。而代理對象可以在客戶端和目標對象之間起到中介的作用。

2、模式圖解

3、核心角色

  • 抽象對象角色

聲明目標對象和代理對象的共同接口。

  • 目標對象角色

定義了代理對象所代表的目標對象。

  • 代理對象角色

代理對象內部含有目標對象的引用,可以在任何時候操作目標對象;代理對象提供一個與目標對象相同的接口,可以在任何時候替代目標對象。代理對象通常在客戶端調用傳遞給目標對象之前或之后,執行某個操作,而不是單純地將調用傳遞給目標對象,AOP編程就是基於這個思想。

4、源碼實現

public class C02_Proxy {
    public static void main(String[] args) {
        AbstractObject object = new ProxyObject();
        object.operation();
    }
}
/**
 * 抽象對象角色
 */
abstract class AbstractObject{
    public abstract void operation();
}
/**
 * 目標對象角色
 */
class TargetObject extends AbstractObject{
    @Override
    public void operation() {
        System.out.println("Target Method Run...");
    }
}
/**
 * 代理對象角色
 */
class ProxyObject extends AbstractObject{
    TargetObject targetObject = new TargetObject();
    @Override
    public void operation() {
        System.out.println("Method Before...");
        targetObject.operation();
        System.out.println("Method After...");
    }
}

三、JDK動態代理

基於JDK動態代理方式實現AOP切面編程。

1、代碼實現

public class C03_JdkProxy {
    public static void main(String[] args) {
        BookService bookService = BookAopProxyFactory.createService() ;
        System.out.println(bookService.getBook());
    }
}
class BookAspect {
    public void before (){
        System.out.println("Method Before ...");
    }
    public void after (){
        System.out.println("Method After ...");
    }
}
interface BookService {
    String getBook () ;
}
class BookServiceImpl implements BookService {
    @Override
    public String getBook() {
        System.out.println("目標方法【getBook】被執行");
        return "高性能MySQL";
    }
}
class BookAopProxyFactory {
    public static BookService createService() {
        // 目標類
        final BookService bookService = new BookServiceImpl() ;
        // 切面類
        final BookAspect bookAspect = new BookAspect();
        /*
         * 代理類:將目標類(切入點)和 切面類(通知) 結合
         */
        BookService proxyBookService = (BookService) Proxy.newProxyInstance(
                BookAopProxyFactory.class.getClassLoader(),
                bookService.getClass().getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,
                                         Object[] args) throws Throwable {
                        // 前執行
                        bookAspect.before();
                        // 執行目標類的方法
                        Object obj = method.invoke(bookService, args);
                        // 后執行
                        bookAspect.after();
                        return obj;
                    }
                });
        return proxyBookService ;
    }
}

四、幾種常見代理

  • 防火牆代理

內網通過代理穿透防火牆,實現對公網的訪問。

  • 緩存代理

為了緩解網站並發壓力,在請求數據庫資源時,先取緩存中代理的數據,如果緩存未命中,再到數據庫取數據,然后緩存取到的數據。

  • 遠程代理

遠程對象的本地代理對象,通過它可以把遠程對象當本地對象調用 。遠程代理通過網絡和調用的遠程對象進行信息交互 。

  • 同步代理

主要使用在多線程編程中,完成多線程間同步工作。

五、源代碼地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM