Showing posts with label Technical Debt. Show all posts
Showing posts with label Technical Debt. Show all posts

Sunday, August 23, 2015

Technical Debt and refactoring



Do not refactor for sake of paying Technical debt.  Refactor the code if it has business value. Hidden message: Do not pay Technical debt if it does not enhance value of software.

Perfection is mirage. Good enough is good.

Saturday, August 22, 2015

Every day indicators of Technical debt

  • Let’s complete testing in next sprint.
  • Lot of “To Do” and “Fix Me” in code.
  • Only Sonia should touch this code.
  • Just copy paste this code.
  • In which class we store password.
  • Unit test cases !! are you joking.
  • Do not worry about documentation for now.
  • I can this in two minutes.
  • It is OK for now. We will refactor later.
  • Let’s do this way, it is faster to do. We will change it later.
  • We cannot implement this feature in current technology of product.
  • The velocity of team is deteriorating without change in team composition or technology shift.
  • Old versions of libraries in use.
  • Frequent problems in production.
  • Known bugs
  • Never say no to features
  • Project in IDE has lot of warnings.
  • At run time we get this warning
  • Our Ops guys are so good, they can make anything work
  • We have always done this way
  • Coding guidelines!! Forget for now.
  • If we release by this Friday, approximately number of 20 bugs will be there. If you can wait till next week bugs will be 5.

Friday, August 21, 2015

Technical and Financial Debt



Most of us are familiar with Financial Debt. Let’s try to draw analogy for Technical Debt from Financial Debt.

Short-term Debt
In financial domain, short-term debt is used to finance temporary cash flow like financing of raw material for an order. As name suggest, it is expected that short term debt will be paid back on priority, generally short-term debt is expensive.

In technical domain equivalent short-term debt is debt assumed to ship code to meet deadline with known bugs, having understanding that immediately patch will released to fix the bug. Second example is hot fix for a P1 issue.  In all of cases, focus is – let’s ship/fix the code NOW, resolve the issues in immediate future.

Long-term Debt
In financial domain, long-term debt is used to finance long term goals of enterprise, generally investments like acquiring plant and machinery, acquiring competitor, etc. Generally long-term debt is cheaper to service. Long-term debts are assumed for strategic reasons.

In technical domain equivalent debt is writing a code which is UNIX specific as most of the prospects are on UNIX. It is possible that long-term debt is camouflaged as strategic architectural/design decision. When long-term debt is camouflaged as strategic architectural/design decision, never paid but does not mean it is free. There might be some opportunity cost associated with it as never approached market segment.

Interest Payment
There is no free lunch. Once you assume debt, you need to pay back it with premium. As a business and/or technical person, you need to decide, can you afford the interest and absolute amount of outgoing benefits. 

Technical debt can be pay backed regularly (with each sprint), in spurts (with each release), in one shot (bug fix release). You may also decide not to pay debt at all in case of end of life products.

Expected Cost/Value
If you purchase a car now, you may commute farther for job, so potentially earn $2,000 extra each month. The car price is $10,000. If you delay purchase of car, you may not have promised job. Are you willing to assume debt to purchase car?

If you do not release product now (before FIFA cup), no one will buy it. Are you willing to cut corners to meet the deadlines?

Opportunity Cost
What else can be done with this money/resources? Instead of following the strict coding guidelines, can I cut corners and release the product early and utilize saved (?) resources to release new features?

Present Value
Your startup needs this particular sale now even with lower margin.  Present value of debt is function of Expected value and \opportunity cost.

Debt Service Coverage Ratio
Debt service coverage ratio (DSCR) is the ratio of cash available for debt servicing to interest, principal and lease payments.

In Technical debt realm, DSCR may be defined as ration of resources available to develop software to resources spent to service technical debt.

Credit Rating
Credit rating of any individual or business depicts confidence of market in paying back the debt. 

