I just got back from CodeMash in Ohio which was a really great conference - not only did I get to meet a number of friends from the .NET community but also saw sessions from pretty much every other technical persuasion. Of the sessions I saw though, the most courageous one was by Alex Papadimoulis from Inedo (perhaps better known for the Daily WTF).
The cornerstone of his presentation is to really challenge yourself when you make any software implementation harder than it absolutely has to be in the name of future requirements, changes or extensibility. I’ve noticed over the past few years that making applications dynamically extensible has gone from a rare and cool capability to a presumed requirement even for the simplest applications. We plow in with IoC containers, elaborate software patterns, and large scaffolding all in the name of being ready for future change.
After all, who wouldn’t like to show years of maintenance programmers that you had a full understanding of both Generics and the command pattern:
orderController.ShipOrder( ShipOrderCommandFactory.Create(order.OrderNumber, carrierId, shippedDate));
Instead of just being really boring:
orderController.ShipOrder(order.OrderNumber, carrierId, shippedDate);
Instead of doing the simplest code approach that will deliver functionality today, we worry about how we can account today for the potential change for tomorrow: What if we want to support multiple, incompatible databases? What if we want to add more commands later? What if we decide to switch from WinForms to WPF?
You Aren’t a Fortune Teller
The thing is, in every one of those cases:
- You’re going to ship a new release. So you’ll have an opportunity to change the code in the face of the actual requirements, not theoretical ones.
- You’re going to be wrong about what the future requirements are. It’ll turn out that the new database is incompatible in a way you didn’t expect (what? No transactions? uh oh…) so you’ll have to change your model anyway. Only now you’ll be extra paranoid and REALLY gold plate it.
- You’ll have to retest anyway. For any worthwhile change you’ll have to retest that the whole thing works together anyway.
So save yourself now: Really challenge why you need to make everything an interface, or if it’s really necessary to use the command pattern to isolate every operation you might perform. It could be you’re making Visual Studio and you really have to create an extensibility framework that’s just about infinitely flexible. Or it could be you can get away with something much simpler. Perhaps you really don’t need any of that at all.
In the end, remember that your ultimate users don’t care how you deliver the features in your application, they just care that they work. Conversely, you’ll get no points for delivering a poor or fragile experience because you’ve made everything isolated and configuration driven.
I really admire Alex for getting up in front of a crowd that’s been hearing two days of how to create ever more elaborate isolation layers between every aspect of software and challenge the foundational premise of it all. Kudos!
The latest update to PostSharp Diagnostics adds Loupe support, enabling extensive high-performance logging to be added to any .NET application with virtually no code changes. PostSharp even has a great free option for developers that complements Loupe Desktop! Read more
The first release of the Loupe Agent for .NET Core is also our first open source version of the Loupe Agent. This is the first step in our plan to open source the entire Loupe Agent to make it easier for anyone to extend and take advantage of what Loupe... Read more
Loupe Service now has a shorter, direct site name that's faster, anywhere in the world. Just to go App.OnLoupe.Com, the new CDN-accelerated endpoint for the Loupe Service. Your existing Agents and Loupe Desktops are unaffected by this change, but access to the web UI will be redirected to the new... Read more