54

I was looking at the WPF MVVM framework Caliburn.Micro and read that a lot of standard things are based on naming conventions.

For example, automatic binding of properties in the View to properties in the ViewModel. Although this seems to be convenient (removes some boilerplate code), my first instinct reaction is that it isn't completely obvious to a new programmer that will read this code. In other words, the functionality of the application is not completely explained by its own code, but also by the documentation of the framework.

EDIT:

So this approach is called convention over configuration. Since I could not find any questions concerning this, I altered my question:

My question is:

Is convention over configuration a correct way of simplifying things, or is it violating some programming principles (and if so, which ones)?

3
  • 10
    Most approaches/principles violate some other approaches/principles to some degree. It's mostly a matter of priorities and trade-offs. Sep 24, 2012 at 7:30
  • 1
    True, but I find the difference stated in my question a bit odd, and therefore I am interested in the specific trade-offs and possibly violated principles when using convention over configuration.
    – Geerten
    Sep 24, 2012 at 7:44
  • The concept of software traceability is relevant here. Programmers rely on tools like grep, but need better tools to trace over uses of generated code. For example, tools should make it more explicit that the css class "user-id" is related the generated method getUserId() and the table column user_id.
    – Macneil
    Jan 21, 2015 at 20:34

5 Answers 5

50

I don't consider "an application should be fully explained by its own code" a fundamental programming principle. There are lots and lots of things which are not explained by just looking at the code of an application. Apart from knowing the basic things of the programming language itself (syntax and semantics), you need to know the conventions. If an identifier in Java starts with a capital letter, it is a type. There are lots of these conventions you need to know.

Convention over configuration is about reducing the amount of decisions the programmer has to make about things. For some things this is obvious -- nobody would consider having a language where the capitalization of types is something you need to declare at the top of your program -- but for other things it is not so obvious.

