ABC Metric (Assignments, Branches, Conditions)
debt(d3/e5/b3/t5)
Closest to 'default linter catches the common case' (d3). Tools like phpmetrics, phploc, and phpmd (listed in detection_hints) can automatically calculate ABC scores and flag violations. These are common static analysis tools in the PHP ecosystem that many teams already use, though not universally enabled by default.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix suggests keeping ABC < 20 via 'extraction and delegation' — this typically means splitting methods, introducing new classes, or restructuring logic. Common_mistakes notes that naively splitting methods doesn't reduce actual complexity, so proper remediation requires thoughtful refactoring beyond simple one-line fixes.
Closest to 'localised tax' (b3). ABC metric as a quality gate applies broadly across contexts (web, cli, queue-worker per applies_to), but the metric itself is a measurement tool rather than an architectural choice. High ABC methods create localized maintenance burden — the pain is felt method-by-method rather than system-wide. Addressing it doesn't require rearchitecting the whole system.
Closest to 'notable trap' (t5). The misconception field explicitly states developers confuse ABC with cyclomatic complexity, thinking they measure the same thing. Common_mistakes reinforces this: developers may reduce ABC superficially by splitting methods without reducing actual complexity, or treat all branches equally when assignments vs calls have different implications. These are documented gotchas that experienced developers eventually learn.
Also Known As
TL;DR
Explanation
The ABC metric (Jerry Fitzpatrick, 1997) measures method complexity using three independent counts: A = assignments (state changes), B = branches (function/method calls and control transfers), and C = conditions (boolean expressions). The final score is computed as the vector magnitude: sqrt(A^2 + B^2 + C^2). Unlike cyclomatic complexity, which focuses on decision paths, ABC captures how much a method mutates state and delegates work. High A suggests excessive state manipulation, high B indicates heavy delegation or deep call chains, and high C reflects complex logic. Tools like PHPMetrics and PHPLoc report ABC per method. Scores above ~20 should be reviewed; above ~50 typically indicate methods that are difficult to test, reason about, and maintain.
Common Misconception
Why It Matters
Common Mistakes
- Reducing ABC by splitting methods without reducing actual logic complexity.
- Ignoring high assignment counts — excessive state mutation is a major maintainability risk.
- Treating all branches equally — external calls and control flow both increase B but have different implications.
- Using ABC thresholds blindly without considering domain complexity.
Avoid When
- Evaluating very small methods where ABC adds little insight.
- Comparing across different domains without normalising expectations.
When To Use
- Identifying overly complex or state-heavy methods.
- Enforcing maintainability thresholds in CI pipelines.
Code Examples
// ❌ High ABC — excessive state + branching
function processOrder($order, $user, $coupon, $tax) {
$total = 0; $discount = 0; $shipping = 0;
if ($order && $user && $coupon) {
if ($coupon->valid && $coupon->amount > 0) {
$discount = $coupon->amount;
}
$total = $order->subtotal - $discount + $tax + $shipping;
}
return $total;
}
// ✅ Lower ABC via decomposition and reduced state
function processOrder($order, $user, $coupon, $tax) {
if (!$this->isProcessable($order, $user, $coupon)) {
return 0;
}
$discount = $this->calculateDiscount($coupon);
return $this->calculateTotal($order, $discount, $tax);
}
private function isProcessable($order, $user, $coupon): bool {
return $order && $user && $coupon;
}
private function calculateDiscount($coupon): float {
return ($coupon->valid && $coupon->amount > 0)
? $coupon->amount
: 0;
}
private function calculateTotal($order, $discount, $tax): float {
return $order->subtotal - $discount + $tax;
}