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

相关文章
|
2月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
308 2
|
2月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
340 0
|
4月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
2月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
384 35
|
2月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
296 8
|
7月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
179 0
|
4月前
|
设计模式 安全 Java
Java设计模式(一):单例模式与工厂模式
本文详解单例模式与工厂模式的核心实现及应用,涵盖饿汉式、懒汉式、双重检查锁、工厂方法、抽象工厂等设计模式,并结合数据库连接池与支付系统实战案例,助你掌握设计模式精髓,提升代码专业性与可维护性。
|
4月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
7月前
|
设计模式 Java 数据库连接
【设计模式】【结构型模式】代理模式(Proxy)
一、入门 什么是代理模式? 代理模式(Proxy Pattern)是一种结构型设计模式,允许你提供一个代理对象来控制对另一个对象的访问。 代理对象在客户端和目标对象之间起到中介作用,可以在不改变目标对
198 10
|
9月前
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。