1. 程式人生 > 實用技巧 >靜態代理模式和動態代理模式

靜態代理模式和動態代理模式

靜態代理模式和動態代理模式

一.靜態代理模式的理解

要完成租房這件事,定義為介面

//租房這件事
public interface Rent {
    public void rent();
}

房東租房

//房東實現租房
public class Host implements Rent {
    public void rent() {
        System.out.println("我是房東,我要出租房子!");
    }
}

代理即相當於中介給房東租房

//找代理即相當於中介來完成租房
public class Proxy implements Rent {
    //房東物件
    private Host host;
    //對房東進行初始化
    public Proxy(Host host) {
        this.host = host;
    }
    //代理即中介租房時要做的所有事
    public void rent() {
        seeFang();
        //真正的目的
        host.rent();
        qianHetong();
        fare();
    }

    public void seeFang(){
        System.out.println("看房");
    }
    public void qianHetong(){
        System.out.println("籤合同");
    }
    public void fare(){
        System.out.println("收費");
    }
}

代理給房東完成租房

public class Client {
    public static void main(String[] args) {
        //房東要出租房
        Host host=new Host();
        //代理中介幫房東出租房
        Proxy proxy=new Proxy(host);
        //代理中介向客戶出租房
        proxy.rent();
    }
}

二.動態代理模式理解

動態代理核心即動態生成代理類
1.仍以房東租房先來理解

租房介面

//租房介面
public interface Rent {
    public void rent();
}

房東

//房東
public class Host implements Rent {
    public void rent() {
        System.out.println("我是房東,我要出租房子");
    }
}

動態代理類來生成租房代理類

//用這個類自動生成代理類
public class ProxyInvocationHandle implements InvocationHandler {
    //被代理的介面
    private Rent rent;
    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //生成代理類物件
    public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }
    //處理代理例項,並返回結果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(rent, args);
        return result;
    }
}

客戶端

public class Client {
    public static void main(String[] args) {
        Host host=new Host();
        ProxyInvocationHandle pih = new ProxyInvocationHandle();
        pih.setRent(host);
        //生成代理類物件
        Rent proxy = (Rent) pih.getProxy();
        proxy.rent();
    }
}

2.動態代理模式工具類

dao介面定義要做的事情

public interface UserDao {
    public void addUser();
    public void deleteUser();
    public void updateUser();
    public void queryUser();
}

UserService實現介面

public class UserService implements UserDao {

    public void addUser() {
        System.out.println("增加一個使用者");
    }

    public void deleteUser() {
        System.out.println("刪除一個使用者");
    }

    public void updateUser() {
        System.out.println("更新一個使用者");
    }

    public void queryUser() {
        System.out.println("查詢一個使用者");
    }
}

動態代理類工具即可以產生任何一個業務介面的代理類

//用這個類自動生成代理類
public class ProxyInvocationHandle implements InvocationHandler {
    //被代理的介面
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理類物件
    public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //處理代理例項,並返回結果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }

    public void log(String msg){
        System.out.println("執行了"+msg+"方法");
    }
}

客戶端呼叫

public class Client {
    public static void main(String[] args) {
        //真實角色
        UserService UserService=new UserService();
        //代理角色,不存在
        ProxyInvocationHandle pih=new ProxyInvocationHandle();
        //設定要代理的物件
        pih.setTarget(UserService);
        //動態生成代理類
        UserDao proxy = (UserDao) pih.getProxy();

        proxy.addUser();

    }
}

執行結果: