当前位置: 代码网 > it编程>软件设计>设计模式 > 一天攻克一个知识点 —— 设计模式之动态代理

一天攻克一个知识点 —— 设计模式之动态代理

2024年08月02日 设计模式 我要评论
经典模式值得反复巩固。

一、设计模式之代理设计

代理设计是在java开发中使用较多的一种设计模式,所谓的代理设计模式就是指一个代理主体操作真实主体,真实主体操作具体业务,代理主体负责给具体业务添砖加瓦。
就好比在生活中你有一套房子想要出租(你=真实主体),你找了房产中介(中介=代理主体)。真实主体负责提供房屋和收钱,代理主体负责带客户看房 、扣除手续费。租客只管租房子和付款,至于谁提供的房子并不关心。

我们发现,只需要定义一个租赁的接口,真实主体与代理主体都可以实现此接口,然后再由代理主体操作真实主体即可,上面的要求可以形成如下的代码:

1. 定义租赁接口

package com.javabasic.proxy;

/**
 * 定义抽象接口
 */
public interface house {

    /**
     * 定义抽象方法 租赁
     */
    void rent();
}

2. 定义真实主体 - 房东

package com.javabasic.proxy;

/**
 * 定义真实主体 房东
 */
public class owner implements house{

    @override
    public void rent() {
        system.out.println("房东提供房子,收取租金200元/月");
    }
}

3. 定义代理主体 - 中介

package com.javabasic.proxy;

/**
 * 定义代理主体 中介
 */
public class agent implements house{

    // 接收真实主体 房东
    private house house;

    /**
     * 通过构造方法,让中介与房东之间产生联系。
     * 根据java动态绑定机制,house运行时的真实类型是房东类型,就可以获取到房东的出租行为。
     * @param house
     */
    public agent(house house){
        this.house = house;
    }

    /**
     * 中介对房东出租业务进行增强
     */
    @override
    public void rent() {
        rentbefore();
        house.rent(); // 房东 出租
        rentafter();
    }

    private void rentbefore(){
        system.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");
    }

    private void rentafter(){
        system.out.println("中介负责租客退租后的清扫工作。");
    }

}

4. 主程序 中介出租房屋

在这里插入图片描述

二、动态代理

上面讲解的代理机制的操作,属于静态代理,因为每一个代理类只能为一个接口服务,这样程序开发中必然会产生过多的代理类。最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理功能。

java 中想要实现动态代理的机制,则需要java.lang.reflect.invocationhandler接口java.lang.reflect.proxy类的支持。

invocationhandler接口的定义如下:

package java.lang.reflect;

public interface invocationhandler {

    public object invoke(object proxy, method method, object[] args)
        throws throwable;
}

proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类。

	/*
		classloader loader : 类加载器
		class<?>[] interfaces : 得到真实类实现的全部接口
		invocationhandler h : 得到invocationhandler子类实例
	*/
    @callersensitive
    public static object newproxyinstance(classloader loader,
                                          class<?>[] interfaces,
                                          invocationhandler h)
        throws illegalargumentexception
    {
        ...
    }

房屋租赁代码修改如下 :

1. 需要房东实现租赁的接口

public interface house {

    /**
     * 定义抽象方法 租赁
     */
    void rent();
}

public class owner implements house{

    @override
    public void rent() {
        system.out.println("房东提供房子,收取租金200元/月");
    }
}

2. 创建代理类(invocationhandler / proxy)

package com.javabasic.proxy;

import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
import java.lang.reflect.proxy;

public class agent2 implements invocationhandler {

    // 接收真实主体
    private object obj;

    // 对外提供绑定真实主体方法
    public object bind(object obj){
        this.obj = obj;
        // 通过真实对象创建代理对象并返回给调用者。
        /*
             proxy.newproxyinstance : 三个参数
                    类加载器 :  this.obj.getclass().getclassloader()
                    真实类型实现的所有接口 : this.obj.getclass().getinterfaces()
                    代理类  : this
             return 代理对象
         */
        object object = proxy.newproxyinstance(this.obj.getclass().getclassloader(),
                this.obj.getclass().getinterfaces(), this);
        system.out.println("bind之后object真实类型 = " + object.getclass().getname());
        return object;
    }

    /**
     * 代理类会执行的方法。
     * @param proxy 代理主体
     * @param method 调用的方法
     * @param args 方法的参数
     *
     * @return
     * @throws throwable
     */
    @override
    public object invoke(object proxy, method method, object[] args) throws throwable {
        system.out.println("proxy真实类型 = " + proxy.getclass().getname());
        
        rentbefore();
        method.invoke(this.obj, args); // 通过反射执行真实主体方法
        rentafter();
        return null;
    }

    private void rentbefore(){
        system.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");
    }

    private void rentafter(){
        system.out.println("中介负责租客退租后的清扫工作。");
    }
}

3. 主程序 出租

在这里插入图片描述

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com