In software development domain, credit rating of a team or product symbolizes the capacity of accruing/acquiring new technical debt.  Team/Product having less technical debt and specifically less unintentional technical debt has capacity to acquire more technical debt.

Acquired debt
A team may be very careful in assuming technical debt. But say due to product acquisition or bug in library used, team gets technical debt.

Minimum sprint payment
Team may decide to pay back technical debt in regular sprint cycle to manage total debt in reasonable limits. This is achieved by choosing debt paying stories in each sprint.

30 days, same as cash
Sometime paying debt immediately does not result in any interest. For example, in few initial sprints, there is no continuous integration.

Retiring Debt
Unlike financial debt, when a product is retired, all technical debt also retires. You do not pay it J

As product reaches end of life, cost to pay technical debt may not be justifiable.

Parting Notes
Unlike Financial debt, you may not pay back technical debt. In some cases paying back technical debt may not have any technical & financial justification. For example Technical debt in case of:

·         product is reaching at end of life
·         part of code which is not evolving/changing 

need not to be paid.  Therefore, In case of Technical debt probability should also be a factor while paying it back.

Thursday, August 20, 2015

Technical Debt – Business & Technical point of views



Business and Technical folks view Technical Debt from different perspective.  Business folks associated with a project view Technical debt as tool to:

  • shorten the go to market time
  • preserve the startup capital
  • minimizing upfront development expense


Technical folks, view Technical debt from entirely different perspective.

  • Ignorance of dev team
  • Doing under engineering to avoid over engineering
  • Surrender to business pressure



What do you think?

Wednesday, August 19, 2015

Technical debt - How to pay?



Like tax and death in life, no team can avoid technical debt in software development. Therefore we need means to manage it. To manage technical debt three broad strategies are used:

  • Buffer stories
  • Buffer tasks
  • Technical debt paying releases

Buffer stories
Team can set aside approx. 10% of velocity per release for technical debt paying stories. This will set the expectation of business stakeholders in each sprint and help to maintain relatively technical debt free software.  These stories are created by dev team. If story is focused on function debt, let PO drive it.

Buffer tasks
During task break down (in Sprint planning meeting), if required, technical debt paying buffer task is created and budgeted. This approach ensures ease in scheduling but also raises the risk of spending resources on not so important things.

Technical debt paying releases
Instead of paying a little in each sprint, team may decide to devote larger chunk of resources periodically (generally every 6 month). This approach is works well where sprints are going on for multiple years. In this approach a risk of mounting debt always lingers on. Team should avoid Technical debt paying release just after a frenzied, time-critical and feature heavy release.

I am sure there are more ways to pay back debt.  I like to hear from you more.

Friday, May 29, 2015

Risk Management & Agile Debt (Technical & Functional Debt)

To contain risk, there are four types of responses are possible:
  • Mitigate;
  • Avoid;
  • Contain; &
  • Evade.
Each of these responses has high probability of assuming Agile Debt (Technical as well as Functional Debts).  While managing risk in any project, Scrum Team as well as stakeholders should be aware that risk response most likely result in some debt. As a good citizen, also have plan to pay debt.

Thursday, May 28, 2015

Agile Debt – Functional Debt and Technical Debt

In Agile, we talk about Technical Debt, but what about debt with respect to functionality.
Let’s build few scenarios.
  1. Team is building a product sprint by sprint at startup.  Sales team rope in a marquee prospect which demands a feature which is not in product vision (at least at this point of time).  Startup needs this customer to survive. Higher Management makes a decision to incorporate the feature demanded by this prospect with understanding that in future versions, this feature will not be present or this feature will not be sold to any other customer.  Is there any technical debt?
  2. In a well-established enterprise team is developing an application for internal use. This application will be replacing existing application. The existing application supports some processes which soon to be obsolete but will be required in application in development. Is there any technical debt?
Certainly there is no technical debt involve in these scenarios but a debt. I prefer to call it Functional Debt.