Balancing convention and configuration is a difficult task. Too much convention can make code confusing (take Perl's implicit variables, for example). Too much freedom on the programmer's side can make systems difficult to understand, since the knowledge gained from one system is rarely useful when studying another.

A good example of where convention aids the programmer is when writing Eclipse plugins. When looking at a plugin I've never seen, I immediately know many things about it. The list of dependencies is in MANIFEST.MF, the extension points are in plugin.xml, the source code is under "src", and so on. If these things were up to the programmer to define, every single Eclipse plugin would be different, and code navigation would be much more difficult.

5
  • 4
    +1: software development is complicated enough as it is. If you can avoid complexity in things you have control of, do so. Save the complexity for places you absolutely need it.
    – scrwtp
    Sep 24, 2012 at 9:03
  • 1
    Thanks for the clear explanation about the difference and balance.
    – Geerten
    Sep 25, 2012 at 6:42
  • 3
    "If an identifier in Java starts with a capital letter, it is a type." - whether it's a type depends on syntax context not on naming pattern, Java naming conventions do not affect the 'compilation configuration'. Are you sure it's a valid example? The last example is not correct as well - it's about "configuration conventions" not "convention over configuration". You are saying right things but they have little to do with the subj principle.
    – Den
    Jan 21, 2014 at 16:56
  • 4
    Don't overanalyze the examples, they are just examples. The first one is just an example of a convention, the last one is an example where convention is a good thing. The Perl example is an example where too much conventions (implicits) are a bad thing (IMO, I should add).
    – JesperE
    Jan 22, 2014 at 7:14
  • 1
    The thing I hate is when convention over configuration becomes convention without configuration...in the latter case you tend to get trapped with a codebase it can be hard to integrate with other tools.
    – Andy
    Oct 17, 2015 at 18:18
85

Gave +1 to @JesperE, and like to add something:

is it violating some programming principles

Yes, "convention over configuration" violates the principle "explicit is better than implicit" (have a look, for example, at "Zen-Of-Python").

On the other hand, the opposite "configuration over convention" tends to violate "Simple is better than complex", and worse, it violates the DRY principle in a subtle way, since you need to repeat names used in your code also in your configuration.

7
  • 4
    That's the most direct answer to the question! Sep 24, 2012 at 12:22
  • This is the actual correct answer among two most upvoted.
    – Den
    Jan 21, 2014 at 16:51
  • +1 for "explicit is better than implicit" Nov 10, 2014 at 17:46
  • 15
    My favorite part about this answer is that it implicitly highlights the reality than principles of good software development often sit in tension with each other. Engineering is about balancing those tensions appropriately for your specific context and application. Dec 28, 2014 at 18:50
  • 1
    @Yorro It's more that explicitness at all costs adds noise which can make the code harder to visually parse for the programmer. Convention/implicitness is preferred when one may intuitively and robustly determine the convention through the context. E.g. Needing self. references to access class variables inside the class methods would just be noise (as opposed to just leaving it out, like Ruby does): stackoverflow.com/questions/68461184/…
    – Magne
    Aug 13, 2021 at 21:46
9

Some of "convention over configuration" just boils down to sensible defaults. You should only have to configure something to use it for a non-standard purpose. I have to compare Struts to Rails here. In Rails, you have to put your "actions/screens" in a folder and then they just work. In Struts, you still have to put them in a folder, but you also have to come up with an action-name AND a JSP file AND a form name AND a form bean AND specify how these three things work together in Struts-config.xml AND specify that the form belongs on the request (RESTful). If that isn't enough, the form/form-bean mapping has its own section in Struts-config which is then mapped independently to the action section in the same file and it all relies on handwritten strings in the JSP file in order to work properly. For each screen, that's at least 6 things you shouldn't have to do and as many opportunities to make an error. I think you can set most or all of those things manually in Rails if you need to, but 2/3 of Struts development time is taken up building and maintaining unnecessary layers of complexity.

In all fairness, Struts 1 was designed when people were porting applications between the desktop and the web. The flexibility that Struts has baked in makes it suitable for everything Rails does, plus everything a desktop application would need. Unfortunately, the mountain of configuration that enables that flexibility is a huge ball and chain for someone who just needs to write a web app or just a desktop app.

I worked somewhere that they took the next step and argued, "Configuration over Code" but having seen that taken to its logical extreme, the result is that the configuration becomes a new coding language. It was a shell game where complexity was pushed around without being tamed in any significant way. And it gave me an appreciation for all the type-checking and other safety nets that a well-designed programming language has. Some half-baked configuration file format that blows up with no error message if you add a space or an apostrophe is NOT an improvement over a quality programming language which has suites of editing tools and a quality compiler written for it.

I can't imagine that having sensible defaults violates any theoretical principals about extensibility and modularity. A Ruby/Rails programmer would sooner jab a hot poker in their eye than switch to a framework like Struts 1 where all configurations are made explicitly in multiple XML files. I'm not arguing Rails vs. Struts IN GENERAL, but that convention can be a huge productivity win. These two technologies are the most extreme real-world comparison I've come across.

If you work in Java at all, check out Joshua Bloch's, "Effective Java," Item 2: "Consider a Builder when faced with many constructor parameters" pp. 11-16. For most purposes, some parameters (configuration) is required, and some is optional. The basic idea is to require only the necessary configuration and only make the user (which could be another program) specify additional options as needed. I cleaned up a bunch of code with this pattern a month ago and it positively sparkles.

8

In other words, the functionality of the application is not completely explained by its own code, but also by the documentation of the framework.

The functionality of an application that uses a framework is always dependend on the framework, convention over configuration doesn't make a difference in that regard.

In my experience, convention over configuration not only makes code more readable, but it also reduces the possibility to introduce subtle bugs (especially copy-paste-bugs).

For example, let's assume in some framework A, event FooBar triggers a call to handleFooBar. In another framework B, this correlation is configured somewhere in an XMLfile.

So, in A, it's simply

handleFooBar() {
   ...
}

and unless you have missspelled FooBar, it will be called whenever FooBar happens.

In B, it's again

handleFooBar() {
   ...
}

but also

<eventconfiguration>
  <event>
    <type>FooBar</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

With hundreds of things to configure this way, it's all too easy to accidentaly create a subtle bug like

<eventconfiguration>
  <event>
    <type>BarFoo</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

because after copy-pasting, we've only changed <type> but forgot to change <handler>.

Since those configuration files are large and monotonous, it's less likely that someone will find the bug by proofreading than he would find a similar bug in actual program code.

1
  • 1
    +1: avoiding repetitive, boring-to-write, hard-to-read, almost-always-obvious configuration is the major advantage of convention-over-configuration. Sep 24, 2012 at 11:14
-1

It might be violating few principles, but at the same time it obeys one of the most fundamental design principles, SRP (Single Responsibility Principle).

1
  • 3
    Using conventions has nothing to do with single responsibility. I could be using a convention and doing 100 things in it.
    – Suamere
    May 13, 2015 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.