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

Extract Class Refactoring

Code Quality Intermediate
debt(d5/e5/b3/t3)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpmd and sonarqube as the tools, both specialist static analysis tools that can flag large/low-cohesion classes via metrics. The automated field is explicitly 'no', meaning even these tools only hint at candidates rather than definitively catching the problem — but they are the primary detection mechanism, placing this squarely at d5.

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 identifying cohesive field groups, creating a new class, moving fields and their methods, and replacing all references in the original class. The common_mistakes note that not updating all references is a pitfall, confirming this spans at least two files (old class + new class) and requires careful cross-reference updates — more than a simple pattern replacement but not a full cross-cutting codebase refactor.

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

Closest to 'localised tax' (b3). The extraction affects the refactored class and its direct consumers, but the rest of the codebase is largely unaffected. The applies_to contexts are broad (web/cli/queue-worker), but the structural impact is localised to the component being refactored and its callers. Future maintainers only pay the tax if they work in that area.

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

Closest to 'minor surprise (one edge case)' (t3). The misconception states developers think Extract Class is only for God Classes, when in fact any class with a cohesive subset of responsibilities qualifies. This is a scoping misunderstanding rather than a behavioural trap — a competent developer won't make catastrophically wrong decisions, but may under-apply the technique. The common_mistakes (anaemic classes, missed references, over-extraction) add minor edge-case surprises, keeping this at t3.

About DEBT scoring →

TL;DR

Extract Class splits a large class into two — moving a cohesive subset of fields and methods into a new class that the original delegates to.

Explanation

A class doing too much (God Class) should be split. Extract Class: identify a cohesive group of fields and methods (e.g., address-related fields in a User class), create a new class (Address), move the fields and methods, update the original class to hold a reference. Signs you need it: class has many unrelated fields, methods only use a subset of fields, natural groupings exist (User + Address, Order + PaymentDetails). In PHP: create the new class, inject it via constructor, update all references. Opposite of Inline Class.

Common Misconception

Extract Class is only for God Classes — any class where you can identify a natural cohesive subset of responsibilities is a candidate.

Why It Matters

Extracted classes are smaller, more focused, independently testable, and reusable — reducing coupling and improving cohesion across the codebase.

Common Mistakes

  • Creating classes with only getters/setters (anaemic) — extract behaviour too, not just data.
  • Not updating all references after extraction — leaving the old fields in place as duplicates.
  • Extracting too aggressively — small classes with one field and one method add unnecessary indirection.

Code Examples

✗ Vulnerable
class User {
    public string $name;
    public string $street;
    public string $city;
    public string $postcode;
    public string $country;

    public function formatAddress(): string {
        return "$this->street, $this->city";
    }
}
✓ Fixed
class Address {
    public function __construct(
        public readonly string $street,
        public readonly string $city,
        public readonly string $postcode,
        public readonly string $country,
    ) {}

    public function format(): string {
        return "$this->street, $this->city";
    }
}

class User {
    public function __construct(
        public readonly string $name,
        public readonly Address $address,
    ) {}
}

Added 23 Mar 2026
Views 49
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 2 pings T 3 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 2 pings F 1 ping S 1 ping S 0 pings M 1 ping T 0 pings W
No pings yet today
SEMrush 1
Amazonbot 7 Google 6 Scrapy 5 Perplexity 4 ChatGPT 3 Unknown AI 3 Ahrefs 3 Bing 3 Meta AI 2 Claude 2 Majestic 1 SEMrush 1
crawler 35 crawler_json 4 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
Identify cohesive field groups in large classes. Create a new class, move the fields and their methods, replace with a reference in the original.
📦 Applies To
web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
class.*{[\s\S]{2000,}}
Auto-detectable: ✗ No phpmd sonarqube
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: Class Tests: Update


✓ schema.org compliant