My comment on a failed project: "The architecture looks like someone spent an afternoon throwing darts at the index page of Gang of Four".

There's a serious point buried in this, which is that most of us will spend at least some of our time working on projects that neither possess nor require particularly complicated architectures. Even on larger projects there's a good chance that the architectural principles have been set long before we first check the code out of source control, and we'll be constrained to work within them.

This is the root of architecture envy. We read about companies doing exciting things, play with publish/subscribe mechanisms, document stores and containers on our home systems... then go to the office and work on a three-tier application with a single MySQL database as the back end. And as a result there's an ever-present temptation lurking, urging us to make this new feature just a tiny bit more complicated than it needs to be so we can employ the decorator pattern or install a NoSQL database.

This is the wrong approach. Design Patterns is not a menu! Good architecture should be shaped by the problem; you shouldn't be shaping your problem in terms of an architecture you'd like to use. Opponents of TDD like to use the phrase "test-induced design damage" to describe the compromises which must be made for a module to be testable. I'd like to coin "architecture-induced design damage" to describe the compromises which must be made to shoehorn spurious architecture into places where it doesn't fit.

It's still important to think about SOLID principles and other hallmarks of good design such as short methods and clear delineation of responsibility at the detail level - spaghetti code is not an architecture, and there's no reason to add more of it - but once you get into the bigger picture or choice of technology it's time to accept the norms of the system you're working with. Even on a greenfield you need to keep things simple unless there's a valid reason to add complexity.

The problem is that if every developer who touches a project decides they're going to throw their current favoured architecture at it, you don't end up with a well-architected project. You end up with a mess, full of strange little architectural peninsulas and over-engineered follies. (Where I am, we call them "spaceships" - applying rocket science when all the customer wants is a bicycle). You get applications where one part of the front end is Knockout and the other Angular. Libraries with decorators here, pure inheritance there. Deployments that require three different types of database to go live, and a forest of mediators to join SQL rows with MongoDB documents. Strange compromises made where a message queue was the wrong solution, but someone was adamant about using a message queue anyway. In short: architecture-induced design damage.

Dan McKinley makes some good points in his Choose Boring Technology post, but one of the things I most like is the idea of innovation tokens. The idea is that you can only innovate a limited number of things at any time - and choosing to use something new or orthogonal to your existing structure takes away your ability to innovate in other areas. What he's encouraging is a sort of internal discipline - to identify where you want to spend your innovation. If you need to develop a new pricing model, then you should be spending your innovation tokens on the pricing model, not bending 50,000 lines of existing code to fit the Architecture of the Month Club's current darling. On the other hand, if your task is refactoring, then you've got innovation tokens to spare and the best place for them is to start considering what your architecture looks like on a holistic level.

Even with this in mind, it's important to keep the problem in mind when doing this kind of architectural refactoring. There's a reason why tiered web applications, object-oriented design and SQL databases have become the boring, de facto approach - and that's because they're well-understood, they're reliable, and with sensible design they scale a lot further than people give them credit for. There are times when other solutions make more sense, but in those cases it will be obvious from the problems the project needs to solve. If it's not obvious, and you can't answer the question, "why not just use n-tier and SQL?" with any better answer than "it's dull", then you're probably suffering from architecture envy. What genuine need for innovation are you going to ignore as a result?