The Problem - Connecting to a Database
(or other external resource)
When a programming language needs to connect with a database, there is usually some friction as the programming language has to conform itself to speak the database’s language, or vice versa. This is commonly called an impedance mismatch. (This situation exists almost any time a program needs to talk to an external resource; databases are just the most common example.)
Before long someone builds a framework to bridge the gap and hide the gritty details. These frameworks come in a variety of shapes, sizes, and complexities: think .NET’s ADO.NET and LINQ, Ruby’s ActiveRecord, Hibernate, iBATIS, etc.
The Database Schema
Every framework needs to know some information about the database schema in order to work. The frameworks fall into two main camps: configuration-based frameworks, and convention-based frameworks.
To put things simply: Configuration-based frameworks read schema information from a configuration file. Convention-based frameworks rely on the developer to follow specific naming conventions within the software, and then the framework deduces the schema information from the naming conventions and directly from the database.
You can also think of the difference as “Explicit vs. Implicit Configuration”, or the “.NET/Java Way vs. the Ruby on Rails Way”.
General Differences
Generally, configuration-based frameworks are more commonly found in compiled languages; and convention-based frameworks in scripted languages. The reason is that most compiled languages are type-checked at build time, so the framework needs to know more information at that time. On the opposite side of the river, most scripted languages use implicit typing or duck typing, where the interpreter avoids making any decisions about a variable’s type until runtime, so the framework can get by with less information.
There are further differences regarding when the framework logic is generated, and how it is stored. Configuration-based frameworks generate logic from the schema at build time and store the logic in code as an API. The API is then consumed by the rest of the application.
Convention-based frameworks tend to generate logic dynamically at run time. The logic may be cached by the framework for future use, or discarded.
Since the convention-based framework only generates logic when it is needed, it can afford to support more features without making the code significantly bigger. Configuration-based frameworks, on the other hand, create and store all of the logic at build time, regardless of whether it is actually used. This leads to a tradeoff: each additional feature requires extra code that is multiplied by the number of different tables or columns. In other words, a convention-based approach can provide more features with less code, a configuration-based approach provides fewer features using more code.
Tradeoffs
There are many personal opinions as the which approach is better.
Proponents of configuration-based frameworks argue that:
- The code is more understandable because everything is spelled out and written down.
- A narrower API leads to cleaner code - everyone is forced to use the same tools to get the job done.
- Configuration-based frameworks are easier to use on big teams; a senior developer can set up the framework, and a junior developer can consume the API without having to understand how it got there.
- It is a Good Thing to be able to check configuration into source control.
- Since the logic is generated at compile time, less has to happen at runtime. This improves performance and leads to statistically fewer runtime bugs.
Proponents of convention-based frameworks argue that:
- The code is more readable because there is less to read.
- A broader API leads to cleaner code - a developer generally has more options and can use the right tool for the job.
- A developer who can’t understand the convention shouldn’t be on the project in the first place. Besides, less code means more agility and smaller teams.
- For database frameworks, the code (or the database schema) is the configuration. Why do you need to store it in an additional place?
The Verdict?
So where do I come out? Like many topics in software, the answer is “it depends.”
I lean toward a convention-based framework (and scripted languages) for rapid prototyping and for quick projects and small teams. I think of this as the “microwave” approach: good for lightweight snacks, but you don’t want to plan a meal around it.
When I need a real powerful oven, I lean toward a configuration-based framework. I’ve found that big projects and big teams always benefit from having configuration nailed down in a file that everyone can reference.
For more articles on Configuration vs. Convention, search Google.