代理模式

作者: 字字经心 | 来源:发表于2022-07-29 12:01 被阅读0次

代理模式

代理模式定义,为另外一个对象提供一个替身以控制对这个对象的访问,是一个控制对象访问的模式。常用的几种控制访问方式有

  • 远程代理控制访问远程对象
  • 保护代理基于权限控制对对象访问,如java 动态代理

假设现在有一个远程的饮料贩卖机器,想在本地监控贩卖情况,就可以在本地产生一个远程的代理对象,本地程序通过本地远程代理来和远程真实对象进行通信。这样客户所做的就像在做远程调用,但是其实只是调用本地代理对象上的方法。再由代理处理所有网络通信的底层细节。

proxy1.png

保护代理,如果一个对象里面的方法不是对每一个对象都是公开的,就可以为对象创建保护代理,每次调用对象方法时触发保护。

假设有一个帮忙实现约会的服务系统,这套系统能鼓励顾客找到可能的配对对象。系统有一个Person bean 对象,允许设置或取得一个人的信息。

public interface PersonBean{
    String getName();
    String getGender();
    // 取得兴趣爱好
    String getInterests();
    // 取得评分1~10
    int getHotOrNotRating();
    
    void setName(String name);
    void setGender(String gender);
    // 设置兴趣爱好
    void setInterests(String interests);
    // 每一次评分都会,再计算平均评分
    void setHotOrNotRating(int rating);
}

// PersonBean 实现
public class PersonBeanImpl implements PersonBean{
    String name;
    String gender;
    String interests;
    int rating;
    int ratingCount = 0;
    
    public String getName(){
        return name;
    }
    
    public int getHotOrNotRating(){
        if(ratingCunt == 0) return 0;
        return (rating/ratingCount);
    } 
    // 其他方法 .....
    
    public void setInterests(String interests){
        this.interests = interests;
    }
    
    public void setHotOrNotRating(int rating){
        this.rating += rating;
        ratingCount++;
    }
}

但是不久就会有人抱怨有人居然篡改了我的兴趣,还有有人居然给自己评高分,以拉高自己的HotOrNotRating 值。所以顾客不可以给自己评分,也不可以修改别人的信息。我们可以为PersonBean 创建保护代理,先看看类图

proxy2.png

在这里PersonBean 就是RealSubject,

  • 图中proxy是由Java 产生的,而且实现了完整的PersonBean 接口
  • InvocationHanlder 是由我们提供的,Proxy 上的任何方法调用都会被传入此类,由它控制对RealSubject 方法的访问

接下来看看具体的代码实现,创建控制自己对主题访问的对象OwnerInvocationHandler,控制别人对主题访问的NonOwnerInvocationHandler 代码类似

import java.lang.reflect.*;

// InvocationHandler 是reflect 里面的接口,实现其中的invoke 方法
public class OwnerInvocationHandler implements InvocationHandler{
    PersonBean Person;
    public OwnerInvocationHandler(PersonBean person){
        this.person = person;
    }
    
    public Object invoke(Object proxy, Method method, object[] args) throws IllegallAccessException{
        try{
            if(method.getName().startsWith("get")){
                return method.invoke(perosn, agrs);
            }else if(method.getName().equals("setHotOrNotRating")){
                // 自己不能给自己评分,调用此方法时抛异常
                throw new IllegalAccessException();
            }else if(method.getName().startWith("set")){
                return method.invoke(perosn, agrs);
            }
        }catch(InvocationTargetException e){
            e.printStackTrace();
        }
        return null;
    }
}

创建getOwnerProxy 代理的方法返回personBean 对象,该代理用于保护自己对personBean 的访问。

// 创建getOwnerProxy 代理
PersonBean getOwnerProxy(PersonBean person){
    // Proxy 是java reflect 包里面的类
    return (PersonBean)Proxy.newProxyInstance(
        person.getClass().getClassLoader(),
        person.getClass().getInterfaces(),
        new OwnerInvocationHandler(person)
        );
}

// 类似的getNonOwnerProxy(),返回NonOwnerInvocationHandler 的代理

// 测试一下,
PersonBean personA = new PersonBean();
personBean ownerProxy = getOwnerProxy(personA);
try{
    // 代理会触发 OwnerInvocationHandler invoke() 
    ownerProxy.setHotOrNotRating(10);
}catch (Exception e){
    System.out.println('Canot set rating from owner proxy);
}

Java 在java.lang.reflect 包中有自己的代理支持,利用这个包可以再运行时动态创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。因为实际的代理类是来运行时创建的,所以称这个Java 技术为:动态代理

复合模式

复合模式:结合两个或两个以上的模式,组成一个解决方案,解决一再发生的一般性问题。我们看看 mvc 模式在web 中的应用,里面也用了好几种设计模式

  • 策略模式,controller 对客户端请求的响应,策略对象是controller,同一个请求可以更换不同的controller 来处理。这不就是策略模式
  • 组合模式,网页由HTML 描述,内部很类似形成组合的对象系统
  • 观察者模式,当model 改变状态时,视图间接地从控制器收到了相当于通知的东西,控制器甚至把模型Bean 给视图
proxy3.png

欢迎大家给我留言,提建议,指出错误,一起讨论学习技术的感受!

相关文章

  • 设计模式

    单例模式 模板方法模式 工厂模式 代理模式 静态代理 JDK动态代理

  • 设计模式

    单例模式 代理模式 静态代理 jdk动态代理 cglib动态代理 工厂模式 适配器模式 建造者模式 观察者模式

  • kube-proxy的3种模式

    userspace代理模式 iptables代理模式 IPVS代理模式 https://kubernetes.io...

  • 第4章 结构型模式-代理模式

    一、代理模式简介 二、代理模式3个角色 三、代理模式的优点 四、代理模式的实例(游戏代练)

  • 理解代理模式

    原创博客地址 简介 代理模式,也叫做委托模式,分为:静态代理动态代理 代理模式也是平时比较常用的设计模式之一,代理...

  • 结构型 代理模式(文末有项目连接)

    1:什么是代理模式 2:没用代理模式时的实例 3:使用代理模式将其解耦(静态代理) 3:使用代理模式将其解耦(动态...

  • 设计模式-动态代理模式

    之前介绍了代理模式,大家也都了解了代理模式,不过之前介绍的代理模式是静态代理,静态代理什么意思?静态代理指的是代理...

  • 代理模式

    一、什么是代理模式 代理模式(Proxy pattern):代理模式又叫委托模式,是为某个对象提供一个代理对象,并...

  • 设计模式之代理模式(Proxy模式)

    代理模式的引入 代理模式的实例程序 代理模式的分析 代理模式的引入 Proxy是代理人的意思,指的是代替别人进行工...

  • Java设计模式之代理模式

    Java设计模式之代理模式 代理模式 静态代理 动态代理 为什么需要代理 通过代理,我们能够不用知道委托人是谁,而...

网友评论

    本文标题:代理模式

    本文链接:https://www.haomeiwen.com/subject/uvrsirtx.html