案例分析:设计模式与代码的结构特性

什么是适配器模式

  将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

模式中的角色

  目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。 需要适配的类(Adaptee):需要进行适配的类。 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。

模式带来的好处

  1. 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。

  2. 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。

  3. 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

以spring-aop-4.3.18.RELEASE.jar中的org.springframework.aop.framework.adapter包为例:

public interface AdvisorAdapter {
    boolean supportsAdvice(Advice var1);

    MethodInterceptor getInterceptor(Advisor var1);
}

Spring的AOP利用advice来增强pointCut的功能,下图中标识了三种advice:

 

案例分析:设计模式与代码的结构特性_第1张图片

每种advice有其对应的adapter和interceptor:

//AfterReturningAdviceAdapter
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
    AfterReturningAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof AfterReturningAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        AfterReturningAdvice advice = (AfterReturningAdvice)advisor.getAdvice();
        return new AfterReturningAdviceInterceptor(advice);
    }
}

//MethodBeforeAdviceAdapter
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
    MethodBeforeAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof MethodBeforeAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
}


//ThrowsAdviceAdapter
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
    ThrowsAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof ThrowsAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        return new ThrowsAdviceInterceptor(advisor.getAdvice());
    }
}

  案例分析:设计模式与代码的结构特性_第2张图片

 

 案例分析:设计模式与代码的结构特性_第3张图片

 

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List interceptors = new ArrayList(3);
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor)advice);
        }

        Iterator var4 = this.adapters.iterator();

    //可以看到在这个方法中,利用多态机制对advice进行判断
    //如果是支持的advice,则生成对应的interceptor
 
        while(var4.hasNext()) {
            AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }

        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        } else {
            return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
        }
    }

  案例分析:设计模式与代码的结构特性_第4张图片

耦合度

由于引入了适配器,目标类和适配者之间的耦合度降低。如果适配者发生变化,修改适配器,目标类并不会收到影响。

应用范例

由于上面的例子是Spring的aop包中的,所以参考这个结构写了一个类似的适配器模式。

https://github.com/wubaii/AdapterPattern

你可能感兴趣的:(案例分析:设计模式与代码的结构特性)