對switch進行拆分重構,降低複雜度,5種方式

如何對switch進行拆分重構

在我們編寫代碼的時候,常常遇到許多if-else或者switch的情況,這種情況下如果分支過多,會導致我們的最大複雜度過大,可能在公司編代碼的時候通過不了檢測,我們可以對這些分支提取成方法單獨存在,也只是能降低平均圈複雜度,最大還是無濟於事,所以這裏我寫了5種方式來降低複雜度:
1、利用多態,也就是方法重寫
2、方法重寫加反射
3、純反射
4、利用枚舉、重寫方法
5、利用方法內部內重寫接口或者抽象方法

這5中方式我個人認爲枚舉更好,也清晰

如果誰有更好的方法,歡迎指正分享

先來看一下普通的switch語句:

public class Test4 {

    public static void main(String[] args) {
        String type = "4";
        switch (type) {
            case "1":
                System.out.println("情況1");
                break;
            case "2":
                System.out.println("情況2");
                break;
            case "3":
                System.out.println("情況3");
                break;
            case "4":
                System.out.println("情況4");
                break;
            case "5":
                System.out.println("情況5");
                break;
            case "6":
                System.out.println("情況6");
                break;
            default:
        }
    }
}

這是一個普通的switch語句塊,這裏我列舉了6個分支,default忽略,假設是幾十個,甚至更多呢?這種情況我們就一直加case嗎?不停地加case會不停地破壞原來的代碼,當複雜度上去了之後,維護起來也麻煩,眼睛都給你看暈。

1、利用多態,也就是方法重寫

利用map和抽象類,或者是接口,對於每種不同的情況重寫具體的方法實現,這樣就降低了方法中的複雜度,我們如果要添加新的分支條件,只需要實現抽象類或者接口的子類,重寫方法內容,在向map中添加進當前的新增子類,就可以實現分支條件的擴展,缺點是子類過多。

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static sun.misc.Version.print;

public class Test4 {
    public static Map<String, Case> caseMap1 = new HashMap<>();

    static {
        caseMap1.put("1", new Case1());
        caseMap1.put("2", new Case2());
        caseMap1.put("3", new Case3());
        caseMap1.put("4", new Case4());
        caseMap1.put("5", new Case5());
        caseMap1.put("6", new Case6());
    }

    public static void main(String[] args) {
        String type = "4";
        caseMap1.get(type).print();
    }

    public static abstract class Case {
        public abstract void print();
    }

    public static class Case1 extends Case {
        @Override
        public void print() {
            System.out.println("情況1");
        }
    }

    public static class Case2 extends Case {
        @Override
        public void print() {
            System.out.println("情況2");
        }
    }

    public static class Case3 extends Case {
        @Override
        public void print() {
            System.out.println("情況3");
        }
    }

    public static class Case4 extends Case {
        @Override
        public void print() {
            System.out.println("情況4");
        }
    }

    public static class Case5 extends Case {
        @Override
        public void print() {
            System.out.println("情況5");
        }
    }

    public static class Case6 extends Case {
        @Override
        public void print() {
            System.out.println("情況6");
        }
    }
}

2、方法重寫加反射

其實這個和第一個本質上沒有什麼區別,區別就是這種方式,是在調用時纔去構造相應的對象

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static sun.misc.Version.print;

public class Test4 {
    public static Map<String, Class<? extends Case>> caseMap = new HashMap<>();
    
    static {
        caseMap.put("1", Case1.class);
        caseMap.put("2", Case2.class);
        caseMap.put("3", Case3.class);
        caseMap.put("4", Case4.class);
        caseMap.put("5", Case5.class);
        caseMap.put("6", Case6.class);
    }

    public static void main(String[] args) {
        String type = "4";
        factory(type).ifPresent(Case::print);
    }

    public static Optional<Case> factory(String type) {
        try {
            return Optional.of(caseMap.get(type).newInstance());
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            //exception
            System.out.println("異常");
            return Optional.empty();
        }
    }

    public static abstract class Case {
        public abstract void print();
    }

    public static class Case1 extends Case {
        @Override
        public void print() {
            System.out.println("情況1");
        }
    }

    public static class Case2 extends Case {
        @Override
        public void print() {
            System.out.println("情況2");
        }
    }

    public static class Case3 extends Case {
        @Override
        public void print() {
            System.out.println("情況3");
        }
    }

    public static class Case4 extends Case {
        @Override
        public void print() {
            System.out.println("情況4");
        }
    }

