← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Object Calisthenics

quality Advanced
debt(d7/e5/b3/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints indicate tools phpcs and phpstan are listed but automated detection is explicitly marked 'no'. The code patterns (multiple indentation levels, else clauses, raw primitives) require human judgment or code review to reliably identify — tooling can flag some surface patterns but not the design intent violations.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes applying nine rules as a checklist, but common_mistakes show that wrapping primitives (Email value objects), extracting methods aggressively, and eliminating else/getters are structural changes that typically touch multiple files and require non-trivial refactoring across a component, not a single-line patch.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Applies broadly to web, cli, and queue-worker contexts per applies_to, but the burden is primarily on code review and developer habits rather than imposing architectural gravity on the codebase. It is a persistent but localised tax — it shapes how individual methods and classes are written without dictating system-wide architecture.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field explicitly states the canonical wrong belief: developers treat the nine rules as mandatory production standards rather than intentional exercises. This contradicts how similar 'principles' (like SOLID) are used elsewhere — those are production guidelines, whereas object calisthenics are training constraints. A competent developer encountering these rules will very likely misapply them as absolute laws.

About DEBT scoring →

Also Known As

OO calisthenics object calisthenics rules Muggeridge rules

TL;DR

Nine strict OO coding rules by Jeff Bay that, if followed, force good object-oriented design habits.

Explanation

Object Calisthenics are nine constraints: (1) one level of indentation per method, (2) no else keyword, (3) wrap all primitives and strings, (4) first-class collections, (5) one dot per line, (6) no abbreviations, (7) keep classes small, (8) no classes with more than two instance variables, (9) no getters/setters. They are deliberately strict — intended as an exercise rather than production rules — but applying them surfaces design improvements, encourages value objects, and reduces coupling.

Common Misconception

Object calisthenics rules are meant to be followed literally in production code. They are intentional constraints used as exercises to build good OOP habits — applying all nine rules to production code simultaneously is generally impractical but using them as a lens reveals design weaknesses.

Why It Matters

Object Calisthenics are nine extreme OOP rules designed to force good habits — applying them even partially (one level of indentation, no else, wrap primitives) measurably improves code quality.

Common Mistakes

  • Treating all nine rules as mandatory production standards — they are learning exercises, not absolute laws.
  • Only one level of indentation is the most impactful rule and the most ignored — extract methods aggressively.
  • Not wrapping primitives and strings — string $email should be an Email value object that validates itself.
  • No else — forcing early return and guard clauses rather than nested if/else is the high-value take-away.

Code Examples

✗ Vulnerable
// Violates multiple calisthenics rules — 3 levels of nesting, else branches, raw primitives:
function process(array $data): string {
    if (!empty($data)) {
        foreach ($data as $item) {
            if ($item['type'] === 'A') {
                return $item['value'];
            } else {
                return 'default';
            }
        }
    } else {
        return 'empty';
    }
}
✓ Fixed
// 9 rules applied pragmatically:

// 1. One level of indentation per method — extract nested logic
public function process(array \$items): array {
    return array_filter(\$items, fn(\$i) => \$this->isValid(\$i));
}

// 2. No else — early return instead
public function find(int \$id): User {
    if (!\$id) throw new \InvalidArgumentException();
    return User::findOrFail(\$id);
}

// 3. Wrap primitives — value objects
\$email = new Email(\$rawEmail);

// 4. First-class collections
class UserCollection {
    public function __construct(private array \$users) {}
    public function active(): self {
        return new self(array_filter(\$this->users, fn(\$u) => \$u->isActive()));
    }
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 25
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 3 pings T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 1 ping T 2 pings W 1 ping T 0 pings F
No pings yet today
Amazonbot 9 Unknown AI 3 Perplexity 2 Ahrefs 2 ChatGPT 2 Bing 2 Majestic 1 Google 1
crawler 20 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: High
⚡ Quick Fix
Apply the 9 rules as a code review checklist: one level of indentation per method, no else keyword, wrap all primitives, first class collections, no getters/setters
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Multiple indentation levels in a method; else clauses; raw primitives passed as domain values; getters on domain objects
Auto-detectable: ✗ No phpcs phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update

✓ schema.org compliant