返回顶部
首页 > 资讯 > 后端开发 > Python >Java通俗易懂系列设计模式之代理模式
  • 483
分享到

Java通俗易懂系列设计模式之代理模式

2024-04-02 19:04:59 483人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录前言介绍实现一.静态代理二.jdk动态代理三.Cglib动态代理总结前言 国内程序员好像普遍对百度都没好感,而且百度近些年产生了不少负面的新闻,像16年的魏则西事件,近期的导演吴

前言

国内程序员好像普遍对百度都没好感,而且百度近些年产生了不少负面的新闻,像16年的魏则西事件,近期的导演吴京黑白照事件,以及最近作家六六斥百度李彦宏:“你是做搜索引擎还是骗子首领”,还有一件就是与程序员有关的:搜索Julia语言,在百度和Google得出首条搜索结果的差异性而被吐槽。Google虽然受欢迎,但是在国内因内容审查问题未解决而不能使用,如果我们要使用它就必须使用代理服务器,由于放置代理服务器的地区区域可以访问google,所以我们可以先访问代理服务器,通过代理服务器转发我们的请求。这是现实生活中的一种代理模式的实例,当然现实生活中这种实例很不少,像明星都有助理,打官司有代理律师等等,这种思想也可以用到我们程序设计中。

介绍

设计模式中代理模式可以分为静态代理和动态代理,而动态代理根据代理的对象类型不同又可以分为Jdk动态代理和Cglib动态代理。

意图:为其他对象提供一种代理以控制对这个对象的访问。

主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

何时使用:想在访问一个类时做一些控制。

如何解决:增加中间层。

关键代码:实现与被代理类组合。

实现

近几年中国电影行业蓬勃发展,电影摄制需要的一种特殊演员->替身,主要任务是代替影片中原演员表演某些特殊的、高难度的动作和技能或原演员所不能胜任的惊险动作,如武打、骑术、驾车等。拍摄的时候虽然是替身在拍摄,但是呈现在荧幕前我们观众却不知道是替身而认为是明星的真实拍摄,代理模式也有这种特点,虽然是代理类在完成任务,但是呈现出来的却是真实类的实现。接下来我们以这种生活中的实例来作示例:

公共表演接口的定义



public interface PerfORMance {
    void act();
}

一.静态代理

明星的实体类



public class Actor implements Performance {
    @Override
    public void act() {
        System.out.println("明星上场拍功夫电影");
    }
}

替身演员的实体类



public class Stuntman implements Performance {

    private Actor actor;

    @Override
    public void act() {
        if (actor == null) {
            actor = new Actor();
        }
        System.out.println("替身演员表演跳火车.");
        actor.act();
        System.out.println("替身演员表演空中360°旋转飞踢.");
    }
}

执行Demo


public class ProxyPatternDemo {
    public static void main(String[] args) {
        System.out.println("------电影拍摄开始------");
        Performance perform = new Stuntman();
        perform.act();
        System.out.println("------电影拍摄结束------");
    }
}

执行程序,输出结果:

------电影拍摄开始------

替身演员表演跳火车.

明星上场拍功夫电影

替身演员表演空中360°旋转飞踢.

二.Jdk动态代理

1、Jdk动态代理是由Java内部的反射机制来实现的,目标类基于统一的接口InvocationHandler。

2、代理对象是在程序运行时产生的,而不是编译期;

3、对代理对象的所有接口方法调用都会转发到InvocationHandler.invoke()方法,在invoke()方法里我们可以加入任何逻辑,比如修改方法参数,加入日志功能、安全检查功能等;之后我们通过某种方式执行真正的方法体,

4、对于从Object中继承的方法,JDK动态代理会把hashCode()、equals()、toString()这三个非接口方法转发给InvocationHandler,其余的Object方法则不会转发。详见JDK Proxy官方文档。

jdk动态代理实现


public class JdkDynamicProxy implements InvocationHandler {

    private Object target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("替身演员表演跳火车.");
        Object o = method.invoke(target, args);
        System.out.println("替身演员表演空中360°旋转飞踢.");
        return o;
    }

    public Object bind(Object target) {
        //取得代理对象
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
}