“Functional Debt is type of Agile Debt which has its origin in functional aspects of the product.  Functional Debt has nothing to do with technical aspects of the product.”

Here, I also introduced a new umbrella term, Agile Debt.

“Agile Debt is a debt taken by product to fulfill immediate need (by choice or by ignorance) under Agile methodology.”

I hope, this little explanation on Agile Debt will be helpful.

Monday, April 6, 2015

TechnicalDebt

TechnicalDebt
Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite... The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise."
— Ward Cunningham, 1992
A “debt” means that you traded acquiring something now for a long-term financial burden. This burden is not just about repaying principal but “interest” as well. Most of the time interest is not simple but compound. It means that, even if you pay your debt timely, you’ll pay more than you took, and if you don’t, your debt will keep increasing. And if you ignore a debt long enough, it will become unpayable and you’ll “bankrupt”.

TechnicalDebt is a metaphor referring to the consequences of poor system design, architecture and/or software development process within codebase. TechnicalDebt includes those internal things that a DevTeam chooses not to do now, but which will impede future development and/or maintenance if left undone.  TechnicalDebt doesn’t include deferred functionality, except when corner cases are left for future.


TechnicalDebt happens when you “buy” more software features than you have resources (Dev team’s time).

Despite the populist feelings against the credit system, epitomized in The Merchant of Venice by Shakespeare’s character Shylock, debt is a good thing.  In any vibrant and growing society possibility of credit drive business, innovation and trade.  With credit you can buy a machine to start producing something and then pay for the machine.
Similarly in software, you need to survive first to grow in future.  In most of the cases you cannot cease flow of immediate money in favor of future money. TechnicalDebt is inevitable in any vibrant, evolving and growing software. Manage TechnicalDebt as you cannot make it ZERO.
Kinds of TechnicalDebt
TechnicalDebt can be classified on two criteria:

  • Intention
  • Unintentional: Careless mistakes, bad judgements
  • Intentional: After due consideration
  • Short term: A new logo wants it now.
  • Long Term: Let’s choose technology X as most of our potential customers are using it.
As you might have guesses by now, only intentional debt is good debt. If code has unintentional debt, you need to introduce technical talent in your team and/or educate your stakeholders.
  • Origin
  • Internal: All TechnicalDebts are not is self-incurred.  Business pressure will force you to take short cuts, putting you in debt. If you do not start paying back soon and regularly, project will be in mess sooner than you think.
  • External: Today, you got a call from Network Security team and they want to apply a patch to all boxes to plug a recently discovered security hole.  All of sudden, you are in debt, through no fault of yours.
Causes

Common causes of TechnicalDebt include:

  • Business pressures: Business considers getting something released sooner, even before all of the non-functional changes are complete, it builds up TechnicalDebt comprising of those internal uncompleted changes.
  • Lack of process or understanding, where businesses are oblivious to the concept of TechnicalDebt, and make decisions without considering the implications.
  • Lack of Technical expertise
    • Lack of knowledge, when the DevTeam simply doesn't know how to create an elegant design or write graceful code.
    • Lack of building loosely coupled components, where functions are not modular, the software is not flexible enough to adapt to changes in business needs.
    • Lack of alignment to standards, where industry standards, frameworks, technologies are ignored. Eventually, integration with standards will be implemented, doing sooner will cost less (similar to 'delayed refactoring').
    • Lack of coding guidelines, where each member of DevTeam is following its own coding guidelines, which will make integration and automatic debugging nearly impossible.
  • Lack of automation
    • Lack of comprehensive test suite, which encourages quick and risky band-aids to fix bugs.
    • Lack of automated code generation for boiler plate
    • Lack of continuous integration
    • Lack of automated deployment
    • Lack of automated code analysis
  • Lack of documentation, where code is created without necessary supporting documentation. That work to create the supporting documentation represents a debt that must be paid.
  • Lack of collaboration, where knowledge isn't shared around the organization and business efficiency suffers, or Dev Team’s junior members  are not properly mentored
  • Parallel development at the same time on two or more branches can cause the buildup of TechnicalDebt because of the work that will eventually be required to merge the changes into a single source base. The more changes that are done in isolation, the more debt that is piled up.
  • Delayed refactoring – As the requirements for a project evolve, it may become clear that parts of the code have become unwieldy and must be refactored in order to support future requirements. The longer that refactoring is delayed, and the more code is written to use the current form, the more debt that piles up that must be paid at the time the refactoring is finally done.
  • Top down project execution methodologies
  • Lack of product vision
  • Fast pace changes
    • Technological
    • Business environment
  • Not paying debt regularly

