首页 > 其他分享 >代理模式

代理模式

时间:2024-09-17 15:16:36浏览次数:1  
标签:Service 对象 接口 代理 realService 模式 public

代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它通过引入代理对象来控制对某个对象的访问。代理对象和实际对象实现相同的接口,因此可以在不改变实际对象的情况下,对访问进行控制。代理模式主要有以下几种类型:

  1. 虚代理(Virtual Proxy):用于延迟初始化对象的创建。虚代理会在实际对象被真正需要时才创建它,从而节省资源。例如,大型图像或视频文件可以在用户查看之前不进行加载。
  2. 保护代理(Protection Proxy):用于控制对对象的访问权限。保护代理可以在实际对象之前增加访问控制,确保只有授权的用户可以访问对象的功能。例如,某些操作可能只对管理员用户开放。
  3. 远程代理(Remote Proxy):用于表示一个位于不同地址空间的对象。远程代理处理网络通信,将远程对象的请求转发到实际的远程对象。例如,分布式系统中的对象访问。
  4. 缓存代理(Cache Proxy):用于缓存对象的结果,减少对实际对象的访问次数,提高效率。例如,缓存计算结果或数据库查询结果,以便后续请求能更快地响应。

主要组成部分

  1. Subject(主题接口)
    • 定义了代理和实际对象的共同接口。客户端通过这个接口与实际对象进行交互,代理对象和实际对象都实现这个接口。
  2. RealSubject(实际对象)
    • 实际实现了主题接口的类。它是代理模式中真正需要控制访问的对象。
  3. Proxy(代理对象)
    • 实现了主题接口,并持有对实际对象的引用。代理对象通过调用实际对象的方法来实现控制和管理功能。根据不同的类型,代理可以在实际对象访问之前或之后执行附加的操作。

示例

接口 Service

public interface Service {
    void add();
    void del();
}

定义了服务接口,声明了两个方法 adddel

实际服务类 RealService

public class RealService implements Service {
    @Override
    public void add() {
        System.out.println("成功添加");
    }

    @Override
    public void del() {
        System.out.println("成功删除");
    }
}

实现了 Service 接口,提供了实际的业务逻辑。

代理服务类 ProxyService

public class ProxyService implements Service {
    private RealService realService;

    @Override
    public void add() {
        if (realService == null) {
            realService = new RealService();
        }
        realService.add();
        System.out.println("在代理中,记录日志,添加成功");
    }

    @Override
    public void del() {
        if (realService == null) {
            realService = new RealService();
        }
        realService.del();
        System.out.println("在代理中,记录日志,删除成功");
    }
}

优点

  1. 简单直观
    • 实现简单:静态代理的实现较为直接,你可以在编译时创建代理类,代码结构清晰,易于理解和维护。
    • 性能较高:由于代理类在编译时已经创建,调用方法时直接调用实际对象的实现,性能相对较高。
  2. 明确的代理行为
    • 控制逻辑明确:由于代理类的代码是手动编写的,代理的行为和逻辑在代码中明确,便于调试和测试。

缺点

  1. 代码重复
    • 代理类多:每种服务或每种业务逻辑都需要一个代理类,代码量大且重复。如果接口或方法增加,需手动创建新的代理类。
  2. 灵活性差
    • 扩展困难:如果业务逻辑变化或增加新的功能,需要修改每个代理类的代码。扩展和修改较为繁琐。
  3. 维护成本高
    • 修改困难:每当接口或业务逻辑发生变化,都需要重新编译和修改所有相关的代理类,增加了维护成本。

动态代理

public interface Service {
    void add();
    void del();
}
public class RealService implements Service {
    @Override
    public void add() {
        System.out.println("成功添加");
    }

    @Override
    public void del() {
        System.out.println("成功删除");
    }
}		
public class DynamicProxyHandler implements InvocationHandler {
    private Object realService;

    public DynamicProxyHandler(Object realService) {

        this.realService = realService;
    }
    /*
    newProxyInstance,方法有三个参数:
        loader: 用哪个类加载器去加载代理对象
        interfaces:动态代理类需要实现的接口
        h:动态代理方法在执行时,会调用h里面的invoke方法去执行
     */
    public Object getRealService(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), realService.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(realService, args);
        // 让service调用方法,方法返回值
        System.out.println(proxy.getClass().getName() + "代理类执行" +realService.getClass().getName()+"内部"+ method.getName() + "方法,返回" + result +  ",记录日志!");
        return result;
    }
}
package StructuralPattern.ProxyPattern;

import StructuralPattern.ProxyPattern.DynamicProxy.DynamicProxyHandler;
import StructuralPattern.ProxyPattern.DynamicProxy.RealService;
import StructuralPattern.ProxyPattern.DynamicProxy.Service;
//import StructuralModel.ProxyPattern.StaticProxy.ProxyService;

public class TestProxyPattern {
    public static void main(String[] args) {
        //静态代理
//        Service proxyService=new ProxyService();
//        proxyService.add();
//        System.out.println();
//        proxyService.del();

        //动态代理
        Service service = new RealService();
        Service serviceProxy = (Service) new DynamicProxyHandler(service).getRealService();
        serviceProxy.add();
        System.out.println();
        serviceProxy.del();
    }
}

