1. 程式人生 > >策略模式——消除大量if-else,並支援動態增加

策略模式——消除大量if-else,並支援動態增加

今天百度面試,先問了一個專案點

我對於小米、魅族、Android6.0以上機型的適配

需要進行大量判斷

面試官真的很厲害,問我能不能用設計模式改進這個大量的判斷,如果後期想要新增條件,如何來的方便?

if(sdk>6.0) {

action1();

} else if(sdk>4.4) {

if(小米) {

action2();

} else if (魅族) {

action3();

}

}

其實工廠、設計模式這一塊我 好久不看了,當時就想到寫一個抽象 操作類

public abstract class AbstractAdapter {

        abstract void doAdapter();

}

小米適配類

public class XiaoMiAdapter extends AbstractAdapter {

        void doAdapter() {

                do1;

        }

}

以此類推。。。

所以現在是

AbstractAdapter adapter = null;

if(sdk>6.0) {
    adapter = new SixAdapter();
} else if(sdk>4.4) {
    if(小米) {
        adapter = XiaoMiAdapter();
    } else if (魅族) {
        adapter = MeiZuAdapter();
    }
}

if (adapter != null) {
    adapter.doAdapter();
}

現在當你需要新增一個機型,比如 華為,只需要建立HuaWeiAdapter繼承自抽象A dapter就可以了。然後 增加一個條件,再例項化一個華為介面卡即可。呼叫還是下面的統一呼叫方式。

事後回到住處,我又想了想如何優化。

我抽象了一下,只留下了條件

小米適配條件:6.0>sdk>4.4,小米

魅族適配條件:6.0>sdk>4.4,魅族

6.0以上適配條件:sdk>6.0,任意機型

現在有3個條件物件,如果我現在手機的引數,去遍歷這3 個條件物件,那不是就可以了?

所以抽象出一個抽象條件類,AbstractCondition。繼承3個。

abstract class AbstractCondition {
    abstract boolean isMatchCondition(int sdk, MobilePhone mobilePhone);
}

class XiaoMiCondition extends AbstractCondition{
    
    @Override
    boolean isMatchCondition(int sdk, MobilePhone mobilePhone) {
            return mobilePhone == "小米" && (sdk < 6.0 || sdk > 4.4);
        }
    }
}

嘿嘿,把他們都放 集合裡去

List<AbstractCondition> conditionList = new ArrayList<>();
conditionList.add(new XiaoMiCondition());
conditionList.add(new MeiZuCondition());
conditionList.add(new SixCondition());

寫到一半發現不夠,於是新增了一個方法

abstract class AbstractCondition {
    
    abstract boolean isMatchCondition(int sdk, MobilePhone mobilePhone);

    abstract String getMobilePhoneTag();
}

class XiaoMiCondition extends AbstractCondition{

    @Override
    boolean isMatchCondition(int sdk, MobilePhone mobilePhone) {
            return mobilePhone == "小米" && (sdk < 6.0 || sdk > 4.4);
        }

    @Override
    String getMobilePhoneTag() {
        return "小米";
    }
}

遍歷集合,找到符合的條件

private String findMatchedCondition(int sdk, MobilePhone mobilePhone) {
    for (AbstractCondition condition : conditionList) {
        if (condition.isMatchCondition(sdk, mobilePhone)) {
            return condition.getMobilePhoneTag();
        }
    }
    
    return null;
}

再根據tag找到對應的介面卡。

流程大致是這樣的:遍歷條件集合, 找到匹配條件,取得tag。tag相當於是這個條件了。這個條件又會對應一個介面卡。所以我們又會用這個tag去找到對應的介面卡。然後進行適配。以後再也不用修改if-else了,只需要新建 條件類和處理類 就可以了。

也可以簡化一下,把條件類和處理類放在一起。最後給一個完整的優化後的demo吧!

抽象類

public abstract class AbstractAdapter {
    public abstract void adapter(int sdk, String mobilePhoneType);
}

以小米的繼承 為例

public class XiaoMiAdapter extends AbstractAdapter{
    @Override
    public void adapter(int sdk, String mobilePhoneType) {
        if (sdk < 6.0 && sdk > 4.4 && mobilePhoneType.equals("小米")) {
            //執行小米的適配工作
        }
    }
}

適配中心

public class AdapterCenter {
    
    private List<AbstractAdapter> adapterList;
    
    AdapterCenter() {
        adapterList = new ArrayList<>();
        
        adapterList.add(new XiaoMiAdapter());
        adapterList.add(new MeiZuAdapter());
        adapterList.add(new SixAdapter());
    }
    
    public void adapter(int sdk, String mobilePhoneType) {
        for (AbstractAdapter adapter : adapterList) {
            adapter.adapter(sdk, mobilePhoneType);
        }
    }
}

外部呼叫,舒服死了誒

AdapterCenter adapterCenter = new AdapterCenter();
adapterCenter.adapter(5, "小米");

再也 沒有海量if-else了

除此之外。下次想要新增華為適配,誒喲,舒服上天了誒!

新增華為介面卡

public class HuaWeiAdapter extends AbstractAdapter{
    @Override
    public void adapter(int sdk, String mobilePhoneType) {
        if (sdk == 5 && mobilePhoneType.equals("華為")) {
            //進行華為適配
        }
    }
}

在介面卡中心註冊一下

adapterList.add(new HuaWeiAdapter());

以後再也不怕if-else啦。。。。。。。。

我要感謝這個面試官,讓我的程式碼水平上升了,mua~~~

---

今日又想了下,如何匹配到一個,並進行了適配後,不再繼續向下遍歷呢?

果斷想到,這裡的Okhttp型的責任鏈是最好的解決形式