My code is well written, unit tested, refactored, and well documented. It has passed all the test scenarios and does what it was supposed to do. Does that make it into a great product? Not necessarily. If it doesn't meet the market expectation and if it isn't valued and used by the end users, it's a waste.
One of the biggest wastes we produce is "unused or outdated features." Various research has shown that far too much money and effort are spent on building something that is never or rarely used by customers and end users.
Even with Agile projects, if we don't focus on "building the right thing," we may end up in the same boat I described above.
How do we ensure that great code results in a great product? Here are some of the practices we have followed in our project teams (at the team level) to make sure this happens:
It starts with a vision. How many of our teams are aware of the project vision and goal, or do they simply jump into the code based on the specifications provided? If teams are involved in drafting the project vision and are aligned with it, it gives them a bird's-eye view of the project, and they feel empowered. One of the good tools I have come across is using Business Model Canvas
. It's a great visual tool that aligns with business and helps provide a common understanding of the vision within your team. Create a poster-size version, print it, and keep it your team room.
We use release planning meetings to discuss and align project vision with the team. Another great way of creating a vision statement is using Simon Sinek's Golden Circle
(starting with "why" and then moving on to "how" and "what").
The Agile Manifestos says, "Individuals and interactions over processes and tools." The more we discuss and communicate with business and users, the better our understanding of product. Frequent conversations are one of the key elements of "building the right thing."
The role of the product owner is an important link between business and IT
Development teams need to build empathy for the customer, sit in customer's chair to understand their need or pain. The PO should help develop that understanding and bridge the gap.
While interactions and discussions at the start of the release are important, equally important is to have it as an ongoing practice. We use "backlog refinement sessions" for this purpose. Product backlog refinement is done throughout the project, during each sprint. As part of this timeboxed meeting, the team and the product owner go through the backlog and discuss top-priority PBIs one by one until the timebox ends.
As we discuss the features and stories, one of my favorite sections is defining acceptance criteria
. We use the following format to capture acceptance criteria:
[event causing change]
[another event causing change],
[another expected result].
In our case, we use Cucumber
to automate the acceptance test cases and capture acceptance criteria in the above format, which helps the developers when they start automating test cases. This mechanism ensures that developers and business are always aligned and running toward the same goal (building the right product).
Frequent releases are not
the same as delivering working software at the end of each sprint. We may be delivering working features sprint-on-sprint, but do they make it to production every sprint?
As we deliver working software in each sprint, we should aim for frequent releases to market. Based on my experience, I have observed that though teams develop working code frequently, it's not released to market frequently. We have our own release timelines, and we are restricted by organizational boundaries. This approach means you don't get real-time feedback of the feature you have completed. To me, something that is ready to go to production but still sitting in the developer's box is a waste.
Incorporating learning from frequent releases is the key to building a great product. Release it to the users, learn from their feedback, and realign your vision/strategy. Once we start following this cycle, we embark on a journey where we steer ourselves toward the truth that "great code results in a great product."