How to automatically register new subclasses?

Evgeniy Gryaznov :

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 entry 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?

jwismar :

I would think OCP would be more applicable to Report itself, and that having ReportRegistry sitting outside of the class hierarchy would be a valid design.

That said, if you want to avoid modifying ReportRegistry each time you create a Report subclass, you could use some reflection tricks to seek out all such subclasses, or create an annotation that ReportRegistry could search for to register all classes with instances.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=157778&siteId=1