设计模式之代理模式

代理模式(Proxy pattern)

  代理模式为其它对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能。

举个例子来说:房东和租房中介之间就是代理与被代理的关系,房东出租房屋,可以看做是一个目标对象,其他琐碎事交给中介来处理。

代理模式设计到的角色:

      抽象角色:声明真实对象和代理角色的共同接口

      代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。代理对象在执行真实对象操作时,可以附加自己的操作,相当于对真实对象进行封装。将统一的流程控制放到代理角色中处理。

      真实角色:代理角色所代表的真实对象,定义真实角色所要实现的业务逻辑,供代理角色调用。是我们最终要引用的对象。

代理模式的分类:

     1. 静态代理

      2. 动态代理         

静态代理的实现:

1.接口

package com.dsx.proxy;
//出租房屋
public interface Rent {
    public void rent();
}

2. 真实角色

package com.dsx.proxy;
//房东
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子");
    }
}

3. 代理角色

package com.dsx.proxy;

public class Proxy implements Rent {
    private Host host;
    public Proxy(){}
    public Proxy(Host host) {
        this.host = host;
    }

    @Override
    public void rent() {
        seeHouse();
        System.out.println("代理帮助房东出租房子");
        fare();
    }
    public void seeHouse(){
        System.out.println("中介带你看房子");
    }
    public void fare(){
        System.out.println("收中介费");
    }
}

4. 客户端访问代理角色

package com.dsx.proxy;

public class Client {
    public static void main(String[] args) {
        //房东要出租房子,
        Host host = new Host();
        //代理 中介帮助房东出租房子,但是,代理一般会有一些附属操作
        Proxy proxy = new Proxy(host);
        //不用面对房东,直接找中介就可以
        proxy.rent();
    }
}

代理模式的优点:

        1.代理模式能将代理对象与真实对象被调用的目标对象分离,使真实角色的操作更加纯粹,不用关注一些公共的业务。
        2.一定程度上降低了系统的耦合度,扩展性好。
        3.保护目标对象。
        4.增强目标对象。

代理模式的缺点:

      1.代理模式会造成系统设计中类的数目的增加(一个真实角色就会产生一个代理角色)。
      2.在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢
      3.增加了系统的复杂度。

动态代理

 动态代理和静态代理角色一样

动态代理的代理类是动态生成的,不是我们直接写好的

动态代理分为两大类:基于接口的动态代理,基于类的动态代理

           基于接口------>  JDK动态代理

           基于类: CGLIB代理       java字节码操作库实现:javassist

代码实现(以JDK代理为例):

需要了解的类:

• JDK自带的动态代理

     – java.lang.reflect.Proxy

     • 作用:动态生成代理类和对象

     – java.lang.reflect.InvocationHandler(处理器接口)

     • 可以通过invoke方法实现对真实角色的代理访问。 • 每次通过Proxy生成代理类对象对象时都要指定对应的处理器对象

1. 接口

package com.dsx.proxy;
//出租房屋
public interface Rent {
    public void rent();
}

2. 真实角色

package com.dsx.proxy;
//房东
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子");
    }
}

3.动态代理的实现

package com.dsx.proxy.dongtaidaili;

import com.dsx.proxy.Host;
import com.dsx.proxy.Rent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;

    public Object getTarget() {
        return 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 seeHouse(){
        System.out.println("中介看房子");
    }
    public void fare(){
        System.out.println("中介收中介费");
    }
    public void log(String msg){
        System.out.println("执行了"+msg+"方法");
    }
}

4.测试代码

 public static void main(String[] args) {
        //真实角色
        Host host = new Host();
        //代理角色
        ProxyInvocationHandler p = new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象
        p.setTarget(host);//设置要代理的对象
        //动态生成代理类
        Rent proxy =(Rent) p.getProxy();
        proxy.rent();


    }

运行结果:

动态代理相比静态代理的优点

一个动态代理类代理的是一个接口,一般就是对应的一类业务。

一个动态代理类可以代理多个类,只要实现了同一个接口即可。

抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,我们可以更加灵活和统一的处理众多方法。

代理模式在开发框架中的应用场景:

   1. struts2中拦截器的实现

   2. 数据库连接池关闭处理

   3. Hibernate中延迟加载的实现

   4. mybatis中实现拦截器插件

   5.AspectJ的实现

   6. spring中AOP的实现(日志拦截,声明式事务处理)

   在Spring的AOP编程中:

      如果加入容器的目标对象有实现接口,用JDK代理

      如果目标对象没有实现接口,用Cglib代理。

以上便是对代理模式的简单回顾,spring的AOP可以参考本人之前的博客 https://blog.csdn.net/duan196_118/article/details/104133176

如有不足,欢迎留言指正,望不吝赐教!!!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【1】项目代码完整且功能都验证ok,确保稳定可靠运行后才上传。欢迎下载使用!在使用过程,如有问题或建议,请及时私信沟通,帮助解答。 【2】项目主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 【3】项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 【4】如果基础还行,或热爱钻研,可基于此项目进行二次开发,DIY其他不同功能,欢迎交流学习。 【注意】 项目下载解压后,项目名字和项目路径不要用文,否则可能会出现解析不了的错误,建议解压重命名为英文名字后再运行!有问题私信沟通,祝顺利! 基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip基于C语言实现智能决策的人机跳棋对战系统源码+报告+详细说明.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值