Search This Blog

Monday, November 22, 2010

Requirements? We don't need no stinkin' requirements

Sometimes, this is true. I’ve written hundreds of programs, sometimes very large ones that took me years to write, without a single line of a requirements document. We only really need requirements documents when one person needs to communicate to another what needs to be built, or to help organize our own work.

Requirements documents can be the bane of a software developers existence. Poorly written, confusing, ambiguous requirements have been the genesis of the demise of many a software project. More than once, I’ve had developers come to me and complain about poor requirements, or complete lack thereof. “How are we supposed to write this software without requirements?” comes the oft-heard mendicant whine. Let’s look at solutions to this dilemma.

Non-Agile approaches to the problem
1. Complain that the requirements stink. Complain that the requirements are missing major pieces, are poorly written, are missing functionality, don’t really address customer needs, and were basically written by idiotic product managers who just don’t understand the technical complexity of the software. Then, stumble along and write code that attempts to meet these requirements in a doomed attempt to make the product manager happy.
2. Give the requirements document back to the product manager with a detailed write-up of what is wrong. Create requirements templates for the product manager to use for future requirements documents. Install processes that strictly formalize the requirements process. Refuse to accept any requirements or specifications unless they are perfect. Teach those product managers not to mess with IT.

This approach often builds an adversarial relationship between development and product management, and usually in environments such as these you see similar adversarial relationships between development and QA, where everyone is so completely focused on adhering to the letter of the requirements and adopting process for process sake that the customer is forgotten.

Agile approaches to the problem
1. Remember three of the four agile principles: value individuals and interactions over processes and tools, working software over comprehensive documentation, customer collaboration over contract negotiation, then
2. Go to the product manager. Ask them to clarify what they wanted. Spend 10-15 minutes drawing workflow diagrams and/or UI on a white board. Take a picture of the white board with your iPhone and send a copy to the product manager. Go write the code.

This approach, besides solving the problem more efficiently, yields some additional benefits. It builds a trust relationship between product management and development. Customers love being asked what they want, and not just handed what you think they want or meant. A mutual learning environment will blossom from this type of relationship, where product managers learn more about how software is built and can be more appreciative of problems when they occur, and developers get a deeper understanding of the customer. It’s win-win.

Ruthlessly applying the lean engineering axe
You might think that the previous example applies lean engineering, but we can go further. Try this scenario: sit down with the customer in front of your computer, and write the code as the customer elucidates what they want moment by moment. Have QA sit with you as you write, checking your unit tests as you go. Sound farfetched? It’s not. This model has been used successfully in agile environments for years. They are “a strong and direct expression of the Lean principles of pull, flow and value" (http://leansoftwareengineering.com/2009/04/07/feature-crews/).

The two approaches outlined above are somewhat idealistic, and reality usually falls somewhere between the two based on a number of factors, including organizational size and trust (more on trust later). We must always be careful not to fall into the trap of installing process for process’ sake, tools because we like new shiny toys, templates and documentation or any artifact because we think it will add customer value. Agile and lean are always trying to remove wasteful processes. Always be examining your customer value stream, and feel free to apply the lean axe when it’s needed.

Monday, May 17, 2010

Technical Debt

What is Technical Debt?

The term "technical debt" describes the obligation that a software development organization incurs when it chooses, knowingly or unknowingly, a design that saves time or money in the short term, but in the long term increases complexity and ends up being more costly. There are two basic kinds of technical debt; intentional and unintentional. The first occurs when an organization makes a conscious decision to optimize for the present rather than the future.

This is not always a bad thing. For strategic reasons, companies often incur technical debt when time to market is critical or to preserve startup capital, preferring to pay for the expense out of later (and hopefully greater) revenue than critical startup resources. Eventually, however, the debt must be paid.

