适配器模式

适配器使用场景

当系统依赖的接口提供了需要的功能,但是接口签名并不是完全匹配时,就可以使用适配器模式,将外部接口桥接到内部系统上。

代码实例

依赖接口

public interface RemoteCallBackA {
    void doCallBackA();
}

public interface RemoteCallBackB {
    void doCallBackB();
}

业务逻辑

public class BuzLogic {
    public void doLogic(Object callBack) { //做完自身业务逻辑后回调外部接口
        System.out.println("do business start");
        System.out.println("do business end");
        if (callBack instanceof RemoteCallBackA) {
            ((RemoteCallBackA) callBack).doCallBackA();
        } else if (callBack instanceof RemoteCallBackB) {
            ((RemoteCallBackB) callBack).doCallBackB();
        }
    }
}

自己的业务BuzLogic需要回调2个外部系统的接口,但外部接口签名不通用,只能通过instanceof来进行区分;当增加一个外部系统时,必然会修改BuzLogic的核心功能;违背开闭原则。设计的原则是封装变化的点,这里变化的点是外部系统签名不同,因此可以使用适配器模式封装这一变化。 

使用适配器模式的代码

public interface CallBackAdapter {
    public void callBack(Object target);

    public boolean supports(Object remoteInterface);
}

public class CallBackAdapterA implements CallBackAdapter {
    public void callBack(Object target) {
        RemoteCallBackA remoteCallBackA = (RemoteCallBackA)target;
        remoteCallBackA.doCallBackA();
    }

    @Override
    public boolean supports(Object remoteInterface) {
        return remoteInterface instanceof RemoteCallBackA;
    }
}

public class CallBackAdapterB implements CallBackAdapter {
    @Override
    public void callBack(Object target) {
        RemoteCallBackB remoteCallBackA = (RemoteCallBackB)target;
        remoteCallBackA.doCallBackB();
    }

    @Override
    public boolean supports(Object remoteInterface) {
        return remoteInterface instanceof RemoteCallBackB;
    }
}

public class BuzLogic {
    CallBackAdapter[] callBackAdapterArray = new CallBackAdapter[]{new CallBackAdapterA(),new CallBackAdapterB()};

    public void doLogic(Object callBack) {
        System.out.println("do business start");
        System.out.println("do business end");
        CallBackAdapter adapter = getCallBackAdapter(callBack);
        adapter.callBack(callBack);
    }

    private CallBackAdapter getCallBackAdapter(Object callBack) {
        for (CallBackAdapter adapter : callBackAdapterArray) {
            if (adapter.supports(callBack)) {
                return adapter;
            }
        }
        return null;
    }
}

之后如果要增加外部系统,只需要添加一个Adapter就可以了,无需修改doLogic代码。

适配器模式引发的思考

抛开具体代码,这个模式带给我们的启发是通过继承和循环替代if/else达到代码的整洁。在扩展功能时由于使用了if/else需要修改业务逻辑,导致违背开闭原则,不便于横向扩展 。适配器模式封装这种变化消除if/else,把每个变化分支放到一个子类中去,在上面的例子中supports和callBack组成一个分支;然后通过父类将所有变化点组织起来,并通过for循环的方式去遍历每个分支;当增加新的分支时,添加一个新的子类而无需修改for循环,达到对新增开发对修改封闭。这种编码的思想应该牢记于心,当复杂业务逻辑使用if/else横向扩展时,就应该通过设计模式封装变化。

另外一种类适配器以MouseAdapter为例,它实现了MouseListener, MouseWheelListener, MouseMotionListener这3个接口,并为所有方法生成了一个空实现方便子类使用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章