在软件开发的世界里,设计模式如同一本精妙的编码诗集,已经成为一种标准的编程实践。在Java编程中,设计模式很重要。是软件开发中广泛应用的一种编程方法,它可以帮助开发人员更快地编写出高效、可靠和可维护的代码。本人将制作一个关于Java设计模式的系列文章,总共23种设计模式将以一篇一篇文章讲解,代码笔记已开源:Gitee点击跳转。在上一篇《Java设计模式(9)享元模式》文章中,我们介绍了享元模式。本文是这个系列的第十篇章,我们将讲解一下代理模式的实现方式、应用场景以及它的用途。
在代理模式中,一个类代表另一个类的功能,这种类型的设计模式属于结构型模式。代理模式通过引入一个代理对象来控制对原对象的访问。代理对象在客户端和目标对象之间充当中介,负责将客户端的请求转发给目标对象,同时可以在转发请求前后进行额外的处理。
代理模式又有两种主要形式:
以下将采用银行与代理银行之间的关系简单实现一下。
/**
* 银行接口
* @author Jensen
* @date 2024-03-28
* */
public interface Bank {
void deposit(BigDecimal amount);
void withdraw(BigDecimal amount);
}
/**
* 实现银行接口
* @author Jensen
* @date 2024-03-28
* */
public class RealBank implements Bank {
private BigDecimal balance = new BigDecimal("0.00");
@Override
public void deposit(BigDecimal amount) {
balance = balance.add(amount);
System.out.println("存款操作完成。当前余额:" + balance + "元");
}
@Override
public void withdraw(BigDecimal amount) {
if (balance.compareTo(amount) >= 0) {
balance = balance.subtract(amount);
System.out.println("取款操作完成。当前余额:" + balance + "元");
} else {
System.out.println("余额不足。当前余额:" + balance + "元");
}
}
}
以上代码我们创建了一个Bank,分别有deposit和withdraw,然后有RealBank实现了Bank并对两个方法做了实际处理。接下来我们需要创建代理对象去代理这个RealBank
/**
* 代理银行
* @author Jensen
* @date 2024-03-28
* */
public class ProxyRealBank implements Bank {
private final RealBank realBank;
public ProxyRealBank() {
this.realBank = new RealBank();
}
@Override
public void deposit(BigDecimal amount) {
realBank.deposit(amount);
}
@Override
public void withdraw(BigDecimal amount) {
realBank.withdraw(amount);
}
}
ProxyRealBank 类也实现了 Bank 接口,但它不直接处理deposit和withdraw,而是将请求转发给一个内部的 RealBank 对象。充当一个中介角色,并且也可以做一些额外的操作。外部只需要调用它就OK了。
/**
* 代理银行(动态代理)
* @author Jensen
* @date 2024-03-28
* */
public class BankInvocationHandler implements InvocationHandler {
private final Object obj;
public BankInvocationHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(obj, args);
}
}
上述代码使用JDK动态代理实现
System.out.println("------------------------------代理模式(静态代理)-----------------------------");
Bank bank = new ProxyRealBank();
// 存款和取款
BigDecimal money1 = new BigDecimal("100.50");
BigDecimal money2 = new BigDecimal("53.20");
BigDecimal money3 = new BigDecimal("47.55");
System.out.println("向银行存款"+money1+"元");
bank.deposit(money1);
System.out.println("向银行取款"+money2+"元");
bank.withdraw(money2);
System.out.println("向银行取款"+money3+"元");
bank.withdraw(money3);
System.out.println("------------------------------代理模式(动态代理)-----------------------------");
RealBank realBank = new RealBank();
BankInvocationHandler handler = new BankInvocationHandler(realBank);
// 使用动态代理创建 Bank 接口的代理对象
Bank bank1 = (Bank) Proxy.newProxyInstance(Bank.class.getClassLoader(),new Class<?>[]{Bank.class},handler);
System.out.println("向银行存款"+money1+"元");
bank1.deposit(money1);
System.out.println("向银行取款"+money2+"元");
bank1.withdraw(money2);
System.out.println("向银行取款"+money3+"元");
bank1.withdraw(money3);
代理模式 主要解决的是在直接访问某些对象时可能遇到的问题,例如对象创建成本高、需要安全控制或远程访问等。