Friday, November 21, 2014

Code is like Wet Sand Built on Wet Sand

The softness of software means that everything we build is sitting on a liquefaction zone. Everything works until someone decides to change the underlying structure. A NodeJS package changes and breaks your code. Entity Framework 6 removes a feature that you need and now your have to refactor your data layer. Chrome adopts the latest CSS revision and text now doesn't appear on your page.

We need updates to software to fix bugs and make development tasks easier. If we didn't do that we'd still be developing with assembler and running DOS. We also need to retire old things because the combinations of things to support grow exponentially over time. Like that estimate before the invention of the transistor that we'd one day need every grown woman in America to be a phone operator, we'd need every high school grad to be a software tester to test all the combinations.

The most common approach to keeping software flexible is to keep areas of functionality with an app very specific and to use abstractions so that no one part knows how another part works. In object oriented programming these are known as the SOLID principles.

Now, if you and your team have the time, skill and discipline to obey these principles, your codebase can survive changes for many years without it getting much harder to modify. But companies need to make deadlines to make money, not everyone knows these ideas and sometimes people just want to be done with a task. Damn real world :)

One way companies mitigate the amount of code they have to maintain is to drop support for things in their products. No more Windows XP and Internet Explorer 6 patches. jQuery 2.x and AngularJS 1.3 need IE9+. Otherwise the testing becomes too onerous, and makes paid products too expensive relative to their value. For free products, this is just too much to ask

I think there is another approach taking shape: planned obsolescence at the app level, not just at the feature/platform level.

The SOLID principles help keep it easy to replace tiny units of code within an app. Lately, though, it feels like people want to expand that approach to entire apps. I've heard people on coding podcasts ask JavaScript developers how they plan to keep a web app running for over 5 years when JS libraries change so fast and the answer is that they don't. They expect the app to be obsolete and to be replaced by something else.

Every app that lives in a cloud system like Azure or Amazon Web Services costs someone some money for every moment it's running or every byte it delivers. Once an app's popularity wanes and the revenue stream drops below the cost of keeping it running it will be decommissioned. Online games are already doing this.

You can see this happening with mobile platforms, too. It's easy to do with hardware that can't be upgraded and costs as much to repair as to replace with the latest version. I have a Windows Phone 7 phone and the flow of new apps for it has almost stopped. Your iPhone 4S can run iOS 8, but it probably shouldn't for performance reasons. As apps start requiring iOS 8+ your 4S and down will be left behind.

As someone who works with some 10+ year old code at work, I support the idea of planned obsolescence at the app level. What would that look like for executables on PCs and servers?

  • A set of small apps with very limited responsibilities. No monolithic services with 20 threads doing 20 different things.
  • Lots of executables. Maybe one that launches the rest, but again, no 1 giant process with a ton of threads.
  • Self-updating. Don't rely on users to keep things up to date. Provide control for the risk-averse enterprise, but limit component use to a year or 2.
Shortly after I started this post Martin Fowler's wrote about "sacrificial architecture", which seems to be a way to deal with retiring large scale systems. Great minds think alike? :)