At best, technical debt can be annoying, making maintenance difficult and slowing productivity. At its worst, it can make forward progress impossible and destroy productivity. Steve McConnell acknowledges that “if a company’s technical debt grows large enough, eventually the company will spend more on servicing its debt than it invests in increasing the value of its other assets. A common example is a legacy code base in which so much work goes into keeping a production system running (i.e., ‘servicing the debt’) that there is little time left over to add new capabilities to the system.” (McConnell, 2010) The industry estimates that it spends up 80% of its total cost on software maintenance (Pressman, 1992). We need to understand technical debt better, adopt in only when we have to, avoid it when we can, know it when we have it, and know what to do with it when we have it.

Signs of Debt

There are a number of ways you can tell if your software has developed significant technical debt. Here is a list of things to look for:

1. Large backlog of bugs
2. Fragile code
3. Unmaintainable/uncommented code and/or outdated comments
4. Security issues
5. Missing infrastructure
6. Lack of documentation and standards
7. Over-reliance on tribal knowledge for maintenance
8. Lack of understanding that you have technical debt and/or ignoring it

As the technical debt increases, and the size of the code base increases, it is important to note that the maintainability costs exponentially rise, and eventually reaches critical mass such that the code becomes unmaintainable. Every new line of code may be a potential new mine in a mine field; a ticking time bomb in a brittle code base where layers of technical debt have created ever increasing levels of risk when the source code needs to be touched. And the source code usually does need to be continually touched to meet continuing customer needs.

Fast, Cheap, Good: Pick Two

It’s been said that lowering quality lengthens development time. This is because the burden of the technical debt must eventually be paid off. If you’re a cowboy coder and you simply hack some code out, it may seem like you get the code out sooner, but the technical debt that must be paid off is much greater compared to the senior developer who creates a full set of unit tests, good designs, and code that is fully performant, secure, reliable, and maintainable from the start. Boehm (2000) discovered that as software proceeds through the life cycle it becomes progressively more expensive to change. Software does not get better over time; it gets worse - unless you actively take steps to fight the decay. In a word, software rots.

Unfortunately, many have interpreted this inflating cost curve to mean that you must produce perfect requirements, followed by perfect specifications, followed by perfect designs, etc. This is not what Boehm’s work suggests. Rather, the software base must be kept resilient and maintainable to keep it prepared for any further customer changes. Code bases begin to accrue technical debt when they are “moved into maintenance” and stop being refactored by the development team as new features are added and bugs are fixed. Refactoring is the process of restructuring an existing body of software without changing its external behavior for the purpose of improving readability, maintainability or to reduce complexity. Refactoring and unit testing are a primary means of fighting software rot.

Once you recognize that you have technical debt and that you have been accruing it, have a transparent discussion with your business owners about the costs of the technical debt. Chances are they may already be aware of it, at least indirectly, by recognizing the signs I’ve listed above. Make sure they understand what the technical debt of the code base is costing the business. They may have unrealistic expectations from software developers working on a legacy codebase. Other teams may be able to develop new features faster (or will be able to develop new features at all), and this may be frustrating to them. Part of this buy-in will be to develop some long-range thinking on the part of the business owners. This type of development is an investment that will yield dividends in the form of higher productivity and higher quality.

Paying off your technical debt

In order to pay your technical debt off you must first understand it. Where is your technical debt occurring, and how is it affecting your business? Do you have high maintainability costs? Look at your bug regression rates. Look at your backlog of bugs. Look at your code metrics. Do you have security issues? Do STRIDE-based security threat modeling on your application to understand potential security threats. Do you have adequate technical documentation and artifacts with respect to the product architecture? Do you have adequate unit tests in place before you start refactoring the code base? You need to list out your technical debt and make it durable by placing it in a permanent, visible location, like a team SharePoint site.

One thing developers love to do is to throw the old code out and start from scratch. I will agree with Joel Spolsky (2010) on this point and suggest that this is almost always a stupid idea. Legacy code may be hard to read, poorly architected, and full of bugs, but it’s been used, tested, and contains a great deal of real-world domain knowledge, bug-fixes and market leadership that will be discarded if you start from scratch. Better to iterate and refactor.

