Capybara James sends us some code which is totally designed to be modular.

This particular software accepts many kinds of requests which it then converts into a request for a ListView. This is a perfect example of where to use polymorphism, so you can write one transform method that operates on any kind of request.

Let's see how they did it:

@Component
public class ListViewTableRequestTransformer implements Function<TableExportRequest, ListViewRequest> {
    @Override
    public ListViewRequest apply(TableExportRequest request) {
        return new ListViewRequest(request.getFilters(), request.getRangeFilters(), request.getSearch(), request.getSort());
    }
}
@Component
public class ListViewFormulaRequestTransformer implements Function<FormulaExportRequest, ListViewRequest> {
    @Override
    public ListViewRequest apply(FormulaExportRequest request) {
        return new ListViewRequest(request.getFilters(), request.getRangeFilters(), request.getSearch(), request.getSort());
    }
}

Now admittedly, my first instinct for letting generics just handle this wouldn't work in Java thanks to type erasure. My excuse is that I've been using C++ templates for too long. But what's not pictured in this code is that TableExportRequest and FormulaExportRequest both implement the same base interface, which means polymorphism could still condense this down into a single function: ListViewRequest apply(RequestInterface request).

Duplicated code like this is like cockroaches. You've seen two, which means there are many many more lurking in the codebase. All of the various request types get their own identical method, differing only in signature.

All my explanation doesn't sum this up as pithily as Capybara James did, however:

There was an attempt to make the code modular and scalable. An attempt I say.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!