優化 IF ELSE

爲何要優化

太複雜地嵌套if else 會致使難以閱讀,以及擴展性極差,違反了單一職責原則和開閉原則.html

IF ELSE 嵌套過深的問題

適當地抽取方法

好比下邊這個例子java

一個方法不應作太多事情,它應當專一於本身.極端狀況下就像是函數式編程的純函數.git

衛語句 - 漏斗式的代碼

優化前github

double getPayAmount(){
    double result;
    if(_isDead) {
        result = deadAmount();
    }else{
        if(_isSeparated){
            result = separatedAmount();
        }
        else{
            if(_isRetired){
                result = retiredAmount();
            else{
                result = normalPayAmount();
            }
        }
    }
    return result;
 }
複製代碼

優化後編程

double getPayAmount(){
    if(_isDead) 
        return deadAmount();

    if(_isSeparated)
        return separatedAmount();

    if(_isRetired)
        return retiredAmount();

    return normalPayAmount();
}
複製代碼

整個方法就像是漏斗同樣,只有真正知足條件的請求,可以走下去.邏輯清晰了不少app

嘗試JDK8的Optional

舉一個簡單的例子ide

String str = "Hello World!";
if (str != null) {
   System.out.println(str);
} else {
   System.out.println("Null");
}
複製代碼

優化後函數式編程

Optional<String> strOptional = Optional.of("Hello World!");
strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));
複製代碼

這裏的例子比較簡單,你可能看不出Optional的威力.函數

再來個複雜的.優化

public class Test {


    public static void main(String[] args) {

        // creepy initialization step, dont worry
        Employee employee = new Employee();

        // 優化前
        if(employee != null){
            Salary salary = employee.getSalary();
            if(salary !=null){
                Unit unit = salary.getUnit();
                if(unit != null){
                    System.out.println("I discovered the variable finally " + unit);
                }
            }
        }
        // 優化後
        Optional.ofNullable(employee)
                .map(Employee::getSalary)
                .map(Salary::getUnit)
                .map(Unit::getPrecision)
                .ifPresent(e -> System.out.println("I discovered the variable finally " + e));


    }


    static class Employee {

        Salary salary;

        public Salary getSalary() {
            return salary;
        }

        public void setSalary(Salary salary) {
            this.salary = salary;
        }
    }

    class Salary {
        // 單位
        Unit unit;

        public Unit getUnit() {
            return unit;
        }

        public void setUnit(Unit unit) {
            this.unit = unit;
        }
    }

    class Unit {
        // 精度
        Integer precision;

        public Integer getPrecision() {
            return precision;
        }

        public void setPrecision(Integer precision) {
            this.precision = precision;
        }
    }

}
複製代碼

IF ELSE 數量過多的問題

表驅動法(IF 判斷條件單一)

表驅動法是一種編程模式,它的本質是,從表裏查詢信息來代替邏輯語句(if,case)。

舉個簡單的例子

/** * 表驅動法 */
public class TableDrivenApproach {
    //private static Map<?, Function<?,?> > actionsMap =new HashMap<>();
    // private static Map<Integer, Function<Integer, Integer>> actionsMap = new HashMap<>();
    private static HashMap<Integer, Function<Integer, Integer>> actionsMap = new HashMap<>();

    static {
        actionsMap.put(1, e -> e + 1);
        actionsMap.put(2, e -> e + 2);
        actionsMap.put(3, e -> e + 3);
    }

    public static void main(String[] args) {
        System.out.println(actionsMap.get(1).apply(0));
        System.out.println(actionsMap.get(2).apply(0));
        System.out.println(actionsMap.get(3).apply(0));

    }
}
複製代碼

責任鏈

if else 的本質是分支判斷,找到一個符合條件的分支而後執行其內部邏輯.
那麼咱們其實能夠把一個一個分支拆成handler,使用責任鏈模式.

static abstract class Handler {

        /** * 持有後繼的責任對象 */
        protected Handler successor;

        /** * 示意處理請求的方法,雖然這個示意方法是沒有傳入參數的 * 但實際是能夠傳入參數的,根據具體須要來選擇是否傳遞參數 */
        public abstract void handleRequest();

        /** * 取值方法 */
        public Handler getSuccessor() {
            return successor;
        }

        /** * 賦值方法,設置後繼的責任對象 */
        public void setSuccessor(Handler successor) {
            this.successor = successor;
        }

    }

    static class ConcreteHandler extends Handler {
        /** * 處理方法,調用此方法處理請求 */
        @Override
        public void handleRequest() {
            /** * 判斷是否有後繼的責任對象 * 若是有,就轉發請求給後繼的責任對象 * 若是沒有,則處理請求 */
            if (getSuccessor() != null) {
                System.out.println("放過請求");
                getSuccessor().handleRequest();
            } else {
                System.out.println("處理請求");
            }
        }

    }
複製代碼

註解驅動

經過 Java 註解(或其它語言的相似機制)定義執行某個方法/類的條件。
在程序執行時,經過對比入參與註解中定義的條件是否匹配,再決定是否調用此方法。具體實現時,能夠採用表驅動或職責鏈的方式實現。

更復雜: 狀態機 / 規則引擎

能夠給個輕量級的規則引擎的例子. easyrules

參考

cmsblogs.com/?p=2691

blog.csdn.net/qq_35440678…

策略加工廠

blog.csdn.net/u011507568/…

相關文章
相關標籤/搜索