technical debt

Table of Contents

1. technical debt

1.3.

1.5. Prioritizing Technical Debt as If Time & Money Matters • Adam Tornhill • GOTO 2022 - YouTube

1.5.1. Lehman’s laws of software evolution - Wikipedia

These are thermodynamical laws for dealing with information with a bit of Cynefin

  • An S-program is written according to an exact specification of what that program can do (closed system, simple)
  • A P-program is written to implement certain procedures that completely determine what the program can do (example: a program to play chess) (closed system, complicated)
  • An E-program is written to perform some real-world activity; desired behavior strongly linked its changing environment: it needs to adapt to varying requirements and circumstances


“Continuing Change”
an E-type system must be continually adapted or it becomes progressively less satisfactory. (2nd law)
“Increasing Complexity”
as an E-type system evolves, its complexity increases unless work is done to maintain or reduce it. (2nd law)
“Self Regulation”
E-type system evolution processes are self-regulating with the distribution of product and process measures close to normal.
“Conservation of Organisational Stability (invariant work rate)”
the average effective global activity rate in an evolving E-type system is invariant over the product’s lifetime.
“Conservation of Familiarity”
as an E-type system evolves, all associated with it, developers, sales personnel and users, for example, must maintain mastery of its content and behaviour to achieve satisfactory evolution. Excessive growth diminishes that mastery. Hence the average incremental growth remains invariant as the system evolves.
“Continuing Growth”
the functional content of an E-type system must be continually increased to maintain user satisfaction over its lifetime.
“Declining Quality”
the quality of an E-type system will appear to be declining unless it is rigorously maintained and adapted to operational environment changes.
“Feedback System” (first stated 1974, formalised as law 1996)
E-type evolution processes constitute multi-level, multi-loop, multi-agent feedback systems and must be treated as such to achieve significant improvement over any reasonable base.

1.5.2. Increasing Complexity: consequences and impact

  • Symptoms that the business sees
    • Roadmap
      • Long Cycle Times
      • Lack of Task Predictability
      • Organizational problems (high turnover)
      • Low innovation (we don’t have time to innovate)
    • Team
      • Developer attrition/Strong code ownership (this isn’t my code, I don’t know how it works) vs shared code ownership
      • Key Personnel Dependencies (X goes on vacation, we cannot do Y)
  • Symptoms that the users experience
    • Product
      • Bugs
      • «Also Lack of quality (bad UX) ?»

1.5.3. Static analysis focuses too much on technical stuff

  • Quantifying Technical Debt with static analysis is not actionable
  • Technical debt cannot be prioritized from code alone
  • There is always a tradeoff between improving existing code vs adding new features, and this tradeoff shifts over time

1.5.4. Behavioral Code Analysis

Understand how we - as a development organization - interat with the system we’re building
Basically different parts of code change at different rates

1.5.5. Android Case Study

Hotspot analysis
Hierarchical circles as folders and files. Size is used to reflect code complexity: how hard is for a human to understand
Code complexity is only really a problem when we have to deal with it (rate of change)
Color is related to code change frequency
Code complexity is the principal, Code change frequency is the Interest Rate

1.5.6. Software Measurement: A Necessary Scientific Basis

There is no single metric than can, you have to identify specific attributes of complexity
Code Quality or Maintainability suggests an absolute, and they are more contextual, poorly defined globally

  • Code Health:
    • Code Health correlates with Development Costs and Delivery Risks
  • Example Virtual Code Review
    Examples include – but are not limited to – the following:
    • Brain Method: A single function/method that centers too much behavior and becomes a local hotspot.
    • Nested Complexity: This is typically revealed as if-statements inside other if-statments and/or loops, and is a construct that increases the risk for defects significantly.
    • Developer Congestion: Code becomes a coordination bottleneck when multiple developers need to work on it in parallel (see Parallel Development and Code Fragmentation).
    • Knowledge Loss due to former contributors: If the developer behind a hotspot with low code healt leaves the organization, the maintenance risk increases significantly.
    • DRY (Don’t Repeat Yourself) Violations: CodeScene detects duplicated logic that is actually changed together in predictable patterns.
    • Primitive Obsession: Code that uses a high degree of built-in, primitives such as integers, strings, floats, often lacks a domain language that encapsulates the validation and semantics of function arguments.

1.5.7. Finding bad code is the easy part

Complicated in Cynefin terms, the complex part is to prioritize
Change frequency follows a power law / Pareto distribution, so you can focus on refactoring the 20% that changes more frequently to get the 80% benefit

1.5.8. Go down to the function level when a file is too big

Refactoring at this scale is a huge risk
Hotspots X-Ray: Using git log, go down to the function level and calculate metrics at that level
Change frequency, Lines of Code, Cyclomatic Complexity for each function → Draw a Hotspot Analysis on that data
Cyclomatic Complexity is more or less the total number of unit tests to cover that function/behavior

1.5.9. Tech Debt and People

Legacy Code: code that lacks in quality that we didn’t write ourselves

1.5.10. Code Contributions

The added LoC follows a Pareto Distribution also: the core 20% contributes 80% of the code: a 20% leaving is not the same as the 80% leaving

1.5.11. Case Study: Off-Boarding

Get knowledge distribution and knowledge sharing in your code: how many people have contributed to that function/file?
Assess the impact of some person leaving the team
If there is a lot of knowledge concentrated on one person, let them share it:
How?: Prioritize with hotspot criteria, low code health, and odds of leaving
Pair programming with a developer that’s going to stay, (maybe a junior, kinda Entangled trios, so that there is not so much assumption of knowledge)

1.5.12. «Code change is a proxy for user needs»

Depends on ideal communication between users and developers

  • Users may stop to ask for changes if they believe is going to take soooo long
  • Code may be changed in places that they’re comfortable with, rather than places which may deliver more value
  • Unarticulated user needs : users don’t knwow what they want, what it’s possible, …

Author: Julian Lopez Carballal

Created: 2024-10-20 Sun 04:02