mercredi 24 avril 2019

How to automatically register new subclasses?

I'm working on the reporting module of our web-application. There are six reports available to the client, each of them has a code. The problem is that now the module is not closed for modification with respect to potential addition of new reports, thus violating OCP.

To elucidate, I have the following set of classes:

A generic report class, which all other reports inherit:

public abstract class Report 
{
    private final String code;

    Report(String code)
    {
        this.code = code;
    }

    public String getCode() { return code; }

    public abstract byte[] generate();
}

A servlet which manages POST requests for report generation:

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
    }

}

Report registry, which stores all existing reports for later access:

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);
    }
}

However, ReportRegistry violates OCP, since we need to add an to its static block every time a new report is created.

My question is: how can I make any new subclass of Report to be registered automatically, without any explicit mentioning?

Aucun commentaire:

Enregistrer un commentaire