java - 使用 Java 8 重构多态性

标签 java spring java-8

我有一个旧代码库,需要使用 Java 8 重构,所以我有一个接口(interface),它告诉我当前站点是否支持该平台。

public interface PlatformSupportHandler {   
  public abstract boolean isPaltformSupported(String platform);
}

我有多个实现它的类,每个类都支持不同的平台。

一些实现类是:

@Component("bsafePlatformSupportHandler")
public class BsafePlatoformSupportHandler implements PlatformSupportHandler {

  String[] supportedPlatform = {"iPad", "Android", "iPhone"};
  Set<String> supportedPlatformSet = new HashSet<>(Arrays.asList(supportedPlatform)); 

  @Override
  public boolean isPaltformSupported(String platform) {

    return supportedPlatformSet.contains(platform);
  }

}

另一个实现:

@Component("discountPlatformSupportHandler")
public class DiscountPlatoformSupportHandler implements PlatformSupportHandler{

  String[] supportedPlatform = {"Android", "iPhone"};
  Set<String> supportedPlatformSet = new HashSet<>(Arrays.asList(supportedPlatform)); 

  @Override
  public boolean isPaltformSupported(String platform) {

  return supportedPlatformSet.contains(platform);
  }
}

在我的过滤器运行时,我得到了我想要的所需 bean:

platformSupportHandler = (PlatformSupportHandler) ApplicationContextUtil
  .getBean(subProductType + Constants.PLATFORM_SUPPORT_HANDLER_APPEND);

并调用isPlatformSupported获取我当前的站点是否支持以下平台。

我是 Java 8 的新手,有什么方法可以在不创建多个类的情况下重构此代码?由于接口(interface)只包含一种方法,我可以以某种方式使用 lambda 来重构它吗?

最佳答案

如果你想坚持当前的设计,你可以这样做:

public class MyGeneralPurposeSupportHandler implements PlatformSupportHandler {
   private final Set<String> supportedPlatforms;
   public MyGeneralPurposeSupportHandler(Set<String> supportedPlatforms) {
      this.supportedPlatforms = supportedPlatforms;
   } 

   public boolean isPlatformSupported(String platform) {
     return supportedPlatforms.contains(platform);
   }
}

// now in configuration:

@Configuration
class MySpringConfig {

    @Bean
    @Qualifier("discountPlatformSupportHandler") 
    public PlatformSupportHandler discountPlatformSupportHandler() {
       return new MyGeneralPurposeSupportHandler(new HashSefOf({"Android", "iPhone"})); // yeah its not a java syntax, but you get the idea
    }

    @Bean
    @Qualifier("bsafePlatformSupportHandler") 
    public PlatformSupportHandler bsafePlatformSupportHandler() {
       return new MyGeneralPurposeSupportHandler(new HashSefOf({"Android", "iPhone", "iPad"}));
    }   

}


此方法的优点是不为每种类型(折扣、bsafe 等)创建类,因此这回答了问题。

更进一步,如果没有请求类型会发生什么,目前它将失败,因为 bean 不存在于应用程序上下文中 - 这不是一个非常好的方法。

因此,您可以创建一个类型映射到一组受支持的平台,在配置中维护映射或让 spring 发挥它的魔力。
你最终会得到这样的东西:
public class SupportHandler {

   private final Map<String, Set<String>> platformTypeToSuportedPlatforms;

   public SupportHandler(Map<String, Set<String>> map) {
       this.platformTypeToSupportedPlatforms = map; 
   }

   public boolean isPaltformSupported(String type) {
        Set<String> supportedPlatforms = platformTypeToSupportedPlatforms.get(type);
        if(supportedPlatforms == null) {
          return false; // or maybe throw an exception, the point is that you don't deal with spring here which is good since spring shouldn't interfere with your business code
        }
        return supportedPlatforms.contains(type);

   }
}

@Configuration 
public class MyConfiguration {

    // Configuration conf is supposed to be your own way to read configurations in the project - so you'll have to implement it somehow
    @Bean
    public SupportHandler supportHandler(Configuration conf) {
      return new SupportHandler(conf.getRequiredMap());
    }
}

现在,如果您遵循这种方法,添加新的受支持类型将变得完全无代码,您只需添加一个配置,这是迄今为止我能提供的最佳方法。

然而,这两种方法都缺乏 java 8 的特性;)

关于java - 使用 Java 8 重构多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59835676/

相关文章:

java - Oracle 无效标识符不理解字符串

Java Flight Recorder - 如何提取自定义事件字段的值?

java - 在接口(interface)实现中不实现异常抛出可以吗?

java - 在 Java 8 中使用列表值 Map<Key, List<Value>> 将 Map 反转为 Map <Value, Key>

java - 如何序列化一个 lambda?

java - 如何在 C Ruby 中使用 Java 库(如 JDBC)?

java - @Scheduled 与 ThreadPoolTask​​Scheduler 行为

java - 从 html 页面恢复 JAVA-Spring (with thymeleaf) 中的表单

java - 静态资源(图片)Tomcat或Nginx服务器

java-8 - java8映射如何简单地将一些元素添加到列表值