Java--设计模式(代理)

参考文章
参考文章

定义
代理模式的本质是一个中间件,主要目的是解耦合服务提供者和使用者。使用者通过代理间接的访问服务提供者,便于后者的封装和控制。是一种结构性模式。
优缺点
# 优点
低耦合
易扩展
灵活度高
# 缺点
间接访问可能会延迟请求相应
增加工作量
分类
# 静态代理
# 动态代理
代理类本身的实现可能并不简单,加上每一个需要代理的对象均需要实现一个代理类,其工作量本身比较大,易出错。
所谓动态代理(DynamicProxy)是指在程序运行时动态的生成对目标对象的访问接口。
主要用途
1、远程代理
2、虚代理
3、保护代理
4、智能指引代理
5、写时复制(Copy-on-Write)代理
6、缓存代理
7、防火墙代理
8、同步化代理
原理
# Subject
定义RealSubject对外的接口,且这些接口必须被Proxy实现,这样外部调用proxy的接口最终都被转化为对realsubject的调用。
# RealSubject:
真正的目标对象。
# Proxy:
目标对象的代理,负责控制和管理目标对象,并间接地传递外部对目标对象的访问。
1、Remote Proxy: 对本地的请求以及参数进行序列化,向远程对象发送请求,并对响应结果进行反序列化,将最终结果反馈给调用者;
2、Virtual Proxy: 当目标对象的创建开销比较大的时候,可以使用延迟或者异步的方式创建目标对象;
3、Protection Proxy: 细化对目标对象访问权限的控制;

在这里插入图片描述

网络代理

在这里插入图片描述

// 定义公共接口类Server
public interface Server{
    void visit(String url);
}

// 代理服务器ProxyServer
public class ProxyServer implements Server{
   private RealServer realServer;
   public ProxyServer(String serverName){
      this.realServer = new RealServer(serverName);
   }
   @Override
   public void visit(String url){
      realServer.visit(url);
   }
}

// 目标服务器RealServer
public class RealServer implements Server{
    private String serverName;
    public RealServer(String serverName){
        this.serverName = serverName;
        System.out.println("This is " + serverName);
    }
    @Override
    public void visit(String url){
        response(url);
    }
    private void response(String res){
        System.out.println("This is response of " + res + " from server:" + serverName);
    }
}

// 演示
public class Demo{
    public static void main(String[] args){
        Server server = new ProxyServer("www.google.com");
        server.visit("map.google.com");
    }
}
静态代理

静态代理的的代理类是我们自己定义好的,在程序运行之前就已经编译完成。
举例:一个班的学生需要交作业,现在让班长代理交作业,那么班长就是代理,学生就是被代理的对象。

// 这个接口是被代理(学生),和代理(班长)的公共接口
public interface Person{
    //交作业
    void giveTask();
}
// 学生实现交作业
public class Student implements Person{
    private String name;
    public Student(String name){
        this.name = name;
    }
    public void giveTask(){
        System.out.println(name + "交语文作业");
    }
}
// 学生代理类(班长),也实现了Person接口,保存一个学生实体,这样就可以代理学生产生行为。
public class StudentsProxy implements Person{
    // 被代理的学生
    private Student student;
	// 只代理学生对象
    public StudentsProxy(Person student){
        if(student.getClass() == Student.class) {
            this.student = (Student)student;
        }
    }
    // 代理交作业,调用被代理学生的交作业的行为
    public void giveTask(){
        student.giveTask();
    }
}
public class StaticProxyTest{
    public static void main(String[] args) {
        // 被代理的学生林浅,他的作业上交有代理对象monitor完成
        Person linqian = new Student("林浅");
        // 生成代理对象,并将林浅传给代理对象
        Person monitor = new StudentsProxy(linqian);
        // 班长代理交作业
        monitor.giveTask();
    }
}
动态代理

动态代理的代理类是在程序运行时创建的。

// 这个接口是被代理(学生),和代理(班长)的公共接口
public interface Person{
    //交作业
    void giveTask();
}
// 学生实现交作业
public class Student implements Person{
    private String name;
    public Student(String name) {
        this.name = name;
    }
    public void giveTask() {
        System.out.println(name + "交语文作业");
    }
}
// 实现InvocationHandler接口,实现类中持有一个被代理对象的实例target。
// InvocationHandler中有一个invoke方法,所有执行代理对象的方法都会被替换成执行invoke方法。
public class StuInvocationHandler<T> implements InvocationHandler{
    // invocationHandler持有的被代理对象
	public T target;
    public StuInvocationHandler(T target){
        this.target = target;
    }
    /**
     * proxy:代表动态代理对象
     * method:代表正在执行的方法
     * objects:代表调用目标方法时传入的实参
     */
    public Object invoke(Object proxy, Method method, Object[] objects) throws Throwable {
        System.out.println("代理执行" + method.getName() + "方法!");
        return method.invoke(target, objects);
    }
}
public class ProxyTest{
    public static void main(String[] args) {
		// 创建一个实例对象,这个对象是被代理的对象
        Person linqian = new Student("林浅");
        // 创建一个与代理对象相关联的InvocationHandler
        InvocationHandler stuHandler = new StuInvocationHandler<Person>(linqian);
        // 创建一个代理对象stuProxy来代理linqian,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
        Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
        // 代理执行交作业的方法
        stuProxy.giveTask();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你默然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值