Principle #2: Effectiveness
Build the Right Thing
In Part 1 of my blog series on Four Principles of Software Development, I proposed the P.E.E.R. acronym (People, Effectiveness, Efficiency, and Relevancy) to describe four principles that set a senior developer apart and define how software ought to be done. The second of these ideas is the idea of effectiveness. I want to highlight the difference between effectiveness and efficiency. I think it is best summed up in a famous quote by Peter Drucker who said:
“Efficiency is doing things right; effectiveness is doing the right things.”
I think there are three major components to building software effectively:
- Understanding the problem you’re trying to solve
- Understanding the solution you’re trying to build
- Measuring the success of your solution
Understanding the problem you’re trying to solve
Many developers jump into a team and first try to learn the code base in terms of the coding conventions, the technologies, and the frameworks. But more important than this, developers must have a really good understanding of the problem they are trying to solve. By this, I mean the reason why they have a job in the first place. You can produce something technically excellent, but if it doesn’t solve the problem at hand, it’s all but worthless. Before even starting to think about technical excellence, you first have to make sure you fully understand the problem and your purpose.
In his book, Domain-Driven Design: Tackling Complexity in the Heart of Software, (often referred to by developers simply as The Big Blue Book), Eric Evans stresses the importance of domain knowledge throughout the entire development team and refers to the business domain as the “Heart of Software”.
One of my favorite ideas from The Big Blue Book is Evans’ concept of ubiquitous language (UL). He defines UL as a common vocabulary used among everybody involved in the project including developers, sales, support, etc. Suppose a sales team has a concept of “registering a client”. To follow the principle of UL, the code should reflect this using the same shared vocabulary and contain a method such as “registerClient” and not “createUser”. This simple technique can have a very inclusive effect. It can foster collaboration between developers and the rest of the business while minimizing the mental effort involved with context switching and mapping between different vocabularies.
Furthermore, developers need to be familiar with the business aspects of what they’re building. They need to have at least a rudimentary understanding of how their team affects the bottom line in terms of both costs and revenue. When making big decisions like when and how many developers to hire, what deadlines to chase, or what risks to take on, the input of developers on the team with a good sense of the business is going to be invaluable.
Understanding the solution you’re trying to build
Understanding the solution you’re trying to build is often harder than it looks at first glance. I would have a sizable sum of cash if I had a dollar for every time well-meaning and hard-working developers delivered something that didn’t meet stakeholder expectations. Gathering requirements for a project is of paramount importance and can’t be rushed. When gathering requirements it is important to always talk in terms of the problem space rather than the solution space.
Udi Dahan, an expert on service-oriented architecture and creator of NServiceBus, stresses the importance of this in one of his training courses. He describes a scenario where a developer is gathering requirements for a new feature. The business analyst describes a feature that they would like built. They describe in great detail how it should work. On the surface, this might seem pretty normal, but Udi stresses the importance of getting the business analyst to rephrase this out of the solution space and into the problem space. That is, instead of asking for a specific feature, the business analyst should instead describe the problem they are having. Not only should they describe the problem, but ideally they should describe the amount of effort it takes them to solve the problem now as well as the potential savings or earnings that a better solution could achieve. Talking in the problem space can unlock innovation. Presumably, you have some really smart technical people on your team and if you give them a problem, there is a lot more room for innovation and creativity than if you gave them a solution.
Measuring the success of your solution
Once you have a deep understanding of both the problem and the solution, it is vitally important to measure the success of your solution. To avoid the all too common Texas Sharpshooter Fallacy, you should have clear goals and objectives defined before you even start building software. Measuring success can include many different things for different software. Some examples are analytics data, user testing, customer acquisition, customer satisfaction, NPS scores, etc. The important thing is that developers and the stakeholders all agree on what is important and what will be measured.
One of my favorite examples of this is the story of Dan Siroker, CEO of Optimizely, who joined the 2008 Obama presidential campaign. As director of analytics, he implemented A/B testing to help raise an additional $60 million in website campaign contributions by doing things as simple as changing photos and button text on the campaign website. He credits his success to challenging assumptions, experimenting, and constantly measuring success. For more information see Dan Siroker’s blog post.