A few hours ago I've posted a tweet that gathered unexpected response:
Popular things that I consciously avoid: IoC Containers, Mocking, ORM, SQL, NuGet, WCF, WWF, WPF, NServiceBus, DTC and TFS.
However the only question people got was: "What's the problem with NuGet"? Well, answering it requires going a few steps back.
Keep in mind, that I'll be pushing my point of view slightly to the extreme, just to make the point more clear.
Every new junior developer (growing team, or a product) starts with the simple approach: we start writing software and adding features till we deliver (sometimes in waterfall approach quite a lot of time could be invested before this happens). Then we grow from there. As software and developers mature, they face new challenges and problems. Luckily we get new tools, skills and ideas to help us growing. New team members and frameworks join in to help everybody move forward and deliver more. Things that hurt or are uncool are thrown away (even though sometimes it might take some effort).
Sounds like fun.
However, somewhere in my career path, I've been lucky to get on a rocky path. We never had real ability to just add more tools, people or features. I never worked on a project that had more than 3 people involved in it full-time at once. All these projects were stressed in time (no man-years till the next release) and functionality (rapidly growing companies need to evolve and scale fast).
Sounds like a minefield and completely unrewarding environment, does not it? Every wrong decision shows itself really fast. Every step that is just good (and not outstanding) also shows (since you waste precious time that could've been invested more efficiently). So my development career was governed by pain: wrong decisions and poor choices lead to long hours, late nights and unsustainable work efforts. Not, that I don't make frequent mistakes any more, but these ones were really bad.
And that's actually good: harder life hits you, faster you learn. Bad ideas and tools don't get a lot of chances to stick around in such poor environment. Semi-useful things don't get to stick either. The core principle that still remains and always works is disciplined simplicity and focus. Among other things this means:
- If I get a chance to remove something or break things down with a small effort, I will take that effort.
- If I get a chance to add something with a small effort, I will fight it.
- I prefer to refactor something first and then maybe add complexity as opposed to adding complexity and then maybe refactoring.
- If I have a chance to defer solving the problem (or even avoid it altogether), I will try that.
Obviously this is the idealistic scenario, that does not factor business values and the rest of the real-world. However, these are just strengthened even more, when you start consciously measuring costs and try to avoid problems.
This often comes to things that other would see as extremes: dropping project references, avoiding to use new technology or framework, removing files, taking preventable risks and even turning down features. Some call this pain-driven development - you keep only things that are too painful to live without, because you can't afford keeping the rest; you focus only on problems that are the most painful for the business (and are measured in real money), because you don't have enough people and hours to deal with the rest.
This is like constant tending your garden or curating an exhibition: you continuously look look for bad combinations or things that are just good (and not great). You think twice before adding something new (Dependencies also count). Because each thing means:
- One more thing for a new developer to learn.
- One more thing that have a chance of going wrong in production.
- One more thing to keep in mind while developing.
- One more logical dependency that has a chance of causing regression.
All this zealotic obsession with simplicity would not be needed if I had environment that is more rich: with more resources, time and people to help us. Would it?
If we push the idea to the extreme, consider two imaginary products. One could be designed by a rich team with a strong vision, smart architects and man-years dedicated for their goal. The other product could be developed mostly by a semi-organized group individualistic hackers, that scavenge a few hours, accept risks, while working on diverse bits, that are kept stupid and isolated.
How do you think, will these projects perform in real life? How close is your project to either of these extremes?
- An example of rich project environment would be something like: TFS.
- An example of poor project would be a collection of hacks commonly known as Git.
I'm not trying to compare these projects or judge them. This is up to you :)
BTW: the answer to the question of "What's wrong with NuGet, NSB etc" is simple: these projects might be good, but I can live without them in my projects (or learned how to live without them). They didn't prove essential (just like almost all utilities and open source libraries I've created and thrown out myself).
Constraints of such projects are:
- A few developers (distributed around the world) and rapid releases.
- Necessity to compete with multi-billion transnational companies.
- Necessity to have complex business intelligence (think business analytics) OR extreme scaling (think big data processing with 200x scaling in matter of hours) OR flexible and rich UIs OR cross-cloud low-friction development OR low operating costs OR tolerance to process failures and human errors.
More often than not, such projects require ALL of that at once (that's how we roll at Lokad). And guess who gets to babysit these projects and spend weekends fixing things that go wrong?
Such tight constraints led to the architectural principles and focus on simplicity that I've outlined in this article.
Tools and frameworks that we still stick to - are getting all the passion, gratitude and even free time. They are worth it, since they helped to work through the problems that we were unable to solve otherwise. However, among all these precious things, the most valuable tool and architectural principle is keep things simple, focus on that.
PS: You can continue reading on this topic in a fine article by Rob Ashton: Your container is not wanted here.