10.1.1 适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern)是一个种结构型模式,基于该模式设计的类能够在两个或者多个不兼容的类之间起到沟通桥梁的作用。
通常我们说的适配器模式是指类适配器或者对象适配器。
image.png


图中,Target接口是Client想调用的标准接口,而Adaptee是提供服务但不符和标准接口的目标类。Adapter便是为了能顺利调用Adaptee类,从而是Client能够与Adaptee适配。

  1. public class Adapter extends Adaptee implements Target {
  2. @Override
  3. public void sayHi() {
  4. super.sayHello();
  5. }
  6. }

对象适配器
对象适配器Adaptee不再继承目标类,而是直接持有一个目标类的对象。如下图
image.png

如下是使用对象适配器的示例。

  1. //对象适配器类
  2. public class Adapter2 implements Target {
  3. //目标类的对象
  4. private Adaptee adaptee;
  5. //初始化适配器时可以指定目标类对象
  6. public Adapter2(Adaptee adaptee) {
  7. this.adaptee = adaptee;
  8. }
  9. @Override
  10. public void sayHi() {
  11. adaptee.sayHello();
  12. }
  13. }

这样,Adapter可以直接将Client要求操作作为委托给目标类对象处理,也实现了Client和Adaptee之间的适配。而且这种适配器更灵活一些。因为要适配的目标对象是作为初始化参数传给Adapter的。


10.1.3 基于反射的动态代理

静态代理中代理对象和被代理对象是在程序中写死的,不够灵活。
java中java.lang.reflect包提供了一个Proxy和InvocationHandler接口,使用它们就可以实现动态代理。
如下代理是基于反射的动态代理
接口代码如下

  1. public interface UserInterface {
  2. String sayHello(String name);
  3. }

被代理类如下

  1. public class User implements UserInterface {
  2. @Override
  3. public String sayHello(String name) {
  4. System.out.println("hello " + name);
  5. return "OK";
  6. }
  7. }
  1. 以下创建一个ProxyHander类继承java.lang.reflect.InvocationHandler接口,并实现其中的invoke方法,invoke方法中需要传入被代理对象、被代理方法及调用代理方法所需的参数。
public class ProxyHandler<T> implements InvocationHandler {
    private T target;

    public ProxyHandler(T target) {
        this.target = target;
    }

    /**
     * @param proxy  被代理的对象
     * @param method 要调用的方法
     * @param args   方法调用时所需要参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("pre words");
        Object ans = method.invoke(target, args);
        System.out.println("post words");
        return ans;
    }
}

使用代理类

public void test() {
    // 创建被代理对象
    User user = new User();
    // 初始化一个ProxyHandler对象
    ProxyHandler proxyHandler = new ProxyHandler(user);

    // 使用Proxy类的一个静态方法生成代理对象userProxy
    UserInterface userProxy =
            (UserInterface) Proxy.newProxyInstance(
                    User.class.getClassLoader(),
                    new Class[]{UserInterface.class},
                    proxyHandler);

    // 通过接口调用相应的方法,实际由Proxy执行
    userProxy.sayHello("动态代理");
}