gpt4 book ai didi

具有类型安全实现的 Java 泛型接口(interface)

转载 作者:行者123 更新时间:2023-12-01 19:22:03 25 4
gpt4 key购买 nike

我正在寻找从通用框架调用特定接口(interface)的良好替代方案。我用代码来举例说明。请参阅问题部分,包含示例代码主要是为了彻底性,并将示例应用到实际场景中。

示例

假设我们想要基于组件列表构建报告。假设我们有两种特定的组件类型:

public interface Component { ... }
public class PDFComponents extends Component { ... }
public class WordComponents extends Component { ... }

每个组件都有一个 ReportBuilder 实现,例如

public interface ReportBuilder { ... }
public class PDFReportBuilder extends ReportBuilder { ... }
public class WordReportBuilder extends ReportBuilder { ... }

它构建了特定的报告实现

public interface Report { ... }
public class PDFReport extends ReportBuilder { ... }
public class WordReport extends ReportBuilder { ... }

最后,我们有了定位组件并根据组件生成报告的服务。

public class ReportService {
ReportComponentRepository repo;
List<ReportBuilder> builders;

public <T extends Report> T getReport(Class<T> reportType) {
// Get report components. E.g., this might return List<PDFComponent>
List<Component> reportComponents = repo.getReportComponents(id);

// Build report from components using one of the registered builders
for (ReportBuilder builder : builders) {
if (builder.buildFor(reportType) {
return builder.buildReport(report);
}
}
}
}

使用该服务的示例

List<PDFReport> reports = new ReportService().getReport(PDFReport.class);

问题

现在回答问题。如何设计一个通用的 ReportBuilder 接口(interface),使其实现具有类型安全性?

例如,选择界面:

public Report buildReport(List<? extends Component> components);

会导致其实现丑陋:

public class PDFReportBuilder implements ReportBuilder {

@Override
public Report buildReport(List<? extends Component> components) {
PDFReport report;

for (Component component : components) {
if (component instanceOf PDFComponent) {
// assemble report ...
report.includeComponent(component);
}
}

return report;
}
}

当我们真正希望 PDFReportBuilder 的界面是这样的时,

 public Report buildReport(List<PDFComponent> component) { ... }

最佳答案

如果将 Component 的类型设置为 ReportBuilder 的类型变量,则可以:

public interface ReportBuilder<T extends Component> {
public Report buildReport(List<T> components);
}

public class PDFReportBuilder implements ReportBuilder<PDFComponent> {
public Report buildReport(List<PDFComponent> components);
}

不过,您必须评估是否确实需要 ReportBuilder 中的类型变量。这并不总是正确的选择。另外,如果您还想要PDFReportBuilder.buildReport要获得 PDFReport 的返回类型,那么您还需要将其作为类型变量(即 public interface ReportBuilder<T extends Component, S extends Report> )。

关于具有类型安全实现的 Java 泛型接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696295/

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