After understanding the nature of the technical debt you have, you need to build a business case with the entire team, including the product owners, on paying down the technical debt. Like most debt, you won’t be able to pay it all off at once, but a little at a time. After you have buy-in from all stakeholders, allocate a small portion of each sprint and pay off the most profitable debt items first. As long as you are paying down more debt than you are accruing, you will be incrementally improving quality and decreasing risk.

Working off technical debt can be a great way to boost team morale. If your Product Owners can be convinced to surface product backlog items dedicated to retiring technical debt, or even devoting entire sprints to the effort, measurable performance and quality improvements can be made which can be highly motivational for the entire team. These improvements will inevitably show up in improved customer satisfaction ratings as well.

References

Boehm, B. (2000). Software Cost Estimation with COCOMO II. New Jersey: Prentice Hall.

McConnell, S. (2010). 10x Software Development. Retrieved May 17, 2010 from http://blogs.construx.com/blogs/stevemcc/archive/2007/11/01/technical-debt-2.aspx.

Pressman, R., (1992). Software Engineering: A Practitioner's Approach. New York: McGraw-Hill.

Spolsky, J. (2010). Things you should never do, Part I. Retrieved May 17, 2010 from http://www.joelonsoftware.com/articles/fog0000000069.html.

Thursday, April 22, 2010

Hansei and Kaizen in the Second Quadrant

Last Friday night, Ben, Pete and I were having drinks, and Ben mused that we needed to do a better job of training for our software applications. “Perhaps better training videos are the solution,” he mused, sipping from his coke. Ben was demonstrating Hansei. He often does this when we are out drinking, much to the annoyance of Pete and I, who were just trying to enjoy each other’s company and drink.

Addicted to the First Quadrant

I thought deeply about Ben’s statement. Often – too often, I believe – we operate in a hurry-up, get-it-done, meet-the-deadline, schedule-driven environment and don’t allocate enough time to do the things that might actually prevent us from have to spend time in that environment in the first place. Don’t get me wrong; it’s an addictive, adrenaline and caffeine fueled world, filled with excitement, and at the end of the day it leaves you feeling like you got a lot done. But all too often, getting caught up in the rush of fast-paced delivery leads to an environment of poor quality software, unhappy customers, broken relationships and a myriad of other problems that stem from poor planning, lost opportunities and lack of preventative measures. What can be done? What do these Japanese words mean anyway, and what is Dave getting at with quadrants?

The 14th Principle

Hansei is a Japanese word which means “relentless reflection.” It is a central idea in Japanese culture, and it is about acknowledging one’s own faults and always trying to correct them. Kaizen means “continuous improvement,” and practiced together they help to build a learning organization. This is the 14th of as many principles of management practiced at Toyota. We practice a little hansei and kaizen already in our software development today. We have a sprint retrospective where examine how we can improve our processes, and we have a built-in improvement step in the inspection process as well. I have seen this at work in the few months since it has been installed. All of the teams have already been getting incrementally better at estimating and scheduling their work, and measurably improving their quality. I want to acknowledge that improvement that the teams have made here. It’s good, but there is still a lot of room for progress.

The Second Quadrant

Stephen Covey, one of my favorite authors, classifies tasks in four quadrants:


The first quadrant contains those that are both urgent and important. Fighting fires and crisis management are examples of first quadrant activities. The second quadrant contains tasks that are important, but not urgent: planning and relationship building are examples of quadrant two activities. How much of your day is spent in these two quadrants? Do you balance them appropriately? (If you’re spending any time at all in quadrants three or four, you’re probably wasting your time).

One of the problems with operating in the first quadrant is that it’s addicting. It’s very satisfying to go to work day after day and solve a seemingly endless wave of problems. You look like an aggressive problem solver; someone willing to take on difficult situations and get the job done; a “can-do” person. Unfortunately, it is not the best way to deal with the situation, as it usually leads to the same thing happening over and over again (well, at least you have some job security). A better approach is to find and eliminate the root cause. This will drive first quadrant activities into the second quadrant, and bring some sanity to the workplace.

Fix it Once

