首页 > 解决方案 > 在方法中从父类动态转换为适当的子类

问题描述

我有一个 Java interface PlatformConfigurable。我也有两个班PlatformProducerConfigPlatformConsumerConfig

稍后,我需要向两者添加一个通用配置,将属性设置为空字符串:

    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;
    }

我正在投射到生产者或消费者配置,因为PlatformConfigurable接口没有.toBuilder().build()在其中声明方法,并且我无权修改接口,因为我只能实现它。

我想摆脱重复的代码:

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();

我正在考虑使用 lambdas,但我不是 100% 确定该怎么做。

标签: javagenericslambdajava-8

解决方案


您可以像这样重构现有代码:

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();
}


推荐阅读