1. 程式人生 > 其它 >java中代理模式

java中代理模式

java中代理模式

前言

代理(Proxy)模式是一種結構型設計模式,提供了對目標物件另外的訪問方式——即通過代理物件訪問目標物件。

這樣做的好處是:可以在目標物件實現的基礎上,擴充套件目標物件的功能。
代理模式主要涉及三個角色:
Real Subject:目標類,也就是被代理類、委託類。用來真正完成業務服務功能;
Proxy:代理類,將自身的請求用 Real Subject 對應的功能來實現,代理類物件並不真正的去實現其業務功能;
Subject:定義 RealSubject 和 Proxy 角色都應該實現的介面。

正文

靜態代理

靜態代理需要先定義介面,被代理物件與代理物件一起實現相同的介面,代理類持有目標類的引用,然後通過呼叫相同的方法來呼叫目標物件的方法


程式碼例項:
介面類 CarInterfaces.class,定義一組介面

interface CarInterfaces {
    void run();
}

目標類 Car.class

public class Car implements CarInterfaces {
    @Override
    public void run() {
        System.out.println("Car run()");
    }
}

代理類 CarSystemProxy.class

public class CarSystemProxy implements CarInterfaces {
    Car car;

    @Override
    public void run() {
        System.out.println("before car run");
        if (car == null) {
            car = new Car();
        }
        car.run();
        System.out.println("after car run");
    }
}

測試類 CarTest.class

public class CarTest {
    public static void main(String[] args) {
        CarSystemProxy carSystemProxy = new CarSystemProxy();
        carSystemProxy.run();
    }
}

問題:當目標類介面增多後,代理類要代理新增的介面,如果按照靜態代理的模式,代理類中要同步新增介面,這時候就顯得比較麻煩,怎麼才能優化這個操作呢?

動態代理

拓展介面如下 CarInterfaces.class:

interface CarInterfaces {
    void run();

    void playMusic();

    void stop();
}

目標類實現介面 Car.class:

public class Car implements CarInterfaces {
    @Override
    public void run() {
        System.out.println("Car run()");
    }

    @Override
    public void playMusic() {
        System.out.println("Car playMusic()");
    }

    @Override
    public void stop() {
        System.out.println("stop()");
    }
}

代理類 動態代理介面 CarSystemProxy.class:

public class CarSystemProxy {
    Car car;

    public Object getProxy() {
        if (car == null) {
            car = new Car();
        }
        return Proxy
            .newProxyInstance(getClass().getClassLoader(), car.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("find proxy.... ");
                    Object invoke = method.invoke(car, args);
                    return invoke;
                }
            });
    }
}

測試類 CarTest.class:

public class CarTest {
    public static void main(String[] args) {
        CarSystemProxy carSystemProxy = new CarSystemProxy();
        CarInterfaces proxy = (CarInterfaces) carSystemProxy.getProxy();
        proxy.run();
        proxy.playMusic();
        proxy.stop();
    }
}