Java 从方法中的父类动态转换为适当的子类
我有一个Java接口平台。我还有两个类PlatformProducerConfig和PlatformConsumerConfig 稍后,我需要为这两个文件添加一个公共配置,将属性设置为空字符串:Java 从方法中的父类动态转换为适当的子类,java,generics,lambda,java-8,Java,Generics,Lambda,Java 8,我有一个Java接口平台。我还有两个类PlatformProducerConfig和PlatformConsumerConfig 稍后,我需要为这两个文件添加一个公共配置,将属性设置为空字符串: private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) { if (platformConfig instanceof Platform
private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
if (platformConfig instanceof PlatformProducerConfig) {
PlatformProducerConfig oldConfig = (PlatformProducerConfig) platformConfig;
Map<String, String> additionalConfig = oldConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return oldConfig.toBuilder().additionalProperties(newConfig).build();
}
else if (platformConfig instanceof PlatformConsumerConfig) {
PlatformConsumerConfig oldConfig = (PlatformConsumerConfig) platformConfig;
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return oldConfig.toBuilder().additionalProperties(newConfig).build();
}
return platformConfig;
}
我曾考虑过使用lambdas,但我不能100%确定如何使用它。您可以像这样重构现有代码:
private PlatfromConfigurable disableHostNameVerificationConfig(Platfromonfigurable platfromConfig) {
if (!(platformConfig instanceof PlatformProducerConfig) && !(platformConfig instanceof PlatformConsumerConfig)) {
return platformConfig;
}
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
if (platformConfig instanceof PlatformProducerConfig) {
return ((PlatformProducerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
}
return ((PlatformConsumerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
}
更新
另一种方法是提取与构建器相关的功能以分离接口,并以这种方式使用它们:
// 1. extend existing `PlatformConfigurable`
public interface BuilderedPlatformConfigurable extends PlatformConfigurable {
ConfigPlatformBuilder toBuilder();
}
// 2. provide builder interface with common implementation
public interface ConfigPlatformBuilder {
Map<String, String> additionalProperties = new HashMap<>();
BuilderedPlatformConfigurable build();
default ConfigPlatformBuilder additionalProperties(Map<String, String> properties) {
this.additionalProperties.clear();
this.additionalProperties.putAll(properties);
return this;
}
}
// 3. update PlatformConsumerConfig class (similarly, PlatformProducerConfig)
public class PlatformConsumerConfig implements BuilderedPlatformConfigurable {
private Map<String, String> additionalProperties = new HashMap<>();
@Override
public Map<String, String> additionalProperties() {
return additionalProperties;
}
public ConfigPlatformBuilder toBuilder() {
return new Builder();
}
public static class Builder implements ConfigPlatformBuilder {
public PlatformConsumerConfig build() {
PlatformConsumerConfig config = new PlatformConsumerConfig();
config.additionalPropertie.putAll(this.additionalProperties);
return config;
}
}
}
// 4. provide overloaded method
private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
return platformConfig;
}
private PlatformConfigurable disableHostNameVerificationConfig(BuilderedPlatformConfigurable platformConfig) {
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(Map::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return platformConfig.toBuilder().additionalProperties(newConfig).build();
}
您可以像这样重构现有代码:
private PlatfromConfigurable disableHostNameVerificationConfig(Platfromonfigurable platfromConfig) {
if (!(platformConfig instanceof PlatformProducerConfig) && !(platformConfig instanceof PlatformConsumerConfig)) {
return platformConfig;
}
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
if (platformConfig instanceof PlatformProducerConfig) {
return ((PlatformProducerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
}
return ((PlatformConsumerConfig)platformConfig).toBuilder().additionalProperties(newConfig).build();
}
更新
另一种方法是提取与构建器相关的功能以分离接口,并以这种方式使用它们:
// 1. extend existing `PlatformConfigurable`
public interface BuilderedPlatformConfigurable extends PlatformConfigurable {
ConfigPlatformBuilder toBuilder();
}
// 2. provide builder interface with common implementation
public interface ConfigPlatformBuilder {
Map<String, String> additionalProperties = new HashMap<>();
BuilderedPlatformConfigurable build();
default ConfigPlatformBuilder additionalProperties(Map<String, String> properties) {
this.additionalProperties.clear();
this.additionalProperties.putAll(properties);
return this;
}
}
// 3. update PlatformConsumerConfig class (similarly, PlatformProducerConfig)
public class PlatformConsumerConfig implements BuilderedPlatformConfigurable {
private Map<String, String> additionalProperties = new HashMap<>();
@Override
public Map<String, String> additionalProperties() {
return additionalProperties;
}
public ConfigPlatformBuilder toBuilder() {
return new Builder();
}
public static class Builder implements ConfigPlatformBuilder {
public PlatformConsumerConfig build() {
PlatformConsumerConfig config = new PlatformConsumerConfig();
config.additionalPropertie.putAll(this.additionalProperties);
return config;
}
}
}
// 4. provide overloaded method
private PlatformConfigurable disableHostNameVerificationConfig(PlatformConfigurable platformConfig) {
return platformConfig;
}
private PlatformConfigurable disableHostNameVerificationConfig(BuilderedPlatformConfigurable platformConfig) {
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(Map::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return platformConfig.toBuilder().additionalProperties(newConfig).build();
}
再进一步,使用泛型:
private <P extends PlatformConfigurable> P disableHostNameVerificationConfig(P platformConfig, BiFunction<P, Map<String, String>, P> appender) {
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return appender.apply(platformConfig, newConfig);
}
如果愿意,请创建帮助器方法以隐藏双功能:
实际上,我认为更好的方法是不使用泛型或lambda:编写一个创建更新映射的方法:
private static Map<String, String> newConfig(PlatformConfigurable platformConfig) {
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = additionalConfig != null ? new HashMap<>(additionalConfig) : new HashMap<>();
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return newConfig;
}
再进一步,使用泛型:
private <P extends PlatformConfigurable> P disableHostNameVerificationConfig(P platformConfig, BiFunction<P, Map<String, String>, P> appender) {
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = new HashMap<>(Optional.ofNullable(additionalConfig).orElseGet(ImmutableMap::of));
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return appender.apply(platformConfig, newConfig);
}
如果愿意,请创建帮助器方法以隐藏双功能:
实际上,我认为更好的方法是不使用泛型或lambda:编写一个创建更新映射的方法:
private static Map<String, String> newConfig(PlatformConfigurable platformConfig) {
Map<String, String> additionalConfig = platformConfig.additionalProperties();
Map<String, String> newConfig = additionalConfig != null ? new HashMap<>(additionalConfig) : new HashMap<>();
newConfig.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
return newConfig;
}
在Alex Rudenko的回答中添加了一件事,并使用不同的函数添加不同的接口实现 私有平台可配置禁用主机名验证配置平台可配置平台配置{ 如果platformConfig==null{ 返回平台配置; } Map additionalConfig=platformConfig.additionalProperties; Map newConfig=new HashMapOptional.OfNullableAddationConfig.orElseGetImmutableMap::of; newConfig.putSslConfigs.SSL_端点_标识_算法_配置; 返回PlatformConfigurableObjectplatformConfig,newConfig; } 因此,您可以在不同的方法中处理所有实例,并且无论以后何时添加PlatfromXCofing类,您只需更改此方法。单一责任原则 私有平台可配置平台可配置平台可配置对象平台可配置平台配置,映射新配置{ 如果platformConfig实例为PlatformProducerConfig{ 返回PlatformProducerConfigplatformConfig.toBuilder.additionalPropertiesnewConfig.build; }否则如果PlatformConsumerConfig的platformConfig实例{ 返回PlatformConsumerConfigplatformConfig.toBuilder.additionalPropertiesnewConfig.build; }否则{ 返回平台配置; } }
在Alex Rudenko的回答中添加了一件事,并使用不同的函数添加不同的接口实现 私有平台可配置禁用主机名验证配置平台可配置平台配置{ 如果platformConfig==null{ 返回平台配置; } Map additionalConfig=platformConfig.additionalProperties; Map newConfig=new HashMapOptional.OfNullableAddationConfig.orElseGetImmutableMap::of; newConfig.putSslConfigs.SSL_端点_标识_算法_配置; 返回PlatformConfigurableObjectplatformConfig,newConfig; } 因此,您可以在不同的方法中处理所有实例,并且无论以后何时添加PlatfromXCofing类,您只需更改此方法。单一责任原则 私有平台可配置平台可配置平台可配置对象平台可配置平台配置,映射新配置{ 如果platformConfig实例为PlatformProducerConfig{ 返回PlatformProducerConfigplatformConfig.toBuilder.additionalPropertiesnewConfig.build; }否则如果PlatformConsumerConfig的platformConfig实例{ 返回PlatformConsumerConfigplatformConfig.toBuilder.additionalPropertiesnewConfig.build; }否则{ 返回平台配置; } }
如果以后添加额外的PlatfromXCofing类呢?如果他们的数量变得相当大怎么办?有没有办法使方法更通用?这是一个很好的重构,但是@Andy Turner给出了一个更一般的答案。非常感谢。我提供了分离构建实现的更新版本:如果以后添加额外的PlatfromXCofing类会怎么样?如果他们的数量变得相当大怎么办?有没有办法使方法更通用?这是一个很好的重构,但是@Andy Turner给出了一个更一般的答案。非常感谢。我提供了分离构建实现的更新版本:这导致:无法解析'P'@QuirkyBit中的方法'toBuilder'。如果您显示问题中类的相关声明,这将有所帮助。PlatformConfigurable上不存在toBuilder方法这一点并不明显。这是在问题描述中:我正在转换到producer或consumer配置,因为PlatfromConfigurable接口没有.toBuilder或.build方法,我没有修改接口的权限,因为我只能实现它。是的,就是这样!非常感谢你!这导致:无法在'P'@QuirkyBit中解析方法'toBuilder'。如果您显示
你问题中的课程。PlatformConfigurable上不存在toBuilder方法这一点并不明显。这是在问题描述中:我正在转换到producer或consumer配置,因为PlatfromConfigurable接口没有.toBuilder或.build方法,我没有修改接口的权限,因为我只能实现它。是的,就是这样!非常感谢你!这是一个很好的重构,但是@Andy Turner给出了一个更一般的答案。非常感谢。这是一个很好的重构,但是@Andy Turner给出了一个更一般的答案。非常感谢。