Я работаю над модулем отчетности нашего веб-приложения. Клиенту доступно шесть отчетов, каждый из которых имеет код . Проблема в том, что теперь модуль не закрыт для модификации в отношении возможного добавления новых отчетов, что нарушает OCP.
Чтобы выяснить, у меня есть следующий набор классов:
Общий класс отчета, который наследуют все остальные отчеты:
public abstract class Report
{
private final String code;
Report(String code)
{
this.code = code;
}
public String getCode() { return code; }
public abstract byte[] generate();
}
Сервлет, который управляет запросами POST для генерации отчета:
public class ReportServlet extends HttpServlet
{
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
Report requested = ReportRegistry.lookup(req.getParameter("report_code"));
byte[] bytes = requested.generate();
// attach bytes to response
}
}
Реестр отчетов, в котором хранятся все существующие отчеты для последующего доступа:
public class ReportRegistry
{
private static final Map<String, Report> registry = new HashMap<>();
static
{
// Violates OCP!
registerReport( GlobalReport.getInstance() );
registerReport( AvailablePackagesReport.getInstance() );
registerReport( BadgeReport.getInstance() );
registerReport( PlacementReport.getInstance() );
registerReport( TerminalReport.getInstance() );
registerReport( VerActReport.getInstance() );
}
private ReportRegistry() { }
static void registerReport(final Report report)
{
registry.put(report.getCode(), report);
}
public static Report lookup(final String reportCode)
{
return registry.get(reportCode);
}
}
Однако ReportRegistry
нарушает OCP, поскольку нам нужно добавлять запись в его статический блок каждый раз, когда создается новый отчет.
Мой вопрос: как я могу сделать так, чтобы любой новый подкласс Report
регистрировался автоматически, без какого-либо явного упоминания?