Firstly, I'm 100% in favour of conventions and an entire team complying. However, I'm looking at frameworks (mostly various PHP but also Ruby on Rails and others) that pretty much enforce coding by convention. On the surface this seems like a great thing, so URLs are directly translated to /controller/action, for example. Models are named after DB tables, and the system knows exactly where to load all files from using a really simple autoloader.
However, we operate a white-label platform and what works for most clients doesn't necessarily work for others. Some may require a particular URL pattern, so we need to customise routes. Some may require that pages have a completely different layout to what other clients have, so we end up with an autoloader that is always checking whether zone-specific versions of files exist first, and fall-back to default if required. This makes development REALLY easy for us, because we just drop an appropriately named file into place and away it goes. But since it is the minority of cases where these are required, we find that the autoloader is spending an inordinate amount of time checking for files that are almost guaranteed to be missing.
To improve the situation a little, I was considering adding configuration over convention, so the zones that deviate from the norm would find the necessary overrides in a configuration file and will just go straight to the correct file, removing all of the existing-file checks, which I gather isn't terribly efficient (especially when some pages require hundreds of calls to the autoloader). I guess we would still be using convention by default, but allowing configuration to take over where necessary.
I'm interested to understand whether this is a practical or even recommended solution
Rails works mostly that way. You have the convention, but everything comes with optional params that allow you to change things as needed. Have a legacy database where the unique id is not named
idas Rails would expect it? Just tell Rails the name. Your routes are different? You can still write your own matchers. Have something to be done before a record is saved? Just hook intobefore_save.For everything else things just work. You have a bit more work to declare all the things that are different, but you would have to write some code for that anyway.
We use Rails in a slightly uncommon environment, where we need to use data from an ERP system and use other systems that are not fully integrated with Rails, but it still takes a lot of work away at the core.
But obviously it only makes sense if there is a large enough core of things that all systems have in common, especially if you intend to write something completely from scratch. Adding flexibility that does not break things all the time requires careful planning.