At Three Pillar, we are passionate advocates of the Product Mindset. We’ve been using the term for quite some time, but it may not be clear right away what it really means. In this article I will focus on the technical aspects of keeping the Product Mindset throughout the life of the software solution.
Understand the difference
The key to understanding the Product Mindset begins with understanding that a software solution not only has to work and support business processes on day 0 of operation, but also to grow and evolve as the business does. In another words, one has to keep in mind that the software will need to live on, long after the original developer is gone. This means that today and every day forward the code the development team produces should be cohesive, loosely coupled, testable and above all maintainable, even as the solution grows in size and scale. In another words, every component of the application needs to be able to adapt to ever-changing business needs. That is not all, the software needs to be a self-funding, revenue or value generating product as early as possible. These requirements are often hard to achieve in practice, but I will try to describe some of the ways the above needs can be met easier with some moderate technical discipline. Before we dive into the technical details, however, there are a few very important aspects to discuss, which are essential to be addressed before a single line of code is committed.
Build a partnership
Start with understanding your client, their business and their needs. As a consultant, one has to form a partnership and establish collaboration with your client. Note that even if you work internally for your company, you provide valuable service to the business, much like a consultant. The key goal is to build a relationship based on mutual trust and understanding. Making tough decisions down the road in this atmosphere will be far less of a challenge. As you begin to form this partnership, you have to lay out some ground rules – a framework for interaction between the business and technology organization. This is where some of the popular Agile methods come very handy.
Take the Scrum approach for example. One of the key actors in Scrum is the Product Manager. This individual is the single-point gate-keeper and mediator between business needs and the development team capabilities. Therefore this person is extremely critical in the process, and should be someone who understands both what the development team can do, what business needs and above all be deeply invested in the success of the product. Another key aspect of any Agile method is an iterative approach. This means that large requirements are broken down into smaller ones, which fit within an the iteration (aka Sprint) window. At the end of each iteration, the business receives a working piece of software. As time goes by, this iterative approach will help building trust and foster collaboration between business stakeholders and technology team. This doesn’t happen over night and usually takes a few iterations for both sides to get used to.
There are also some ground rules for developers as well, that Scrum does not cover. There needs to be a person (or more than one depending on team size), who can establish, enforce and evolve these rules. This role is typically filled by the architect or technical lead, who often is one and the same person on small teams. The purpose of a technical leader (or gate keeper), is to maintain day-to-day order in the code base, and also look out to the future and plan for what may come. So, what are these rules?
Establish your team and roles
As a leader, one must establish good rapport with developers, empower them to innovate and collaborate. One must reward good performance, act quickly and decisively to address both personnel and technical issues. If a member pulls the team down, one should not hesitate to replace them. In an environment where every team member is an independent contractor, this may be impossible, unless the team lead is a member of the client organization. Things get much easier when a technical lead AND all of their developers belong to the same organization. In such cases it is also less likely that any personnel issues would ever occur, since it is more likely that there is a good sense of cohesion in the team, prior to the start of any work.
Organize planning, development and testing
Use a planning and defect management tool (e.g.: JIRA + Greenhopper). Establish workflow and processes regarding stories, tasks, defects, etc. Communicate these with your team and business users. Work with the client to identify the best tool, which client (and their internal policies) will accept. A good tool can help elicit and capture early feedback from testers and users, which in turn is essential to keeping a pulse on the client’s business needs.
Enforce code quality
Code quality means a lot of things. The key is to promote the idea that the code written today should be easy to read and understood by other developers now, several months or even years into the future. It is common for developers to forget how and why they developed something even after a month or two. Employing design reviews with an architect, a tech lead or a senior developer will help steer clear of structural and/or performance issues in the future. Pair programming and peer code reviews can greatly help improve maintainability and will help less senior team members to grow their skills. Below are some other tips to keep the code from becoming unmaintainable:
Being consistent and clear when using design patterns (and use the right ones in right places) can prevent many headaches in the future.
Writing many small, cohesive and loosely coupled objects (i.e. POJOs), rather than large “multi-tasking” giants will produce code, which is understandable and easy to unit test.
Making it a habit to document code “as you go” will greatly reduce the amount of technical debt your team incurs each iteration. This can be in-line or JavaDoc style comments. Many developers note changes to the code by including a bug tracker number in the comments.
Selecting one IDE and sticking with it will make tasks such as enforcing code style and formatting much less complicated. Many open source projects provide code style and formatting templates in order to preserve uniformity across the code. The team’s preference and tech leads good judgment should be a good guide in making the choice.
Using popular, standards based build tools (i.e. Maven) will save you a great deal of frustration when it comes to continuous integration, deployment and other configuration management activities.
The mention of testing is in many of the above points, not without reason. Testing early, testing often and testing almost fanatically limit the risk of costly defect down the road. In fact, testing is so important that many developers advise developing tests, prior to implementing the logic. Regardless of approach the key is to cover all requirements in a unit test. Unit testing, however is not enough. Using automated integration and functional test tools (i.e. Spring Context Test, Arquilian, Selenium) can save you plenty of time and ensure that many bugs were prevented or were detected early, before the users get to test the live application.
Minimize technical debt
Technical debt – aka the “brown cloud” – consists of all the things developers would defer in order to devote more time to push features out. This includes re-factoring and redesigning existing code, adequate testing and in-code documentation. There is no golden rule for avoiding this debt, but there are some approaches that work well to reduce it. Some teams include the technical debt in the definition of “done”, that mandates each feature to be well tested and documented (well defined ground rules for development may greatly help here); this however reduces the initial project velocity, which may cause your client to be less satisfied. Others keep a backlog of technical debt and pause feature development for one iteration to concentrate on reducing the debt. This could be done on a regular basis, or as needed. It is up to the development team and the business to identify which or what combination of both) is the right choice.
Maintain course, stay flexible, adapt
Maintaining agility over time is critical to delivering the promise of the Product Mindset in practice. It is not an easy or straight-forward endeavor. Every day there are many distractions coming from many different sources. That is why it is essential to have the right technical, leadership, and product management talent involved in software development activities, though it is equally as important to keep these individuals communicating, collaborating and working as a team. Strong teams are extremely effective in consistently delivering successful software, but it takes time for teams to mesh, building the cohesion and discipline that spell success.