Kiichiro Toyoda said that every defect is a treasure – but only if the root cause of the defect can be found and corrected across the company so that it does not occur again. The Toyota Company empowers every employee to completely shut the production line down when a defect is found in order to discover the root cause of the defect and prevent it from re-occurring. This is a very powerful paradigm, and in part has led to the highest quality automobiles in the world. Do you feel that way? When you see a problem, do you feel empowered to stop what you’re doing and make the changes necessary so that the problem never happens again? Why not? Wouldn’t that be adding real value to the company? Sun Tzu’s wit is not lost on us when he said, “When trouble is solved before it forms, who calls that clever?” Yet the best employees are those that do exactly that.

It will be interesting to observe Ben as he practices hansei and kaizen in the second quadrant and solves the training issue. I suggested he work with Dave Skender and work to install these pieces as potential deliverables within the MedAssurant Agile Process. These Work Products will need Owners, will belong to a Discipline, and be assigned to a phase of the Process.

More to the point, it will be interesting to watch each and every one on the team as you practice hansei and kaizen in the second quadrant and solve problems before they turn into fires. Franklin was right when he said “an ounce of prevention is worth a pound of cure.” We must, each and every one of us, practice hansei and kaizen in the time that we have, in the place that we are. That, or inevitably be consumed by the unquenchable fire of the first quadrant.

Monday, April 19, 2010

Why Traditional Software Planning Fails

Mike Cohn, founding member of the Agile Alliance, eloquently describes the main reasons that software projects have failed (Cohn, 2006). Here are a few of the main ones:

Lateness is passed down the schedule – traditional software planning processes focus on the dependencies between activities. As a result, best case is that everything finishes on time, but because of dependencies, a slip in any one activity is sure to cause a slip in the entire schedule. What is worse, such slippages are not simply additive. Lateness on one task may ripple over to many other dependent tasks, making all of them late, multiplying the lateness by a factor of the number of dependencies in the system.

We ignore uncertainty – traditional software planning fails because it assumes initial requirements can lead to a perfect and complete specification, and that all unknowns can become knowable at the start of a project. It fails to take into account that customers may change their minds, come up with new requirements, or change requirements during the course of a project. The old school assumes that manufacturing methods can be applied to software development; but studies by the Standish Group (1995, 1998) and others conclusively show these methods don’t work, no matter how rigorously they are applied. Usually we are implementing a new idea or design, which has unknowns and risks, but we need to achieve exacting quality. It’s common sense: we don’t have perfect information, so expecting the perfect estimate or the perfect schedule is silly (I am quoting Eric Brechner, author of “Hard Code,” and Development Manager of Microsoft Office). It is an ill plan that cannot be changed.

Estimations become commitments – when we give an estimate for the completion of any task, implicit in that estimate is a probability of completing that estimate in that time. Armour (2002) points out that every estimate is a probability; but you cannot make commitments to probabilities. You make commitments to dates. Before making a commitment to a date, software teams must be given the chance to use solid estimation techniques such as wide band Delphi estimation to uncover assumptions and risks associated with a project, and develop risk management plans to define how the teams will handle change when (not if) it occurs in their projects (PMI, 2004). These risk management plans must be approved by senior management; otherwise teams are just signing up for failure.

Plans and Planning

Planning is a critical step in any undertaking. We want the problem to be understood as well as conditions allow, and to uncover as many assumptions as early as possible. Why do estimates often fail us for engineering projects, particularly software development? They fail because software engineering is a design activity, not a manufacturing one. There is a common sense understanding of the difference between plans and planning:

A good plan, violently executed now, is better than a perfect plan next week. - Patton
In preparing for battle I have always found that plans are useless, but planning is indispensable. – Eisenhower

No battle plan survives contact with the enemy – Colin Powell

Did you notice the quotes above are from military men? Software teams are equally at war, but it is a mistake to think they are at war with customers, the operational staff, or executive management. They’re not. They (and the customers, operational staff and executive management) are together at war with uncertainty. Agile project planning is all about recognizing that uncertainty exists, minimizing that uncertainty as much as possible, and installing tools and processes that manage that uncertainty and risk within the framework of the business goals and objectives.

