What do traditional archers and old Linux hackers have in common?
Terrible looking websites.
I’ve recently started getting into traditional archery. Like any other geek, the first place I looked for information was the Internet. In my quest to suck less at hitting targets, I scoured the Internet for resources. I found lots of content, especially video content, but most of the websites were so outdated it made them hard to read. Not only were they unusable on my phone, but many sites didn’t even look good on my computer. While there are lots of videos on YouTube, I could only find one well designed site. (http://www.archery360.com/)
The thing about traditional archery is that it’s been around for thousands of years. It’s about the most evergreen content you can find. A well written archery site should be able to last indefinitely.
This got me thinking about how to build a future proof (or at least future resistant) web application. The benefits of future proof apps are obvious, but even if you don’t plan for longevity, your app is probably going to be running longer than you expect. I’ve seen many instances of businesses running ancient apps that no one thought would last that long. Think about the trillions of lines of COBOL happily chugging away in server rooms across the world.
Additionally, most people have better things to do than redesign their sites every year. Not everyone needs to keep up with the latest web design trend. This is especially true for people who are producing evergreen content, as opposed to news sites and blogs.
Great software is software that can be efficiently maintained. Pay attention to proper design principles. Separate your concerns, don’t get too clever, and keep things simple whenever possible. Program to interfaces to isolate dependencies. There’s a reason why we call these concepts “best practices”. Additionally, use a robust suite of automated tests. Automated tests will save your ass when trying to make changes. Software that can be properly maintained lasts longer and is easier to deal with. It’s also less expensive. Realize that most of the stuff you write isn’t going to be scrapped in the next few years. The web is a mature platform and most applications are going to be around for a while.
While the Lindy Effect is useful, relying on it alone will steer you wrong. COBOL and FORTRAN have been around since forever, but there’s no way in hell anyone should be writing new code in them. Think about what other people are doing with your chosen stack today. Are people writing anything new in it or is the technology on it’s way out?
Another predictor of longevity is who’s backing the technology in question. ASP.NET has Microsoft behind it. Ruby on Rails and PHP both have large communities of users. Angular.js has Google (and to a lesser degree, Microsoft) behind it. You don’t need a large corporate backer to be viable, but if you see lots of people and companies get behind a technology, the likelihood of it being around in ten years is high.
People access the web from all sorts of devices. From computers to phones to Internet enabled refrigerators. One thing we know about the future is that the number of device form factors is not going down. When I was looking for archery sites, the most common problem was the text was too small. This was because most of the sites were designed with one viewport in mind.
There are two things we can do to make our designs future proof.
How dated does it look? Can you still use it?
While Google isn’t the most beautiful site, it’s simplicity gives it long term appeal. When building something to last, stick with a simple design. You don’t need to go as spartan as Google, but keep the content to chrome ratio firmly in the content side.
With frameworks like Bootstrap and Foundation, it’s easier than ever to make your site responsive. Responsive design should be the default for everything you build on the web. You never know what kind of device someone is going to visit your page with, but with a little bit of effort, you can make your web application work on most of them.
Future proofing should be an important design consideration. By making good choices in the beginning, you can ensure your web app will live a long life.
Now if you’ll excuse me, I have a traditional archery website to build…
There’s nothing like replacing a legacy software system to stoke the fires of self-righteousness. You get to pull some poor users out of the dark ages and save them from a system may have been state of the art last decade, but is junk now. (Ignoring the fact that the old system lasted that long because it did what it what the users wanted it to do.) It’s especially fun when the old system is so laughably bad that it was obsolete the day it was written. Unfortunately, these projects come with a few pitfalls.
The first pitfall is that you can end up building the same legacy system in a new technology. It’s hard to transfer old paradigms into new ones and if you’re not careful, you can end up repeating old mistakes. I worked at a company that was creating an ASP.NET web app built over an existing database. Many of the tables in this database had no keys or relational data. The original system was built on a mainframe using flat files. When that system was upgraded in the 90’s, the flat files were just copied over. There was no regard to modern relational database structuring. When the ASP.NET version came along, the plan was to just copy over each of the old pages, one by one. Management didn’t take modern web and object oriented practices into consideration. Needless to say there was some debate between the developers and management.
The second pitfall can come while gathering requirements. When gathering requirements for the new system, it’s easy (and often correct) to reference the old system. There are two problems using the old system as the primary reference for requirements. First, the system sometimes does things a certain way because of technical constraints. I once worked on replacing a system that had lots of batch processes. Many of those processes were not needed because modern systems were fast enough to process those records on the fly. Second, many times, old systems don’t reflect the business practices of people who use them. There are lots of instances where users have to do something convoluted to get their old system to behave how they need it to. Watch out for these types of scenarios, fixing them is a good way to score brownie points with your customers.
The third pitfall happens when the builders of the new system don’t recognize the advantages of the old system. In the system I mentioned in the first point, the legacy system allowed for rapid keyboard entry. The new system, being a web application, did not optimize for keyboard entry. In the beginning, the developers ignored the users because of the “obvious” superiority of the new way of doing things. Eventually, we realized our error and created a keyboard entry optimized set of web controls. The users were much happier. While it may be fun to mock the old system, you should also pay attention to your users and make sure you aren’t creating a system that’s worse than what they started with. Just because it’s pretty and new doesn’t mean it’s good for the customer.
1. Make sure your new system is using new paradigms. Don’t repeat legacy design.
2. Be careful when gathering requirements from the old system. Especially when it comes to implementation details.
3. Don’t make a new system that’s worse than the system you’re replacing.
Software developers spend most of their time taming chaos into orderly systems. Along the way, there’s often lots of random issues that can throw you off track. Heavy processes like waterfall development sought to eliminate as much risk as possible. Unfortunately, this risk avoidance often lead to lots of pain at the end of a project. After several decades of failure, we now use agile practices that expect chaos. Dealing with chaos and risk are important for anyone who builds software for a living.
I recently read Antifragile by Nassim Nicholas Taleb. Antifragile is one of those books that changes how you see the world. Once you understand the concept of antifragility, it becomes a useful analytic tool. As a software developer, I started thinking about how to build less fragile software.
Antifragile is about how some things become better when exposed to volatility. For example, when you lift a heavy weight, your body makes itself stronger. It becomes stronger in response to stress. Additionally, if you never exercise, your body becomes weak. The human body needs some stress to be healthy. The author talks about three different states.
Fragile things suffer from volatility. Think of a teacup. If you drop it, it will break. Fragile things tend to be rigid and over-optimized. Think of a complex code base with lots of dependencies. One small change can cause the whole system to come crashing down. Systems that are fragile tend to suffer from a small number of devastating events.
Resilient things are indifferent to volatility. Think of a rock. If you drop it, nothing happens. Resiliency can come from redundancy or structural integrity. Think of a well structured code base with lots of automated tests. Failures are generally caught and corrected for before they can cause a problem. Many of the principles of software development revolve around building resilient software programs.
Some systems go a step beyond resiliency and become antifragile. Antifragile things actually gain with disorder (up to a point). Changes are generally frequent and have a small impact. Free market economies are a good example of antifragile systems. Individual businesses are fragile, but the system is strong because the best businesses survive. Evolution is another example of an antifragile system. Individuals of a species can die, but the best adapted animals get to reproduce. This causes the species as a whole to get stronger with volatility.
Other summaries of Antifragile
There are lots of software development practices that captialize on chaos. The key is to use frequent failures as learning expiriences. Here are some examples:
Agile Software Development
Agile processes revolve around building software in tight iterations with frequent customer feedback. Frequent exposure to criticism reduces the impact of criticism. It also allows you to gather more accurate information about what the users want. Additionally, your process continually improves, which means your team becomes more effective over time. This is in contrast to waterfall processes that front-load understanding and are fragile. One mistake in understanding can have a large and painful impact in waterfall projects.
Frequent releases / Continuous Integration
If you do hard things frequently, like releasing software, they become easier. A frequent release cycle breeds processes that make deployment easy and reversible. Continuous integration allows companies like Facebook to push several updates a day. This gives them a huge advantage over slower companies.
The chaos monkey is a process build by engineers at Netflix. It is a program that randomly breaks processes. The introduced chaos allows developers handle problems in a controlled way. It also encourages resilient design in the first place. Contrast this to companies that avoid chaos. Random failures occur at inconvenient times and the fix is likely to consist of bubblegum and duct tape.
Minimum Viable Product
A minimum viable product is a small product used to test the market. Because the product is cheap to build, you can run many iterations. Each iteration allows you to learn more about your potential customers. These experiments allow companies to find profitable products quickly. This process allows smaller companies to exploit market situations that bigger companies cannot.
The world of software development is chaotic. We should not fear the chaos, but instead build systems that capitalize on it. Modern software development practices expect change and use it to create better software. Using these processes, we can build software that isn’t just resilient, but is also antifragile.
If you’re interested in learning more, check out Antifragile