结合 if 子句重构大型 switch case

所以我有这样的事情:


switch (data){

    case "one" :

        if (version1) 

            createDataOneV1();

         else 

             createDataOnetV2();

         break;

    case "two":

        if(version1)

            createDataTwoV1();

        else 

            createDataTwoV2();

        break;

    default:

        createDefaultData();

}

有很多(开关)案例。有重构的建议吗?


一只萌萌小番薯
浏览 76回答 4
4回答

翻阅古今

不使用Map。它不会为您提供与您相同的编译时安全性switch。如果您仍然想摆脱它,那么我建议使用enum:public enum DataCreationStrategy {&nbsp; &nbsp; ONE("one", DataCreator::createDataOneV1, DataCreator::createDataOneV2),&nbsp; &nbsp; TWO("two", DataCreator::createDataTwoV1, DataCreator::createDataTwoV2)&nbsp; &nbsp; // ... other cases&nbsp; &nbsp; ;&nbsp; &nbsp; private final String key;&nbsp; &nbsp; private final Function<DataCreator, String> creator;&nbsp; &nbsp; private final Function<DataCreator, String> defaultCreator;&nbsp; &nbsp; DataCreationStrategy(String key, Function<DataCreator, String> creator, Function<DataCreator, String> defaultCreator) {&nbsp; &nbsp; &nbsp; &nbsp; this.key = key;&nbsp; &nbsp; &nbsp; &nbsp; this.creator = creator;&nbsp; &nbsp; &nbsp; &nbsp; this.defaultCreator = defaultCreator;&nbsp; &nbsp; }&nbsp; &nbsp; public static Function<DataCreator, String> of(String key, boolean flag) {&nbsp; &nbsp; &nbsp; &nbsp; for (DataCreationStrategy strategy: values()){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(strategy.key.equals(key)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return flag ? strategy.creator : strategy.defaultCreator;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return DataCreator::createDefaultData;&nbsp; &nbsp; }}然后像这样使用它:String createdData = DataCreationStrategy.of(key, versionFlag).apply(creator);(可以替换String成你实际需要生成的数据类型)该of方法也可以以 Stream API 方式实现。但在这种特殊情况下,普通的旧 for 循环要干净得多。public static Function<DataCreator, String> of(String key, boolean flag) {&nbsp; &nbsp;return Arrays.stream(values())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(s -> s.key.equals(key))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .findAny()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(s -> flag ? flag ? s.creator : s.defaultCreator )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .orElse(DataCreator::createDefaultData);}

倚天杖

您可以创建一个Keyfor aHashMap与 some Supplier(例如):@RequiredArgsConstructorclass SpecialKey&nbsp; {&nbsp; &nbsp; &nbsp;private final String data;&nbsp; &nbsp; &nbsp;private final boolean second;&nbsp; &nbsp; &nbsp;// hashCode/equals}让我们假设你createDataOneV1并createDataOneV2返回一个boolean:Map<SpecialKey, Supplier<Boolean>> map = new HashMap<>();map.put(new SpecialKey("one", true), this::createDataOneV1);map.put(new SpecialKey("one", false), this::createDataOneV2);然后简单地说:String data = ... // get the "data" somehowboolean version = ...boolean res = map.getOrDefault(new SpecialKey(data, version), this::createDefaultData).get();

HUWWW

首先决定是否真的需要重构该代码。丑吗?当然。但它简单明了。您可以使用额外的抽象层来清理它,但这通常会导致代码不那么明显,而且性能通常会降低。无论如何,如果你想重构该代码,你可以使用类型系统。定义一个DataCreator可以为V1和生成数据的接口V2。DataCreator您可以使用如下函数选择正确的:DataCreator getDataCreatorForData(String data){&nbsp; &nbsp; switch(data) {&nbsp; &nbsp; &nbsp; &nbsp;case "one": return new DataCreatorOne();&nbsp; &nbsp; &nbsp; &nbsp;case "two": return new DataCreatorTwo();&nbsp; &nbsp; &nbsp; &nbsp;default: return new DefaultDataCreator()&nbsp; &nbsp; }}一旦你有了DataCreator,你就可以检查版本:DataCreator creator = getDataCreatorForData(data);if (version1){&nbsp; &nbsp; creator.createV1Data();}else{&nbsp; &nbsp; creator.createV2Data();}这种结构比问题中的结构更扁平,嵌套更少。

慕田峪7331174

使用字符串作为键和函数作为值创建映射。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java