代理模式-以房屋中介说明

代理模式可以在目标对象的基础上,增加额外的功能,代理对象相当于对真实对象进行封装。

代理模式由三部分组成:

ISubject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口。
RealSubject:真实主题角色,是实现抽象主题接口的类。

Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

下面我们以房屋中介为例说明静态代理模式:

共用的接口:

package proxy;

/**
 * Created by liuliu on 2017/6/9.
 */

public Interface HousingSales{
        void showings();//看房
        void reserve();//预定
        void SignContract();//前合同
}


房东类:

package proxy;

/**
 * Created by liuliu on 2017/6/9.
 */

public class Landlord implements HousingSales {
    public void showings() {
        System.out.println("正在看房");
    }

    public void reserve() {
        System.out.println("正在预定");
    }

    public void SignContract() {
        System.out.println("正在签合同")
    }

}

中介类:

package proxy;

/**
 * Created by liuliu on 2017/6/9.
 */

public class Proxy implements HousingSables {
    private Landlord landlord;

    public Proxy(Landlord landlord) {
        this.landlord = landlord;
    }

    public void showings() {
        landlord.showings();
    }

    public void reserve() {
        landlord.reserve();
    }

    public void SignContract() {
        landlord.SignContract();
    }

    //中介新扩展的功能
    public void serve() {
        //中介服务于租房者
    }

    public void CollectExtraFees() {
        //中介收取多余的费用
    }
}

中介包含了房东的所有功能,当调用中介的方法时,会转去调用房东的相应方法;此外,中介还扩展了新的功能,中介对房东进行了封装。上面是利用组合实现代理类,使用继承亦可。

package proxy;

/**
 * Created by liuliu on 2017/6/9.
 */

public class Proxy extends Landlord {

    public void showings() {
        super.showings();
    }

    public void reserve() {
        super.reserve();
    }

    public void SignContract() {
        super.SignContract();
    }

    //中介新扩展的功能
    public void serve() {
        //中介服务于租房者
    }

    public void CollectExtraFees() {
        //中介收取多余的费用
    }
}

静态代理总结:
1.可以做到在不修改目标对象的功能前提下,对目标功能扩展.
2.缺点:
因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.
如何解决静态代理中的缺点呢?答案是可以使用动态代理方式。


动态代理有以下特点:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象

生成代理对象的API是Proxy类中的静态方法:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

三个参数依次为:
ClassLoader loader : 被代理类的类加载器
Class<?>[]  interfaces : 被代理类实现的接口
InvocationHandler  h : 事件处理器,调用代理类的方法时,会触发invoke方法,转去执行被代理类的方法。

invoke方法中第一个参数是被代理的对象,第二个参数是被代理对象的方法,第三个参数是被代理对象的方法的参数。

静态代理的接口、房东类、中介类都没变,我们增加InvocationHandler ,测试动态代理:

public class Handler implements InvocationHandler {
    private Object target;

    public TimeHandler(Object target) {
        super();
        this.target = target;
    }

    /**
     * 参数:
     * proxy 被代理的对象
     * method 被代理对象的方法
     * args 方法的参数
     * 返回:
     * Object 方法返回值
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        method.invoke(target, args);
        return null;
    }

}


测试:

public class Test {
    public static void main(String[] args) throws Exception {
        Landlord landlord = new Landlord();
        InvocationHandler h = new Handler(landlord);
        Class<?> cls = landlord.getClass();
        /**
         *loader 类加载器
         *interfaces 实现接口
         *h InvocationHandler
         */
        HousingSales housingSales = (HousingSales) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
        housingSales.showings();
        housingSales.reserve();
        housingSales.SignContract();
    }
}

JDK动态代理步骤
1.创建一个实现InvocationHandler接口的类,它必须实现invoke()方法
2.创建被代理的类及接口
3.调用Proxy的静态方法,创建一个代理类
4.通过代理调用方法




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值