Most of the time, TechnicalDebt is created to achieve short run goals sacrificing, long term solution.  But remember, you cannot have a  long term if you do not survive in short term. But also do not forget – What you sow is what you reap.

BigUpfrontDesign

In the first glance it seems very plausible that BigUpfrontDesign will resolve the issue of TechnicalDebt. You must avoid fallacy of - we are designing the product from very starting, so we will be avoiding lot of challenges which might come on the way during long course of development.  Ask few questions:

  • Is requirement space frozen?
  • Are technological innovations halted?
  • Is business environment static?

If your answer is “NO” for any one of above question, BigUpfrontDesign will results in bigger TechnicalDebt.

Puxadinho
Puxadinho is a Portuguese word which means an extension of a construction done without any expert supervision, poor materials and generally illegally.

Pauxadinho is not restricted to construction only.

You can encounter pauxadinho in software everywhere. Pauxadinho is result of excessive TechnicalDebt. Every one suffers.

Affordable Care web sites were prime examples of Pauxadinho across the states and federal agencies. Few of the examples you can follow here:
Various US agencies had to spend great sum of money and time to rectify the various web sites with great loss to reputation.
But, you should also not ignore Reid Hoffman’s (Linkedin creator) advice – if you are not embarrassed by first version of your product, you’ve launched too late.

Festina lente
The Roman historian Suetonius, in De vita Caesarum, tells that first Roman emperor, Augustus deplored rashness in military commanders, and thus “Festina lente” was one of his favorite sayings.
Gold coins minted for Augustus bore images of a crab and a butterfly to attempt an emblem for the adage.

The constructive intent of the phrase is that activities should be performed with a proper balance of urgency and diligence. If tasks are overly rushed, mistakes are made and good long-term results are not achieved. Work is best done in a state of flow in which one is fully engaged by the task and there is no sense of time passing.

Broken Window
The broken windows theory is a criminological theory of the norm-setting and signaling effect of urban disorder and vandalism on additional crime and anti-social behavior. The theory states that maintaining and monitoring urban environments to prevent small crimes such as vandalism, public drinking and toll-jumping helps to create an atmosphere of order and lawfulness, thereby preventing more serious crimes from happening.
James Q. Wilson and George L. Kelling first introduced the broken windows theory in an article titled Broken Windows, in the March 1982 The Atlantic Monthly. The title comes from the following example:
  • Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break a few more windows. Eventually, they may even break into the building, and if it's unoccupied, perhaps become squatters or light fires inside.
  • Or consider a pavement. Some litter accumulates. Soon, more litter accumulates. Eventually, people even start leaving bags of refuse from take-out restaurants there or even break into cars.

Replace building with code. A code base with spaghetti will get more. With not so good code everyone wants to hack it and get the work done. Who cares about long term?

First Law of Programming
Lowering quality lengthens development time.

Quality software takes the least amount of time to develop. If your code are simple as possible, complete tests and a design that fits just right (no over engineering please!), additions and changes happen in the fastest possible way because the impact is lowest. Consequently, if you hack something out, the more you hack the slower you go because the cost of addition or change grows with each line of code.

Adding features vs writing from scratch
In a well-written system, the cost of adding a new feature should be less than the writing from scratch in most of the cases.

