亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

結合 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 關注
  • 197 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號