代理模式

一、代理模式

代理(Proxy)是一种设计模式,提供了间接对目标对象进行访问的方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能。这就符合了设计模式的开闭原则,即在对既有代码不改动的情况下进行功能的扩展。

①静态代理(以租房为例)

在使用静态代理时,被代理对象与代理对象需要一起实现相同的接口或者是继承相同父类,因此要定义一个接口或抽象类.
1、编写接口
package cn.cduestc.proxymode.staticproxy;

//租房的操作
public interface Rent {
    void rent();
}
2、创建真实出租房屋的对象
package cn.cduestc.proxymode.staticproxy;

//房东: 房东需要进行出租房屋操作
public class Host implements Rent {

    @Override
    public void rent() {
        System.out.println("房东将房子出租出去");
    }
}
3、创建代理对象
package cn.cduestc.proxymode.staticproxy;

//代理对象(中介):也需要有出租房屋操作
public class ProxyManager implements Rent {

    //中介应该持有具有出租房屋意向的房东的引用
    private Rent rent;

    public ProxyManager(){

    }

    public ProxyManager(Rent rent){
        this.rent = rent;
    }

    @Override
    public void rent() {
        seeHouse();
        rent.rent();
        contract();
    }

    public void seeHouse(){
        System.out.println("带客户去看房");
    }

    public void contract(){
        System.out.println("客户签订合同");
    }
}
4、创建客户对象
package cn.cduestc.proxymode.staticproxy;

//客户
public class Client {
    public static void main(String[] args) {
        //创建一个房东对象,即看上一套房子,去联系中介
        Host host = new Host();
        //将这套意向房屋告诉中介
        ProxyManager proxyManager = new ProxyManager(host);
        //租下这套房
        proxyManager.rent();
    }
}
优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。

②动态代理(用找工作为例)

1、编写被代理接口
package cn.cduestc.proxymode.dynamicproxy;

//职位接口
public interface Job {
    void job();
}
2、创建有招人意向的公司
package cn.cduestc.proxymode.dynamicproxy;

//公司有职位,需要人来入职
public class Company implements Job {
    @Override
    public void job() {
        System.out.println("公司有职位需要招人");
    }
}
3、编写创建代理类的类
package cn.cduestc.proxymode.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//自动生成代理对象的类
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的工作,中介介绍工作
    private Job job;

    public void setJob(Job job) {
        this.job = job;
    }

    //生成代理对象的方法
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),job.getClass().getInterfaces(), this);
    }

    //执行代理实例中需要执行的代码
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        Object result = method.invoke(job, args);
        return result;
    }

    public void log(String msg){
        System.out.println("[Debug] 执行了" + msg);
    }
}

4、测试(创建找工作的人)
package cn.cduestc.proxymode.dynamicproxy;

//找工作的人
public class Client {
    public static void main(String[] args) {
        Company company = new Company();

        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setJob(company);

        //获取代理实例
        Job proxy = (Job) pih.getProxy();

        proxy.job();
    }
}

③创建代理类的模板

package cn.cduestc.proxymode;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//自动生成代理对象的模板
public class ProxyInvocationHandlerDemo 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);
    }

    //执行代理实例中需要执行的代码
    @Override
    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("[Debug] 执行了" + msg);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值