Convention-over-configuration is a convenient thing. Instead of writing tons of configuration in xml/yaml/json/whatever, you simply know that something will have a given default value. For example, the restful endpoint URL may have a value of
/class-name/method-name, or a join table will be named
mainEntity_joinField. A “view” can be populated by default with the input parameters of the controller method or other values.
And this is all very nice – we don’t want to annotate each field of a java bean, and we don’t want to explicitly configure our Maven directory structure. But there is a “darker” side of convention-over-configuration, and it comes whenever the knowledge of the default behavior is needed in order to understand the code.
Imagine you open a project for the first time. I have had the need to do that recently – as a government advisor I sometimes have to do a quick-fix or a quick investigation of some software that would otherwise require a tender, a contract, and at least 4 months to handle. I agree it’s a rare use case, but bear with me.
If, for example, a web framework automatically includes
/views/header.ext into your views, and you try to find “where the hell is this menu item coming from”, you may have a hard time. If you try to figure out what controller handles the
/foo/bar/baz URL, and you don’t find any configuration or mapping file, nor you find any part of the URL using the search functionality, you’re lost.
Convention-over-configuration can roughly be split in three groups: straightforward removal of boilerplate code, specific configuration logic and stuff that doesn’t matter for investigating the project. But there is no obvious line between them. The fields of the java-bean can obviously be referred to in a JSP by name, or spring beans are automatically named using the uncapitalized . It doesn’t matter whether Maven has the java classes in src/main/java, or in src/java – you’ll click through the folders anyway. But if there is specific logic of mapping URLs to controller methods, then you’d have to read about the framework being used. In rare cases like mine you may even not know the framework being used, so you have to find that out first.
That’s a problem, in a sense – in order to understand the program flow, you need to know the framework details.
I know this is rarely a big problem – normally you join a team which already has knowledge of the framework and if you find yourself wondering “how is that configured”, you can always ask someone. But as a general piece of advice – try not to use convention-over-configuration with complicated, specific logic. It may save a few keystrokes, but typing is not what takes time in software development. And any complicated convention-over-configuration logic makes the project harder to read and navigate.