Certainly previous statement is function of reusability of existing code. Even if there is very little code reusability, the patterns of the existing system can be reused to reduce the number of design decisions.

Of course, TechnicalDebt will increase if you do not refactor on continual basis.


Legacy Code

You might have thought of COBOL code is Legacy code. I have different take on it. Code which does not have well written code is Legacy code.  You will find it difficult to refactor this code. You find it difficult to add features to this code.

If you refactor this this code, you have no idea what else is broken.  You need tests to verify. To test it, you need to refactor.  This is Catch 22 of fixing a Legacy code.

TechnicalDebt Quadrant

In response to Uncle Bob’s post saying a mess is not a debt, Martin Fowler came up with idea of TechnicalDebt Quadrant. TechnicalDebt Quadrant is an attempt to distinguish between irresponsible, incompetency and prudency for a team.

The original quadrant lists two quadrants and one half.
With my experience with various teams across industry and geographies, I overlay my ideas over original. This overlay represents teams various state of working under numerous environmental conditions.

TechnicalDebt Matrices

You can't manage what you don't measure. It is an old management adage that is true beyond business situations. Unless you measure something you don't know if it is getting better or worse. You can't manage for betterment if you don't measure to view what is getting better and what isn't.

Before jumping to matrices, I suggest to understand your project in little different way:

  1. Is project in the active development phase?
  2. Is project in the maintenance phase?

If project is in the active development phase, let’s assume you are using Scrum while if your project is in maintenance phase, you are using KanBan.

Let’s start with a project which is in active development.

Are you marking your user stories – whether story is TechnicalDebt payment one or not? Are you assigning TechnicalDebt Payment points with story points to stories?  If your answer is NO.  Tighten your belt, accept Red pill.

Start ASAP and with next Sprint Planning and Product Backlog Grooming sessions start assigning TechnicalDebt Payment points.

There are four attributes which should be assigned to a story w.r.t TechnicalDebt:

  1. Is pure TechnicalDebt story: This attribute has binary value – Yes or No. YES signifies that this story is not adding any feature to the increment. NO means that apart from TechnicalDebt payment, this story will also be adding feature to the product. This attribute to be filled up during one of the Product Backlog grooming session.
  2. TechnicalDebt points to be paid: This number represents team’s best intention estimate of TechnicalDebt points to be paid if this story to be executed. The value of this attribute to be estimated during the Product Backlog sessions. At the Sprint Planning meeting the final value must be assigned.
  3. TechnicalDebt points paid: After completion of all tasks associated with this story and just before declaring story DONE, assign value to this attribute. This attribute’s value signifies TechnicalDebt paid off by executing this story.
  4. TechnicalDebt points collected: After completion of all tasks associated with this story and just before declaring story DONE, assign value to this attribute. This attribute’s value signifies prudency of team in acquiring new TechnicalDebt.
In a mature and healthy team, “Is pure TechnicalDebt story” value should be “No”. Why to pay debt upfront if you are not getting any benefit. But in some cases like where synergies or dependencies among stories warrant, you will be having value “Yes” for this attribute.

In ideal world value for remaining three attributes should be ZERO, but sadly utopia does not exist.

The value of various TechnicalDebt points should be estimated using the same method, that  you are using to assign Story Points: T-shirt sizes, Fibonacci sequence (1, 2, 3, 5, 8, 13, …), power of 2 (2, 4, 8, 16, 32, …), etc.

Now it is time to see the trend in TechnicalDebt. Plot TechnicalDebt points against time (per Sprint). You will be drawing three lines.

  • Total TechnicalDebt points in the Product Backlog: This trend line will provide glimpse of technical health of your product. In a technically healthy product, this line should be flat over a time unless some major technical or functional or non-functional changes occur in the product. You may also notice some spike in this trend line with introduction of new blood in the team.
  • TechnicalDebt points collected in a sprint:  The trend line should be downward. You may also notice some spikes in this trend which must be avoided but due to business pressure or other reasons may not be avoidable.
  • TechnicalDebt points paid off in a sprint: This trend line depicts team’s focus on Technical heath of the product.  This line should be understood with “Total TechnicalDebt points in Product Backlog” and “TechnicalDebt points collected in a sprint” lines.
