代理模式
代理模式的定义是为其他对象提供一种代理以控制对这个对象的访问,代理也就相当于我们日常生活中的中介。代理模式主要可以分为静态代理与动态代理。下面我将以房屋中介为例分别介绍这两种代理。
一、静态代理
静态代理是由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。完整静态代理需包含以下几个角色:
抽象接口:用于定义业务方法
/**
* 买房接口
*/
public interface BuyHouse {
public void buyHouse(Integer price);
}
委托类:用于实现接口所定义的逻辑
/**
* 买房实现
*/
public class BuyHouseImpl implements BuyHouse {
@Override
public void buyHouse(Integer price) {
System.out.println("买房,价格:" + price);
}
}
代理类:代替客户端操作接口
/**
* 代理类
*/
public class ProxyBuy implements BuyHouse {
private BuyHouse buyHouse;
public ProxyBuy(BuyHouse buyHouse){
this.buyHouse = buyHouse;
}
@Override
public void buyHouse(Integer price) {
buyHouse.buyHouse(proxyPrice);
}
}
客户端测试类:
public class ProxyTest {
public static void main(String[] args) {
BuyHouse proxyBuy = new ProxyBuy(new BuyHouseImpl());
proxyBuy.buyHouse(300);
}
}
静态代理总结:
优点:
- 代理类对客户隐藏了接口的具体实现,在一定程度上实现了解耦,安全性提高。
缺点:
- 代理类与委托类实现相同方法,造成代码冗余;
- 代理类只能对固定接口的类进行代理,如果接口新增方法,则需要实现类与代理类同步修改,维护成本较高;
二、动态代理
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
创建动态代理类实现InvocationHandler接口:
/**
* 代理类
*/
public class DynamicProxy implements InvocationHandler {
private BuyHouse buyHouse;
public DynamicProxy(BuyHouse buyHouse){
this.buyHouse = buyHouse;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(buyHouse, args);
return result;
}
}
客户端测试类:
public class ProxyTest {
public static void main(String[] args) {
DynamicProxy dynamicProxy = new DynamicProxy(new BuyHouseImpl());
BuyHouse buyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(),
new Class[]{BuyHouse.class}, dynamicProxy);
buyHouse.buyHouse(300);
}
}
动态代理优点:
动态代理只需传入被代理对象即可获取其代理类对象,使得其更加灵活且更容易扩展。
浙公网安备 33010602011771号