代理模式与动态代理

简介: 代理模式与动态代理

代理模式与动态代理

1 概述

代理模式是在二十三种设计模式中比较接近现实生活和容易理解的一种设计模式,简单的来说就是A通过B的代理,与C进行通信,如图:

网络异常,图片无法展示
|


当然这样看来并没有增加A与C通信的效率,反而多了一层代理,但是,当A多了以后呢?

网络异常,图片无法展示
|


显然,这样可以只让B与C进行通信,类似于多加了一层的代理层,专门用来处理请求,再来一个现实点的例子:

如果一个人有事想找你你可以直接与他对话,而如果一群人想找你你一定不能同时与他们进行对话,就需要一个一个的回复,比如我们平常的移动联系方式微信,此时他就可以代理你进行消息的接收和回复,如图 :

网络异常,图片无法展示
|


因此,我们总结下代理模式的概念和优点:

定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

优点:(1)职责清晰 (2)高扩展性(3)智能化

2 代理模式(静态代理)

静态代理简单的说就是接口代理实现类,当一个或多个类实现一个接口后,需要将接口的方法进行实现,当类进行实例化时使用接口进行代理方法的实现,直接调用接口的方法而不是实现类的方法。

网络异常,图片无法展示
|


/**
 * 代理模式(静态代理)
 *
 * @author 17122
 */
public class StaticProxy {
    public static void main(String[] args) {
        People people = new Programmer();
        people.sayHello();
    }
}
interface People {
    /**
     * sayHello方法
     */
    void sayHello();
}
class Student implements People {
    @Override
    public void sayHello() {
        System.out.println("Hello I am a Student");
    }
    public void study() {
        System.out.println("Study");
    }
}
class Programmer implements People {
    @Override
    public void sayHello() {
        System.out.println("Hello I am a Programmer");
    }
    public void playCode() {
        System.out.println("Play code");
    }
}
复制代码

3 动态代理

动态代理的实现较为复杂,因为要实现动态代理就需要依托Java的反射机制,就是JDK官方原生的代理,继承InvocationHandler接口,实现invoke方法,就可以自定义代理工具类,根据不同的类进行动态的代理。

网络异常,图片无法展示
|


/**
 * 动态代理
 *
 * @author 17122
 */
public class DynamicProxy {
    public static void main(String[] args) {
        Boos boos = new Boos();
        Worker worker = new Worker();
        getDynamicProxy(worker, Worker.class);
        getDynamicProxy(boos, Boos.class);
    }
    /**
     * 动态代理实现方法
     *
     * @param obj
     * @param clazz
     */
    public static void getDynamicProxy(Object obj, Class clazz) {
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(obj);
        Courier instance = (Courier) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), myInvocationHandler);
        instance.takeSomething();
    }
}
/**
 * 快递员
 */
interface Courier {
    /**
     * 取东西
     */
    void takeSomething();
}
class Worker implements Courier {
    @Override
    public void takeSomething() {
        System.out.println("Worker take Something");
    }
}
class Boos implements Courier {
    @Override
    public void takeSomething() {
        System.out.println("Boos take Something");
    }
}
class MyInvocationHandler implements InvocationHandler {
    /**
     * 被代理的目标类
     */
    private Object target;
    /**
     * 构造方法 放入目标类
     *
     * @param target
     */
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    /**
     * Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.
     * 返回指定接口的代理类实例,该接口将方法调用分派给指定的调用处理程序。
     *
     * @param proxy  the class loader to define the proxy class  定义代理类的类装入器
     * @param method the list of interfaces for the proxy class to implement  代理类要实现的接口列表
     * @param args   the invocation handler to dispatch method invocations to  将方法调用分派到的调用处理程序
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result = method.invoke(target, args);
        return result;
    }
}
复制代码

4 静态代理和动态代理有什么不同

(1)最主要的不同就是动态代理依靠反射机制,可以在程序运行的过程中进行被代理对象的确定,而静态代理在程序编译时期就已经确定。

(2)静态代理需要自己写代码进行完成,而动态代理就是通过Proxy.newInstance()生成。


相关文章
|
10月前
|
前端开发 安全 开发者
【通义灵码实践】实现经典手机游戏推箱子
本文介绍了使用通义灵码辅助实现经典推箱子游戏的过程。首先,通过输入“用Python写一个推箱子游戏”,灵码生成了基本的终端版本代码,包括地图渲染、玩家移动和胜利检测等功能。然而,终端版本交互体验不佳。为了解决这一问题,再次输入“不要在终端上运行,希望可以在页面上运行”,灵码生成了基于Flask的后端代码和HTML前端代码,实现了网页版推箱子游戏。最终结果展示了游戏的完整实现,包括前后端交互和用户界面。总结中提到,该方法具有快速生成代码、代码质量高、易于扩展等优点,但也存在功能简单、样式和用户体验有限、错误处理不足等问题,适合快速原型开发和教学演示。
297 2
|
12月前
|
Python
Python 练习实例90
Python 练习实例90
|
SQL 安全 Devops
一个简单的代码拼写错误导致17个生产数据库被删!微软Azure DevOps宕机10小时始末
一个简单的代码拼写错误导致17个生产数据库被删!微软Azure DevOps宕机10小时始末
195 0
|
Java 容器
Java——使用多线程模拟真实高并发业务并保证安全性(二)
Java——使用多线程模拟真实高并发业务并保证安全性(二)
|
存储 程序员 C语言
C++的数据类型
C++的数据类型
|
NoSQL 数据库
|
SQL 索引 数据库管理
[20170412]op code列表.txt
[20170412]op code列表.txt 转载:http://www.itpub.net/thread-1517926-1-1.html --看redo转储,需要了解OP的含义,做一个记录: 附op code列表(来自网络): 格式:lay...
1083 0
|
7天前
|
人工智能 运维 安全
|
5天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
607 21