As software developers what is it we’re actually doing every day? Obviously we’re pressing buttons on a rectangular box to make computers do things we want them to do but why is that difficult? And why does it take so long? What we’re actually doing is making choices about where to diverge from defaults. When we diverge from defaults make our code more complex. Complexity makes software harder to maintain and apps harder to use and understand. We can avoid that unnecessary complexity by starting with good defaults and making informed decisions about where to diverge from them.
“Perfect” software is no software at all. No software has no bugs, it doesn’t ever require customer support, it has infinite uptime, it’s infinitely simple and has zero complexity. That doesn’t necessarily mean all apps with fewer features are better then all apps with more features.
DHH wrote a great post about how simplicity isn’t that important. He’s right. Simplicity on its own isn’t valuable so it shouldn’t the be the most imperative objective. Simplicity detracts from other characteristics of great software. Utility: for example. “No software” is not very useful unless the customer can solve their problem without software in the first place. But do realize, any feature you add will increase complexity. Once you add your first line of code you no longer have infinite uptime, your customers will require support (yes, even if it’s one line) and you no longer have an infinitely simple app. That doesn’t mean your app is necessarily worse off. You just have to make sure the trade-off is worth it.
Every time you diverge from a default your app and your code gets more complex. You also risk introducing bugs or confusing your user. Whenever you diverge from a default, ask yourself: “how is this change getting me closer to what I want? Is it solving a problem for my user? Is this communicating something to them? Is it better representing my brand? Does it make the app more enjoyable to use?” If you can’t answer those questions you probably shouldn’t make the change.
One way people make fewer divergences is by starting with a good set of defaults. The better your defaults are the fewer times you’ll have to diverge from them. Bitters gives us a set of reasonable default styles for the apps we build. Clearance provides a good default authentication system. This is also the thought behind the convention over configuration mantra behind Rails. By using a tool like Clearance or Bitters you can deffer the decisions you make to a larger group of people.
These tools make lots of decisions for you. By making one decision you get all the benefits of the decisions made by the tool. Thousands of Rails apps have Clearance installed and many people have contributed to making it better. Unless your apps authentication requirements are particularly unique using an exiting solution will have less bugs and provide a better user experience then building it yourself. If you have good conventions and defaults you can minimize divergence while maximizing value to your user.
Building great software is not just about building lots of features. Building great software is a about building a set of features that are logical, useful, and enjoyable to use. You can learn what those features look like by building something simple, talking to your users, and iterating from there. In the end programming is just another form of communication. The key to effective communication is about saying exactly what you want to say without saying anything more. Programming is no exception.