我有一个旧代码库,需要使用 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/