为了账号安全,请及时绑定邮箱和手机立即绑定

结合 if 子句重构大型 switch case

结合 if 子句重构大型 switch case

一只萌萌小番薯 2023-12-13 17:07:11
所以我有这样的事情:switch (data){    case "one" :        if (version1)             createDataOneV1();         else              createDataOnetV2();         break;    case "two":        if(version1)            createDataTwoV1();        else             createDataTwoV2();        break;    default:        createDefaultData();}有很多(开关)案例。有重构的建议吗?
查看完整描述

4 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

不使用Map。它不会为您提供与您相同的编译时安全性switch。


如果您仍然想摆脱它,那么我建议使用enum:


public enum DataCreationStrategy {


    ONE("one", DataCreator::createDataOneV1, DataCreator::createDataOneV2),

    TWO("two", DataCreator::createDataTwoV1, DataCreator::createDataTwoV2)

    // ... other cases

    ;


    private final String key;

    private final Function<DataCreator, String> creator;

    private final Function<DataCreator, String> defaultCreator;


    DataCreationStrategy(String key, Function<DataCreator, String> creator, Function<DataCreator, String> defaultCreator) {

        this.key = key;

        this.creator = creator;

        this.defaultCreator = defaultCreator;

    }


    public static Function<DataCreator, String> of(String key, boolean flag) {

        for (DataCreationStrategy strategy: values()){

            if(strategy.key.equals(key)){

                return flag ? strategy.creator : strategy.defaultCreator;

            }

        }

        return DataCreator::createDefaultData;

    }


}

然后像这样使用它:


String createdData = DataCreationStrategy.of(key, versionFlag).apply(creator);

(可以替换String成你实际需要生成的数据类型)


该of方法也可以以 Stream API 方式实现。但在这种特殊情况下,普通的旧 for 循环要干净得多。


public static Function<DataCreator, String> of(String key, boolean flag) {

   return Arrays.stream(values())

                .filter(s -> s.key.equals(key))

                .findAny()

                .map(s -> flag ? flag ? s.creator : s.defaultCreator )

                .orElse(DataCreator::createDefaultData);

}


查看完整回答
反对 回复 2023-12-13
?
倚天杖

TA贡献1828条经验 获得超3个赞

您可以创建一个Keyfor aHashMap与 some Supplier(例如):


@RequiredArgsConstructor

class SpecialKey  {

     private final String data;

     private final boolean second;

     // 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" somehow

boolean version = ...


boolean res = map.getOrDefault(new SpecialKey(data, version), this::createDefaultData).get();



查看完整回答
反对 回复 2023-12-13
?
HUWWW

TA贡献1874条经验 获得超12个赞

首先决定是否真的需要重构该代码。丑吗?当然。但它简单明了。您可以使用额外的抽象层来清理它,但这通常会导致代码不那么明显,而且性能通常会降低。


无论如何,如果你想重构该代码,你可以使用类型系统。定义一个DataCreator可以为V1和生成数据的接口V2。DataCreator您可以使用如下函数选择正确的:


DataCreator getDataCreatorForData(String data){

    switch(data) {

       case "one": return new DataCreatorOne();

       case "two": return new DataCreatorTwo();

       default: return new DefaultDataCreator()

    }

}

一旦你有了DataCreator,你就可以检查版本:


DataCreator creator = getDataCreatorForData(data);

if (version1){

    creator.createV1Data();

}else{

    creator.createV2Data();

}

这种结构比问题中的结构更扁平,嵌套更少。


查看完整回答
反对 回复 2023-12-13
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

使用字符串作为键和函数作为值创建映射。



查看完整回答
反对 回复 2023-12-13
  • 4 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信