·          

Now it is time to look into a project which is in maintenance phase.

Kanban is becoming popular to manage support projects which have entered into the maintenance phase. In this scenario there are two possibilities:
  • During development phase TechnicalDebt matrices were collected and are available to maintenance team
  • TechnicalDebt matrices are not available to maintenance team

In first case where maintenance team has historical information about TechnicalDebt of the project can continue the work from where development team left.

In both cases whether maintenance team has TechnicalDebt records or not, there will be lot of adhoc tickets to resolve issues arising daily basis and some enhancement requests.

Before bringing a story Task Board, ensure that TechnicalDebt related attributes have proper values.  This will help you to build trend lines over a time period.

Techniques to prevent TechnicalDebt

It is always a good idea to take preventive measure to ensure that bare minimum TechnicalDebt is acquired by team over the product’s life cycle.
  1. Emphasize in Collaborative Design techniques
    1. Whiteboard sessions on design topics
    2. Leverage collective experience of the team
    3. Wisdom of the crowd
    4. Fair mixture of subject-matter experts and novices
  2. Utilize Emergent Architecture
    1. Evolution over revolution
    2. Gradual changes
    3. Controlled Generic-ness
    4. Avoid YAGNI (You Ain't Gonna Need It)
  3. Strong Definition of “DONE”
    1. Story
    2. Sprint
    3. Release
    4. Release to Prod
“Done should cover “Completion Criteria” as well as “Acceptance Criteria”.
  1. Automation
    1. Boiler plate code generation
    2. Deployment
    3. Continuous build
    4. Testing
  2. Test Driven Development
  3. Refactor on continual basis
  4. Cultural reinforcement
    1. Without unit test cases, no code is ready to be called “DONE”
    2. We own this product end to end
    3. System thinking
    4. No free lunches. Pay now or later (bigger amount)
    5. We will not allow TechnicalDebt until unless tactical or strategic business imperative demands so.
  5. Aware business
    1. Business should be made aware that short term quick fixes result in long term pains (TechnicalDebt)
    2. Business should be made aware of benefit and necessity of paying TechnicalDebt in timely manner.
TechnicalDebt Management

Since you have already accepted the Red pill, be ready for the consequences.

  • Accept the truth, No product of a reasonable size can be TechnicalDebt free at all time. Product will be in TechnicalDebt.
  • Try to prevent accepting new TechnicalDebt.
  • If you fail in prevention, resist with all of your claws.

There are two popular ways to pay TechnicalDebt:
  • In spurts
  • Regularly in each iteration( Sprint if using Scrum)

Because of the Red pill, third option of not paying TechnicalDebt is out of consideration.

Let’s devise a plan to manage TechnicalDebt.

In Product Backlog mark technical stories explicitly. Most of the time Technical stories help you to pay TechnicalDebt or prevent you to accumulate new TechnicalDebt.

In each sprint planning meeting pick up stories which will pay some TechnicalDebt apart from Functional stories.

If you are using cards for user stories, use TechnicalDebt paying stories on obnoxiously colored cards. We all love beauty. It will motivate you to write clean code.

Start assigning TechnicalDebt points to each story during Product Backlog and Sprint Planning sessions.


During Product Backlog Grooming sessions:
  • Identify Low hanging fruits
  • Perform 80-20 analysis

During Retro and Product Backlog Grooming sessions:
  • Identify automation possibilities

Prepare high level TechnicalDebt payment plan and get buy in from Stakeholders.

Now, it’s time to pay back.

Repeat the cycle.

Reference