zoukankan      html  css  js  c++  java
  • 设计模式——代理模式

    知识点:静态代理和动态代理

    参考博客:https://www.cnblogs.com/daniels/p/8242592.html

                      https://blog.csdn.net/familyshizhouna/article/details/78905997

    一:什么是代理模式

    代理模式是给某个对象提供一个代理对象,由代理对象调用原对象的方法,类似我们生活中的中介,经纪人的角色,本人不直接去做,找一个人代替我们去做一些事情。

    二:使用代理模式的好处

    a.中介隔离作用:当我们不想直接调用一个对象时,代理对象可以起一个中介隔离的作用,被代理对象和代理对象都实现相同的接口

    b.遵循开闭原则:我们可以通过代理类,在被代理类功能前后,加入一些公共服务,比如缓存,日志等,而不用修改原被代理类

    三:代理模式的分类

     按创建代理的时间分类可以分为:静态代理和动态代理

       静态代理是代码创建后编译,运行之前,代理类的.class文件就已经创建了;

      动态代理:是在程序运行时,通过反射机制动态创建代理对象的(另一篇博客简略地介绍Java中的反射:https://www.cnblogs.com/shuaifing/p/10863645.html)

    (1)静态代理

    //代理模式(静态代理)
    //测试类
    public class StaticProxy {
    public static void main(String[] args) {
    Object obj=new ProxyObject();
    obj.action();
    }
    }
    //公共接口
    interface Object{
    void action();
    }
    //代理类
    class ProxyObject implements Object{
    Object obj;
    public ProxyObject(){
    System.out.println("代理类构造方法创建被代理类");
    obj=new ObjectImp();
    }
    @Override
    public void action() {
    System.out.println("代理类执行被代理类中的方法");
    obj.action();
    }
    }
    //被代理类
    class ObjectImp implements Object{
    @Override
    public void action() {
    System.out.println("被代理类输出的内容!");
    }
    }
    运行结果:

    (2)动态代理

    当有多个类要代理的话,手动创建多个代理对象比较麻烦,代码冗余,动态产生代理对象的话,代码更加灵活,方便

    //动态代理,反射是动态语言的关键
    //测试类
    public class DynamicProxy {
    public static void main(String[] args) {
    //1.被代理类的对象
    RealSubject realSubject=new RealSubject();
    //2.创建一个实现InvocationHandler接口类的对象
    MyInvocationHandler handler=new MyInvocationHandler();
    //3.调用blind()方法,动态返回一个实现了跟被代理类所实现接口的代理对象
    Object obj=handler.blind(realSubject);
    Subject subject=(Subject) obj;//subject是代理类对象
    subject.action();//代理类对象调用action(),会转到对InvocationHandler接口实现类的invoke()方法调用


    //增加另一个 ObjectImp的被代理对象,返回相应的代理对象
    ObjectImp objIml=new ObjectImp();
    com.kdgc.interfacetest.Object proxyObject= (com.kdgc.interfacetest.Object)handler.blind(objIml);
    proxyObject.action();
    }
    }
    //公共接口
    interface Subject{
    void action();
    }
    //被代理类
    class RealSubject implements Subject{
    @Override
    public void action() {
    System.out.println("被代理类要执行的方法!");
    }
    }
    class MyInvocationHandler implements InvocationHandler{
    Object obj;//实现了接口的被代理对象的声明

    //1.给被代理对象实例化 2.返回一个代理类的对象
    public Object blind(Object obj){
    this.obj=obj;
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    }
    //当通过代理类的对象发起对被重写方法的调用时,会转化为对下面的invoke方法的调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object val=method.invoke(obj,args);
    return val;
    }
    }

    运行结果:

     (3)补充:动态代理与AOP

    在固定的代码的位置,动态地调用不同对象的方法

       //测试类

    public class AOPTest {
    public static void main(String[] args) {
    Man man = new Man();
    Person person = (Person) MyProxy.getProxyInstance(man);
    person.drink();
    person.eat();
    }
    }
    //公共接口
    interface Person{
    void eat();
    void drink();
    }
    //被代理类
    class Man implements Person{
    @Override
    public void eat() {
    System.out.println("吃东西!");
    }
    @Override
    public void drink() {
    System.out.println("喝水!");
    }
    }
    //固定的方法
    class ChangelessMethodUtil{
    public void method1(){
    System.out.println("===========方法1==========");
    }
    public void method2(){
    System.out.println("============方法2===========");
    }
    }
    class MyInvocationHanlder implements InvocationHandler{
    Object obj;//代理类的声明
    public void setObject(Object obj){
    this.obj=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    ChangelessMethodUtil changelessMethodUtil=new ChangelessMethodUtil();
    changelessMethodUtil.method1();

    method.invoke(obj,args);

    changelessMethodUtil.method2();
    return null;
    }
    }
    class MyProxy{
    //动态创建一个代理类的对象
    public static Object getProxyInstance(Object obj){
    MyInvocationHanlder hanlder=new MyInvocationHanlder();
    hanlder.setObject(obj);

    return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),hanlder);
    }
    }

    运行结果:

  • 相关阅读:
    [Swift]LeetCode632. 最小区间 | Smallest Range
    [Swift]有用的Binary Heap Type类
    [Swift]LeetCode633. 平方数之和 | Sum of Square Numbers
    [Swift]LeetCode630. 课程表 III | Course Schedule III
    [Swift]LeetCode629. K个逆序对数组 | K Inverse Pairs Array
    [Swift]LeetCode628. 三个数的最大乘积 | Maximum Product of Three Numbers
    [SQL]LeetCode627. 交换工资 | Swap Salary
    [SQL]LeetCode626. 换座位 | Exchange Seats
    [Swift]LeetCode623. 在二叉树中增加一行 | Add One Row to Tree
    [Swift]LeetCode622. 设计循环队列 | Design Circular Queue
  • 原文地址:https://www.cnblogs.com/shuaifing/p/10862633.html
Copyright © 2011-2022 走看看