    public static class Case5 extends Case {
        @Override
        public void print() {
            System.out.println("情況5");
        }
    }

    public static class Case6 extends Case {
        @Override
        public void print() {
            System.out.println("情況6");
        }
    }
}

3、純反射

這種方式和前兩種就有區別了,這種就是利用反射機制直接去執行方法

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static sun.misc.Version.print;

public class Test4 {
    public static Map<String, Method> caseMap2 = new HashMap<>();

    static {
        try {
            caseMap2.put("1", Test4.class.getMethod("case1"));
            caseMap2.put("2", Test4.class.getMethod("case2"));
            caseMap2.put("3", Test4.class.getMethod("case3"));
            caseMap2.put("4", Test4.class.getMethod("case4"));
            caseMap2.put("5", Test4.class.getMethod("case5"));
            caseMap2.put("6", Test4.class.getMethod("case6"));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            System.out.println("異常");
        }
    }

    public static void main(String[] args) {
        String type = "4";
        execute(type);
    }
    
    public static void execute(String type) {
        if (caseMap2.get(type) != null) {
            try {
                caseMap2.get(type).invoke(Test4.class.newInstance());
            } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
                //exception
                e.printStackTrace();
                System.out.println("異常");
            }
        }
    }
    
    public void case1() {
        System.out.println("情況1");
    }

    public void case2() {
        System.out.println("情況2");
    }

    public void case3() {
        System.out.println("情況3");
    }

    public void case4() {
        System.out.println("情況4");
    }

    public void case5() {
        System.out.println("情況5");
    }

    public void case6() {
        System.out.println("情況6");
    }
}

4、利用枚舉、重寫方法

這種方式就是我們在枚舉中定義一個抽象方法,對於每個不同的情況進行重寫方法,大家平常用的最多的可能就是把枚舉當做常量來使用,其實枚舉也是有構造方法,也是存在變量,方法的,其實這完全就是個類嘛,只是它對於不同的情況需要直接先在枚舉內部構造出來而已

package com.company;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static sun.misc.Version.print;

public class Test4 {
    public static Map<String, CaseEnum> caseMap3 = new HashMap<>();

    static {
        caseMap3.put("1", CaseEnum.CASE1);
        caseMap3.put("2", CaseEnum.CASE2);
        caseMap3.put("3", CaseEnum.CASE3);
        caseMap3.put("4", CaseEnum.CASE4);
        caseMap3.put("5", CaseEnum.CASE5);
        caseMap3.put("6", CaseEnum.CASE6);
    }

    public static void main(String[] args) {
        String type = "4";
        caseMap3.get(type).print();
    }

    public enum CaseEnum {
        CASE1() {
            @Override
            public void print() {
                System.out.println("情況1");
            }
        },
        CASE2() {
            @Override
            public void print() {
                System.out.println("情況2");
            }
        },
        CASE3() {
            @Override
            public void print() {
                System.out.println("情況3");
            }
        },
        CASE4() {
            @Override
            public void print() {
                System.out.println("情況4");
            }
        },
        CASE5() {
            @Override
            public void print() {
                System.out.println("情況5");
            }
        },
        CASE6() {
            @Override
            public void print() {
                System.out.println("情況6");
            }
        };

        public abstract void print();
    }
}

5、利用方法內部內重寫接口

這種方式其實和單獨每種情況去實現接口的子類異曲同工,只是這種情況省略了單獨對父類的繼承,而是針對每種不同的情況對對象進行方法重寫,其實也相當於上面枚舉的變種

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static sun.misc.Version.print;

public class Test4 {

    public static Map<String, Case> caseMap4 = new HashMap<>();

    static {
        caseMap4.put("1", new Case() {
            @Override
            public void print() {
                System.out.println("情況1");
            }
        });
        caseMap4.put("2", new Case() {
            @Override
            public void print() {
                System.out.println("情況2");
            }
        });
        caseMap4.put("3", new Case() {
            @Override
            public void print() {
                System.out.println("情況3");
            }
        });
        caseMap4.put("4", new Case() {
            @Override
            public void print() {
                System.out.println("情況4");
            }
        });
        caseMap4.put("5", new Case() {
            @Override
            public void print() {
                System.out.println("情況5");
            }
        });
        caseMap4.put("6", new Case() {
            @Override
            public void print() {
                System.out.println("情況6");
            }
        });

    }
    
    public static abstract class Case {
        public abstract void print();
    }
    
    public static void main(String[] args) {
        String type = "4";
        caseMap4.get(type).print();
    }
}

最終6種情況打印的結果一致:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章