执行Demo


public static void main(String[] args) {
     //创建JDK动态代理类
     JdkDynamicProxy proxy = new JdkDynamicProxy();
     //绑定对象
     Performance performProxy = (Performance) proxy.bind(new Actor());
     System.out.println("------电影拍摄开始------");
     performProxy.act();
     System.out.println("------电影拍摄结束------");
}

执行结果

------电影拍摄开始------

替身演员表演跳火车.

明星上场拍功夫电影

替身演员表演空中360°旋转飞踢.

Java动态代理为我们提供了非常灵活的代理机制,但Jdk动态代理是基于接口的,如果对象没有实现接口我们该如何代理呢?答案是Cglib动态代理。

三.Cglib动态代理

cglib动态代理底层则是借助asm来实现的,它允许我们在运行时对字节码进行修改和动态生成,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。
目标类基于统一的接口MethodInterceptor。

CGLIB的核心类:
net.sf.cglib.proxy.Enhancer – 主要的增强类。
net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现。
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用。

我们要使用cglib代理必须引入cglib的jar包(package net.sf.cglib.proxy;),我在这里使用的是spring包中cglib,其实和单独的引cglib包是一样的,只不过spring为了版本不冲突,将cglib包含在自己的包中。

cglib动态代理实现:


import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class CglibDynamicProxy implements MethodInterceptor {

    private Object target;

    //创建代理对象
    public Object getInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        // 回调方法
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("替身演员表演跳火车.");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("替身演员表演空中360°旋转飞踢.");
        return result;
    }
}

执行Demo


public static void main(String[] args) {
       CglibDynamicProxy cglibProxy = new CglibDynamicProxy();
        Performance userService = (Performance) cglibProxy.getInstance(new Actor());
        System.out.println("------电影拍摄开始------");
        userService.act();
        System.out.println("------电影拍摄结束------");
    }

执行结果

------电影拍摄开始------

替身演员表演跳火车.

明星上场拍功夫电影

替身演员表演空中360°旋转飞踢.

总结

1、通过以上的例子我们可以发现代理模式的特点:

优点:

  • 职责清晰。
  • 高扩展性。
  • 智能化。

缺点:

  • 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  • 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

2、Jdk动态代理和Cglib动态代理的区别:

  • JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理。
  • cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。同样的,final方法是不能重载的,所以也不能通过CGLIB代理,遇到这种情况不会抛异常,而是会跳过final方法只代理其他方法。
  • JDK动态代理是Java原生支持的,不需要任何外部依赖,但是它只能基于接口进行代理;CGLIB通过继承的方式进行代理,无论目标对象有没有实现接口都可以代理,但是无法处理final的情况。
  • 和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
  • 和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

以上就是Java通俗易懂系列设计模式之代理模式的详细内容,更多关于Java设计模式的资料请关注编程网其它相关文章!

--结束END--

本文标题: Java通俗易懂系列设计模式之代理模式

