Je suis look pour de bonnes alternatives à l'invocation d'une interface spécifique à partir d'un cadre générique. Je vais illustrer avec le code. Regardez la partie question, l'exemple de code est principalement inclus pour la rigueur, et pour mettre l'exemple dans un scénario réel.Java interfaces génériques avec les implémentations Typesafe
Exemple
Supposons que nous voulons construire un rapport basé sur une liste des composants. Disons que nous avons deux types de composants spécifiques:
public interface Component { ... }
public class PDFComponents extends Component { ... }
public class WordComponents extends Component { ... }
Chaque composant a une implémentation ReportBuilder, par exemple,
public interface ReportBuilder { ... }
public class PDFReportBuilder extends ReportBuilder { ... }
public class WordReportBuilder extends ReportBuilder { ... }
qui construit des implémentations de rapport spécifiques
public interface Report { ... }
public class PDFReport extends ReportBuilder { ... }
public class WordReport extends ReportBuilder { ... }
Enfin, nous avons le service qui localise composants et produit un rapport sur les composants.
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);
}
}
}
}
Exemple d'utilisation du service
List<PDFReport> reports = new ReportService().getReport(PDFReport.class);
Question
maintenant à la question. Comment puis-je concevoir une interface générique ReportBuilder qui permette la sécurité des types dans ses implémentations?
Par exemple, le choix de l'interface:
public Report buildReport(List<? extends Component> components);
causerait la laideur dans sa mise en oeuvre:
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;
}
}
quand nous désirons vraiment l'interface pour PDFReportBuilder être par exemple,
public Report buildReport(List<PDFComponent> component) { ... }
Je suppose que vous souhaitez implémenter des interfaces au lieu de les étendre, le '' PDFReport' met en œuvre VERBAL D', et parenthèse après les classes/interfaces les noms ne sont pas vraiment là. –
Vous avez absolument raison.À la longueur de mon message, je vois que j'étais négligent avec certains détails. Ceci est corrigé maintenant. –