Java进阶篇设计模式之七 ----- 享元模式和代理模式 (2)

class ExecutePerson implements Shopping {
private String name;
public ExecutePerson(String name) {
this.name = name;
}

@Override public void buyFood() { System.out.println(name + " 买东西"); }

}

class ProxyPerson implements Shopping {
private ExecutePerson ep;
public ProxyPerson(ExecutePerson ep) {
this.ep = ep;
}
@Override
public void buyFood() {
ep.buyFood();
}
}

public class ProxyTest {
public static void main(String[] args) {
String name = "李四";
Shopping shopping = new ProxyPerson(new ExecutePerson(name));
shopping.buyFood();
}
}

输入结果:

李四 买东西

在使用静态代理实现该功能之后,我们发现实现起来很简单,通过一个代理类就可以在不影响目标对象的前提进行扩展使用。但是我们也发现一个问题,如果我们不确定需要代理某个真实类的时候会比较麻烦,而且在类过多的时候,目标对象与代理对象都要维护,会使系统复杂度提升,维护起来也更加麻烦。 不过这时我们就可以使用`动态代理`来进行解决。 ### 动态代理 所谓`动态代理`可以不必强行指定某个真实的角色,只需要在运行时决定就可以了。这里我们可以使用JDK中`java.lang.reflect`来进行开发。 JDK对动态代理提供了以下支持: - java.lang.reflect.Proxy 动态生成代理类和对象 - java.lang.reflect.InvocationHandler - 可以通过invoke方法实现对真实角色的代理访问; - 每次通过Proxy生成代理类对象时都要指定对象的处理器对象. 那么废话不在多说,开始进行代码改造,之前的接口和真实者不需要更改,我们只需要更改代理者就可以了。 更改之后的代码如下:

class ProxyPerson2 implements InvocationHandler {
private Shopping shopping;
private final String methodName = "buyFood";
public ProxyPerson2(Shopping shopping) {
this.shopping = shopping;
}

@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; if (methodName.equals(method.getName())) { result = method.invoke(shopping, args); } return result; }

}

测试代码,注意这里调用和之前不同! 这里通过Proxy类中的newProxyInstance方法会动态生成一个代理类,然后进行调用。其中这三个参数的说明如下: - ClassLoader: 生成一个类, 这个类也需要加载到方法区中, 因此需要指定ClassLoader来加载该类 - Class[] interfaces: 要实现的接口 - InvocationHandler: 调用处理器

public class ProxyTest {
public static void main(String[] args) {
Shopping shopping2 = (Shopping)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Shopping.class}, new ProxyPerson2(new ExecutePerson(name)));
shopping2.buyFood();
}
}
```

代理模式优点:

1、职责清晰。 2、高扩展性。 3、智能化。

代理模式缺点:

1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

注意事项:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydpfd.html