本文链接: https://lsjlt.com/news/124351.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java通俗易懂系列设计模式之代理模式
    目录前言介绍实现一.静态代理二.Jdk动态代理三.Cglib动态代理总结前言 国内程序员好像普遍对百度都没好感,而且百度近些年产生了不少负面的新闻,像16年的魏则西事件,近期的导演吴...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之模板模式
    目录介绍实现总结实际开发中常常会遇到,代码骨架类似甚至相同,只是具体的实现不一样的场景。例如:流程都有开启、编辑、驳回、结束。每个流程都包含这几个步骤,不同的是不同的流程实例它们的内...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之装饰模式
    目录介绍实现类图总结介绍 装饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,装饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之策略模式
    目录介绍实例类图总结介绍 策略设计模式是行为设计模式之一。当我们为特定任务使用多个算法时,使用策略模式,客户端决定在运行时使用的实际实现。 策略模式的最佳示例之一是Collecti...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之适配器模式
    目录介绍结构类图对象适配器类适配器实例类适配器实现对象适配器实现测试demo类适用场景总结今天看了部特工电影,里面有个桥段,主角在直升机上和反派生死搏斗,而飞机则是无人驾驶的状态,有...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之责任链模式
    目录概述JDK中的责任链模式示例责任链设计模式示例责任链设计模式 - 基类和接口责任链模式 - 链实现责任链设计模式 - 创建链责任链设计模式类图责任链设计模式重点JDK中的责任链模...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之观察者模式
    目录介绍观察者模式Java示例Java观察者模式类图适用场景介绍 观察者模式是行为设计模式之一。当您对对象的状态感兴趣并希望在有任何更改时收到通知时,观察者设计模式非常有用。在观察者...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之建造者模式
    目录介绍意图定义实例使用场景JDK中的Builder设计模式示例总结介绍 今天我们将研究java中的Builder模式。Builder 设计模式是一种创造性的设计模式,如工厂模式和抽...
    99+
    2024-04-02
  • Java设计模式之代理模式
    本文由老王出租房子引出——代理设计模式,将从最简单的静态代理实现开始,后延伸使用jdk实现动态代理,最后扩展到Cglib实现动态代理。为了更深入理解代理模式,...
    99+
    2024-04-02
  • Java设计模式之代理模式详解
    目录一、代理模式二、静态代理三、动态代理一、代理模式 代理模式就是有一个张三,别人都没有办法找到他,只有他的秘书可以找到他。那其他人想和张三交互,只能通过他的秘书来进行转达交互。这个...
    99+
    2024-04-02
  • java设计模式学习之代理模式
    代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式结构图模拟需求:3班小张喜欢1班小红,但是不认识小红,委托1班小明送给小红礼物。创建一个小张和小明都能实现的接口。package ProxyModel;inter...
    99+
    2023-05-31
    java 设计模式 代理模式
  • java设计模式笔记之代理模式
    代理(Proxy)模式:代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。核心作用:通过代理,控制对对象的访问。可以详细控制访问某个(某类)对象的方法,在调用这个方法之前做前置处理,在调用这个方...
    99+
    2023-05-31
    java 设计模式 代理模式
  • Java设计模式--代理模式
    目录1、代码设计的代理模式2、计算机网络中的正向代理和反向代理总结1、代码设计的代理模式 代理模式属于构建型模式(Proxy),提供了对目标对象的一种访问方式; 即通过代理对象访问...
    99+
    2024-04-02
  • javascript设计模式之代理模式
    目录一. 初识代理模式二. 代理模式的实现思想三. 代理模式分类四. 虚拟代理模式的实际运用五. 代理的使用意义及要求六. 总结一. 初识代理模式 代理模式是为一个对象提供一个代用品...
    99+
    2024-04-02
  • 深入理解Java设计模式之代理模式
    目录一、引言二、什么是代理模式三、代理模式的结构四、代理模式和装饰模式的异同五、代理模式和委托六、代理模式的种类七、代理模式的应用场景八、代理模式的优缺点九、代理模式的实现总结一、引...
    99+
    2024-04-02
  • Java设计模式之迭代器模式
    本文介绍设计模式中的迭代器模式,首先通俗的解释迭代器模式的基本概念和对应的四个角色,并根据四个角色举一个典型的实例,为了加强知识的连贯性,我们以Jdk源码集合中使用迭代器模式的应用进...
    99+
    2024-04-02
  • Android设计模式系列之组合模式
    Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用。在android UI设计,几乎所有的widget和布局类都依靠这两个类...
    99+
    2022-06-06
    组合模式 Android
  • Android设计模式系列之单例模式
     单例模式,可以说是GOF的23种设计模式中最简单的一个。 这个模式相对于其他几个模式比较独立,它只负责控制自己的实例化数量单一(而不是考虑为用户产生什么样的实例),...
    99+
    2022-06-06
    单例模式 Android
  • Java设计模式之代理模式详细解读
    目录Java设计模式-代理模式什么是代理模式?代理模式-UML图:源代码:运行结果:总结:应用实例:优点:缺点:使用场景:Java设计模式-代理模式 什么是代理模式? 在代理模式(P...
    99+
    2024-04-02
  • java设计模式之代理模式怎么应用
    代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对实际对象的访问。代理对象充当了实际对象的替代品,可以在调用实际对象的...
    99+
    2023-08-08
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作