Java设计模式-代理模式(7)

简介: Java设计模式-代理模式(7)

大家好,我是馆长!今天开始我们就要进入结构型模式的讲解和整理了。在开始具体的讲解之前,我们再次介绍下结构型模式含义和涉及到的相关模式。

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。其中包含:代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式。今天我们就讲一下今天的主角:代理模式。

代理模式(Proxy Pattern)

定义

代理模式是一种结构型模式,是为某对象提供一种代理以控制对该对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。最经典的示例就是 Spring AOP的应用。可分为:静态代理和动态代理。

解决问题

在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

实现

代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问。

结构

主要角色如下:

1.抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。

2.真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。

3.代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

4.客户端(Client):使用抽象主题接口来操作真实主题或代理主题,不需要知道具体是哪一个实现类。

注意:

1、真实主题和代理类都是实现抽象主题(Subject)类。也就是说真实 主题类和代理类拥有共同的基类或者接口(抽象主题(Subject)类)。

2、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口(共同接口)。

3、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

代码实现:静态代理

//抽象主题类 Subject
public interface Subject {
void Request();
}
//真主题类:HuaWeiSubject
public class HuaWeiSubject implements Subject{
@Override
public void Request() {
System.out.println("HuaWeiSubject 真实主题 Request");
}
}
​​​​​

//代理主题类 ProxySubject
public class ProxySubject implements Subject {
private HuaWeiSubject realSubject;

private void preRequest() {
    System.out.println("代理主题的前置处理:preRequest");
}

private void afterRequest() {
    System.out.println("代理主题的后置处理:afterRequest");
}

@Override
public void Request() {
    if (realSubject == null) {
        realSubject = new HuaWeiSubject();
    }
    preRequest();
    realSubject.Request();
    afterRequest();
}

}

//模拟客户类:Client
public class ClientDemo {
public static void main(String[] args) {
ProxySubject proxySubject = new ProxySubject();
proxySubject.Request();
}

}

代码实现:动态代理

jdk动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

动态代理步骤:

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法。

2.创建被代理的类以及接口

3.通过Proxy的静态方法newProxyInstance创建一个代理

4.通过代理调用方法

//抽象主题类 Subject
public interface Subject {
void Request();
}
//真实主题类:HuaWeiSubject
@Data
public class HuaWeiSubject implements Subject {
@Override
public void Request() {
System.out.println("HuaWeiSubject 真实主题 Request");
}
}
//动态代理类
@Data
public class DynamicProxy implements InvocationHandler {
private Subject subject;

DynamicProxy(Subject subject) {
    this.subject = subject;
}

/**
 * invoke()方法同样有三个参数:
 * 1.Object proxy 动态代理类的引用,通常情况下不需要它。但可以使用getClass()方法,得到proxy的Class类从而取得实例的类信息,如方法列表,annotation等。
 * 2.Method method 方法对象的引用,代表被动态代理类调用的方法。从中可得到方法名,参数类型,返回类型等等
 * 3.Object[] 对象数组,代表被调用方法的参数。注意基本类型(int,long)会被装箱成对象类型(Interger, Long)
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("--before Request...");
    method.invoke(subject, args);
    System.out.println("--before Reqeust...");
    return null;
}

}

//模拟客户类
public class ClientDemo {
public static void main(String[] args) {
DynamicProxy handler = new DynamicProxy(new HuaWeiSubject());
/**

     * Proxy.newProxyInstance()方法有三个参数:
     * 1.ClassLoader loader:类加载器(Class Loader)
     * 2.Class<?>[] interfaces:需要实现的接口数组
     * 3.InvocationHandler h:InvocationHandler接口。所有动态代理类的方法调用,都会交由InvocationHandler接口实现类里的invoke()方法去处理。这是动态代理的关键所在
     */
    Subject huaWeiSubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
            new Class[]{Subject.class},
            handler);

    huaWeiSubject.Request();
}

}

其他实现方式:

Cglib动态代理:它是基于继承被代理类的方式实现的,不强制要求实现任何接口。Cglib动态代理利用了ASM框架,这是一种Java字节码操控框架,允许在不重新编译原始类的情况下动态生成新的类。Cglib动态代理的工作原理是在运行期生成一个新的子类,这个子类覆盖了原始类的方法,并在方法调用前和后添加额外的逻辑。这种代理方式适合于那些没有实现接口但希望对其所有方法进行增强的情况。具体的实现方式和代码建设请各位看官自行查阅。

扩展

当一个复杂对象的多份副本须存在时,代理模式可以结合享元模式以减少存储器用量。典型做法是创建一个复杂对象及多个代理者,每个代理者会引用到原本的复杂对象。而作用在代理者的运算会转送到原本对象。一旦所有的代理者都不存在时,复杂对象会被移除。

好了,关于代理模式的说明,馆长就先讲到这里。谢谢各位看官!!

23 种设计模式不是孤立存在的,很多模式之间存在一定的关联关系,在大的系统开发中常常同时使用多种设计模式,或者模式与模式之间的组合进行生成更加强大的程序功能。

相关文章
|
1月前
|
设计模式 算法 Java
Java中的设计模式:提升代码质量的秘诀
【8月更文挑战第23天】在Java开发中,设计模式是提高代码可读性、可维护性和扩展性的强有力工具。本文通过浅显易懂的语言和实际案例,探讨几种常见的设计模式及其在Java中的应用,旨在帮助开发者更好地理解并运用这些模式来优化自己的代码结构。
46 2
|
13天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
155 37
|
9天前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
13天前
|
设计模式 安全 算法
【Java面试题汇总】设计模式篇(2023版)
谈谈你对设计模式的理解、七大原则、单例模式、工厂模式、代理模式、模板模式、观察者模式、JDK中用到的设计模式、Spring中用到的设计模式
【Java面试题汇总】设计模式篇(2023版)
|
13天前
|
设计模式 缓存 安全
设计模式——代理模式
静态代理、JDK动态代理、Cglib 代理
设计模式——代理模式
|
13天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
4天前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
22 11
|
28天前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
39 2
|
28天前
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
31 1
|
28天前
|
设计模式 Java
重构你的代码:探索Java中的混合、装饰器与组合设计模式
【8月更文挑战第30天】在软件开发中,设计模式为特定问题提供了结构化的解决方案,使代码更易理解、维护及扩展。本文将介绍三种常用的 Java 设计模式:混合模式、装饰器模式与组合模式,并附有示例代码展示实际应用。混合模式允许通过继承多个接口或抽象类实现多重继承;装饰器模式可在不改变对象结构的情况下动态添加新功能;组合模式则通过树形结构表示部分-整体层次,确保客户端处理单个对象与组合对象时具有一致性。
18 1