gpt4 book ai didi

java - 在工厂中动态调用正确的实现

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:20:01 26 4
gpt4 key购买 nike

我有一个库可以解析 URL 并提取一些数据。每个 URL 有一个类。要知道哪个类应该处理用户提供的 URL,我有下面的代码。

public class HostExtractorFactory {

private HostExtractorFactory() {
}

public static HostExtractor getHostExtractor(URL url)
throws URLNotSupportedException {
String host = url.getHost();

switch (host) {
case HostExtractorABC.HOST_NAME:
return HostExtractorAbc.getInstance();
case HostExtractorDEF.HOST_NAME:
return HostExtractorDef.getInstance();
case HostExtractorGHI.HOST_NAME:
return HostExtractorGhi.getInstance();
default:
throw new URLNotSupportedException(
"The url provided does not have a corresponding HostExtractor: ["
+ host + "]");
}
}

问题是用户请求解析更多 URL,这意味着我的 switch 语句在增长。每次有人提出解析器时,我都必须修改我的代码以包含它。

为此,我决定创建一个映射并将其公开给他们,以便在编写他们的类时,他们可以通过向工厂提供主机名和提取器来将自己注册到工厂。下面是实现了这个想法的工厂。

public class HostExtractorFactory {

private static final Map<String, HostExtractor> EXTRACTOR_MAPPING = new HashMap<>();

private HostExtractorFactory() {
}

public static HostExtractor getHostExtractor(URL url)
throws URLNotSupportedException {
String host = url.getHost();

if(EXTRACTOR_MAPPING.containsKey(host)) {
return EXTRACTOR_MAPPING.get(host);
} else {
throw new URLNotSupportedException(
"The url provided does not have a corresponding HostExtractor: ["
+ host + "]");
}
}

public static void register(String hostname, HostExtractor extractor) {
if(StringUtils.isBlank(hostname) == false && extractor != null) {
EXTRACTOR_MAPPING.put(hostname, extractor);
}
}

用户会这样使用它:

public class HostExtractorABC extends HostExtractor {

public final static String HOST_NAME = "www.abc.com";

private static class HostPageExtractorLoader {
private static final HostExtractorABC INSTANCE = new HostExtractorABC();
}

private HostExtractorABC() {
if (HostPageExtractorLoader.INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}

HostExtractorFactory.register(HOST_NAME, this);
}

public static HostExtractorABC getInstance() {
return HostPageExtractorLoader.INSTANCE;
}
...

当我意识到这永远行不通时,我正在拍拍自己的背:当我收到 URL 时,不会加载用户类,只有工厂,这意味着它们的构造函数永远不会运行,并且映射始终为空。所以我回到绘图板,但想要一些关于让它工作的想法或其他方法来摆脱这个讨厌的 switch 语句。

小号

最佳答案

另一种选择是使用 Service Loader方法。

让您的实现者在 ./resources/META-INF/services/your.package.HostExtractor 中添加如下内容:

their.package1.HostExtractorABC
their.package2.HostExtractorDEF
their.package3.HostExtractorGHI
...

然后在你的代码中,你可以有这样的东西:

HostExtractorFactory() {
final ServiceLoader<HostExtractor> loader
= ServiceLoader.load(your.package.HostExtractor.class);

for (final HostExtractor registeredExtractor : loader) {
// TODO - Perform pre-processing which is required.
// Add to Map? Extract some information and store? Etc.
}
}

关于java - 在工厂中动态调用正确的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46096302/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com