优点

  1. 高灵活性
    • 动态创建:代理类在运行时创建,不需要为每种服务手动编写代理类。可以处理不同的实际对象和方法调用。
    • 通用性:通过 InvocationHandler 可以动态定义代理行为,适用于接口方法增加或变化的情况。
  2. 减少重复代码
    • 代码简洁:只需编写一个通用的 InvocationHandler 实现类,减少了重复的代码和维护工作。
  3. 易于扩展
    • 修改方便:修改代理逻辑只需调整 InvocationHandler 中的代码,不需要改变业务类或创建新的代理类。

缺点

  1. 性能开销
    • 反射开销:动态代理依赖于反射机制,这可能会引入一定的性能开销。在性能要求较高的场景中可能不够高效。
  2. 调试难度
    • 难以跟踪:由于代理类在运行时创建,调试和排错可能更加困难。代理行为是通过反射实现的,可能不如静态代理直观。
  3. 复杂性增加
    • 理解难度:动态代理的实现相对复杂,需要理解反射机制和代理模式的工作原理。对初学者来说,可能有一定的学习曲线。

总结

  • 静态代理适合接口较少、变化不频繁的场景,优点在于实现简单、性能较高,但缺点是代码重复、灵活性差、维护成本高。
  • 动态代理适合接口较多、业务逻辑复杂、需要灵活控制代理行为的场景,优点在于高灵活性、减少重复代码、易于扩展,但缺点是性能开销、调试难度和复杂性增加。

参考

https://blog.csdn.net/m0_51380306/article/details/119912574

代理模式的主要优点是能够控制对实际对象的访问,增加灵活性,同时不需要修改实际对象的代码。

标签:Service,对象,接口,代理,realService,模式,public
From: https://www.cnblogs.com/20lxj666/p/18389076

相关文章

  • 状态模式
    状态模式状态模式(StatePattern)是一种行为设计模式,它允许对象在内部状态发生改变时改变其行为。状态模式使得对象的行为依赖于其内部状态,并且在状态改变时,对象的行为也会随之改变。这个模式的核心思想是将不同的状态封装成不同的类,让状态对象在内部进行切换,而不是将所有的状态逻......
  • 备忘录模式
    备忘录模式备忘录模式(MementoPattern)是一种行为型设计模式,用于保存和恢复对象的内部状态,而不暴露对象的实现细节。这种模式使得对象能够恢复到之前的状态,从而支持撤销和恢复操作。主要角色发起人(Originator):负责创建一个包含自身内部状态的备忘录对象,并可以使用备忘录恢复状......
  • 中介者模式
    中介者模式中介者模式(MediatorPattern)是一种行为型设计模式,用于减少多个对象或类之间复杂的交互依赖。通过引入一个中介者对象,所有对象之间的通信不再直接进行,而是通过中介者来协调和管理,从而降低对象之间的耦合度。这使得系统更易于扩展和维护,因为对象之间的关系可以通过修改中......
  • 迭代器模式
    迭代器模式迭代器模式(IteratorPattern)是一种行为设计模式,旨在提供一种方法顺序访问一个聚合对象(如列表、集合)中的各个元素,而无需暴露其内部表示。这种模式的核心是将遍历行为封装在迭代器对象中,使得客户端代码可以统一地处理不同类型的集合或容器。主要角色迭代器接口(Iterato......
  • 解释器模式
    解释器模式解释器模式(InterpreterPattern)是一种行为设计模式,它定义了一种用于解释和执行语言或表达式的语法表示方法。该模式的主要目的是让语言的语法易于扩展和修改。解释器模式的结构解释器模式通常由以下几个部分组成:抽象表达式(AbstractExpression):定义一个解释操作的接......
  • 观察者模式
    观察者模式观察者模式(ObserverPattern)是一种设计模式,用于建立对象之间的一对多依赖关系。这种模式使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式通常用于实现事件处理系统或消息通知系统。在观察者模式中,有两个主要角色:被观察者(Subject......
  • 访问者模式
    访问者模式“访问者模式”通常是指软件开发中的一种设计模式,也叫做“Visitor模式”。它属于行为型设计模式之一,主要用于将数据结构和操作解耦。通过使用访问者模式,可以在不修改数据结构的前提下,定义新的操作。访问者模式的基本思想是:你有一个包含不同对象的对象结构(例如一个元素......
  • 模板方法模式
    模板方法模式模板方法模式(TemplateMethodPattern)是一种行为设计模式,它定义了一个算法的骨架,并允许子类在不改变算法结构的情况下重写算法的某些步骤。通过这种模式,能够复用算法的整体流程,同时又能够灵活调整某些具体步骤的实现。模板方法模式的关键要素抽象类(AbstractClass......
  • 策略模式
    策略模式策略模式(StrategyPattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互换。这种模式允许算法在不影响客户端的情况下变化,从而提高了代码的灵活性和可维护性。策略模式的组成策略模式由以下几个部分组成:抽象策略(Strategy):这是一个接口或抽象......
  • 命令模式
    命令模式命令模式(CommandPattern)是行为型设计模式之一,它将请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,以及对请求排队或记录请求日志等操作。通过使用命令模式,命令的发出者与命令的执行者可以完全解耦。命令模式的结构Command(命令接口/抽象类):定义了执行命令......