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);
}
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();
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();
}
这种结构比问题中的结构更扁平,嵌套更少。
添加回答
举报