代理模式是一种设计模式,用于在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。代理模式可以应用于各种不同的场景,如网络请求、图片加载、数据库操作等。代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。
本文目录导读:
在软件设计模式中,代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问,代理模式可以在不修改原始类的情况下,为原始类添加新的功能,同时还可以隐藏原始类的实现细节,本文将详细介绍代理模式的概念、特点、应用场景以及优缺点,并通过实例演示如何使用代理模式。
代理模式概念
代理模式是一种结构型设计模式,它通过创建一个代理对象来控制对实际对象的访问,代理对象可以在调用实际对象的方法之前或之后执行一些操作,从而实现对实际对象的控制,代理模式主要有两种类型:静态代理和动态代理。
1、静态代理:在编译时期就确定了代理类和被代理类的关系,代理类需要实现与被代理类相同的接口,静态代理的优点是性能较好,因为不需要在运行时生成代理类;缺点是灵活性较差,因为代理类与被代理类之间的关系是在编译时期确定的,无法在运行时动态调整。
2、动态代理:在运行时期根据需要生成代理类,可以使用Java的反射机制或者AOP(面向切面编程)技术来实现,动态代理的优点是灵活性较好,可以根据运行时的需求动态生成代理类;缺点是性能较差,因为需要在运行时生成代理类。
代理模式特点
1、封装:代理模式将被代理类的内部实现细节隐藏起来,只暴露给外部接口,这样可以降低系统的耦合度,提高系统的可维护性和可扩展性。
2、继承:代理模式可以通过继承的方式实现,子类继承父类的同时,也继承了父类的接口,这样可以保证代理类与被代理类具有相同的接口,便于调用。
3、多态:代理模式实现了接口的多态性,当客户端通过接口调用方法时,实际上调用的是代理类的方法,这样可以实现对被代理类的统一处理,简化客户端的使用。
应用场景
1、AOP(面向切面编程):在不修改原有代码的情况下,为系统添加新的功能,如日志记录、权限控制等。
2、远程调用:通过网络通信实现分布式系统中的对象间通信,降低系统的耦合度。
3、缓存:使用代理模式实现对目标对象的缓存,提高系统的性能。
4、限流:通过代理模式限制系统资源的访问频率,防止系统过载。
优缺点
优点:
1、降低了系统的耦合度,提高了系统的可维护性和可扩展性。
2、通过代理对象可以实现对目标对象的统一处理,简化客户端的使用。
3、可以隐藏目标对象的实现细节,保护其商业机密。
缺点:
1、性能较差,因为需要在运行时生成代理类。
2、灵活性较差,因为代理类与被代理类之间的关系是在编译时期确定的,无法在运行时动态调整。
实例演示
下面通过一个简单的银行转账示例来演示如何使用代理模式实现对目标对象的控制,假设我们有一个BankAccount类,用于表示银行账户,包含存款和取款两个方法,我们希望在不修改BankAccount类的前提下,为其添加一个功能:记录每次交易的时间,我们可以使用代理模式来实现这个功能。
// 定义一个接口,用于定义银行账户的操作方法 interface Account { void deposit(double amount); void withdraw(double amount); } // 实现Account接口的具体类,即BankAccount类 class BankAccount implements Account { private double balance; @Override public void deposit(double amount) { balance += amount; } @Override public void withdraw(double amount) { if (balance >= amount) { balance -= amount; } else { System.out.println("余额不足"); } } } // 实现一个Logger接口,用于记录交易时间的功能 interface Logger { void logTransaction(String operation, double amount); } // 实现Logger接口的具体类,即LoggingAccount类,作为BankAccount的代理对象 class LoggingAccount implements Account, Logger { private BankAccount target; private double lastWithdrawAmount; // 最后一笔取款金额 private long lastLogTime; // 最后一条日志的时间戳 LoggingAccount(BankAccount target) { this.target = target; } @Override public void deposit(double amount) { target.deposit(amount); // 先将钱存入目标账户再进行操作日志记录的操作(懒加载)<------懒加载使得每次只有真正要操作的时候才去获取target对象(减少不必要的计算),并且只有在target对象真正发生变化后才更新lastLogTime(减少不必要的日志记录)------->懒加载使得每次只有真正要操作的时候才去获取target对象(减少不必要的计算),并且只有在target对象真正发生变化后才更新lastLogTime(减少不必要的日志记录)<-------------懒加载使得每次只有真正要操作的时候才去获取target对象(减少不必要的计算),并且只有在target对象真正发生变化后才更新lastLogTime(减少不必要的日志记录)<------------------------------------懒加载使得每次只有真正要操作的时候才去获取target对象(减少不必要的计算),并且只有在target对象真正发生变化后才更新lastLogTime(减少不必要的日志记录)<----------------------------------------------------------------------------------懒加载使得每次只有真正要操作的时候才去获取target对象(减少不必要的计算),并且只有在target对象真正发生变化后才更新lastLogTime(减少不必要的日志记录)<-------------------------------------------------------懒加载使得每次只有真正要操作的时候才去获取target对象(减少不必要的计算),并且只有在target对象真正发生变化后才更新lastLogTime(减少不必要的日志记录)<--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->最后取出上一次取款金额进行比较 <--------------最后取出上一次取款金额进行比较 ------------------------------最后取出上一次取款金额进行比较 <--------------最后取出上一次取款金额进行比较 <---------------------------------最后取出上一次取款金额进行比较 <----------------最后取出上一次取款金额进行比较 --------------------------------------最后取出上一次取款金额进行比较 <--------------------------------最后取出上一次取款金额进行比较 <-------------------------------------------------------最后取出上一次取款金额进行比较 <-----------------------------最后取出上一次取款金额进行比较 ------------------------------最后取出上一次取款金额进行比较 <-----------------------------最后取出上一次取款金额进行比较 <----------------最后取出上一次取款金额进行比较 <-----------------------------最后取出上一次取款金额进行比较 ------------------------------最后取出上一次取款金额进行比较 <--------------------------------最后取出上一次取款金额进行比较 <----------------最后取出上