Doing it better

In environments that change very slowly, traditional project management methods focus on a full understanding of the product through careful analysis and planning. Before any significant investment is made, the uncertainty is therefore reduced to a level where risk can be comfortably managed.

However, when business and technical requirements change rapidly, often because the business is continually redefined, this full understanding is impossible to achieve. Planning is critical, yet we must be cautious about what we do with the results of our planning phase, and be careful not to fall into the trap of believing we can have perfect estimation and perfect scheduling at the beginning of a project. There will always be a lot of variability in project scope at the beginning of a project, and there will always be change throughout the life cycle of the product. Turing award winners Barry Boehm, Kristen Nygaard, Ole-Johan Dahl, and Peter Naur have all espoused and developed these agile development ideas. We ignore their research at our peril.

Software is not a unique industry in having high uncertainty at the beginning; what other industries do is constantly reiterate and re-plan. They don’t make a big up-front plan and treat it as inviolate. Estimation is a tough but important problem, and we need to be thoughtful about doing it better, as long as we don’t confuse valuable planning with a rigid and brittle plan, or estimates with commitments.

Armour, Phillip. (2002). Ten Unmyths of Project Estimation. Communications of the ACM 45, no. 11155-18.

Brechner, Eric. (2008). Hard Code. Redmond: Microsoft Press.

Cohn, Mike. (2006). Agile Estimating and Planning. Upper Saddle River, NJ: Pearson Education, Inc.

PMI. (2004). A Guide to the Project Management Body of Knowledge, 3rd Ed. Newtown Square: Project Management Institute.

Standish Group International. (1994). The Chaos Report. The Standish Group.

Flexing Iron Triangles

Any Project Manager will be able to quote to you the three vertices of the famous “iron triangle” of project management: Scope, Resources, and Schedule. Every project is a combination of these three elements:

• Scope: What we’re going to do
• Resources: How much money we have to spend to get it done
• Schedule: How much time we have to get it done

I’ve had managers who jokingly said that they want everything yesterday for free. Usually when a manager says this, or a variation of this, they are usually really asking me for options on scope, on resources, or about the schedule. Sometimes these are variable and sometimes they’re not. I need to ask the manager precision questions around the business need for the deliverable to get the right answers and move the levers of the triangle appropriately. What features do you really need? Who is the customer? What is the venue? Who is the presenter? When is the presentation? How many will be present? Sometimes you can narrow the use cases down to a scope that can be accomplished in a given timeframe in this way. When managers become intransigent around these questions, that’s usually a sign you have a bad manager, or you aren’t asking the questions very well.

The idea is that you can often fix any two of the vertexes. For example, if you have a fixed set of resources and fixed cost, your schedule is going to vary; or, you can reduce the number of features in a product to get it done in a given timeframe. A key takeaway of the iron triangle is that you cannot fix all three sides. Such a system becomes over-constrained.

In software development organizations, over-constraining the iron triangle is very common. Something, however, must give. When a software development effort is over constrained, the usual result is:
• High bug rates
• Low morale
• Late schedules
• Cut features
• Failure to adopt new technologies
• Low productivity

What gives is obvious: quality. We have metrics already within our own organization to prove this. We have high inspection yields and high bug densities in our software, which indicates if we spent a little extra time checking our work, our quality would dramatically improve. We can correct this by injecting quality processes as standard operating procedures and setting expectations that this will be the way we will work from this point forward. We will be doing inspections. We will be writing unit tests. We will be doing peer reviews. Code will not be checked in until it passes all of the StyleCop and FXcop rules we put in place. Etc., etc. Software development will appear to slow down, but quality will go up. This is about setting expectations and pushing quality upstream. When doing your estimates, remember wide-band delphi estimation is about uncovering assumptions: did you include testing in your assumptions? Stress testing? Performance testing? Inspections? These are things software engineers do. Coders don't.