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

Low Cohesion

Code Quality Intermediate
debt(d5/e7/b7/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpmetrics, phpmd, and phploc — all specialist static analysis tools. The LCOM4 > 2 metric from phpmetrics is a specialist measure, not caught by default linters or compilers. It requires deliberate setup and interpretation of metrics.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix describes extracting method groups into separate classes, but low cohesion classes (e.g., a UserService handling billing, reporting, and notifications) have callers throughout the codebase. Splitting a God class means updating injection sites, tests, and consumers across many files — this is cross-cutting by nature, not a single-component fix.

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

Closest to 'strong gravitational pull' (b7). Low cohesion classes tend to be load-bearing (UserService, helpers used everywhere) and every new feature is shaped by — and tends to worsen — the existing dumped-in design. As noted in why_it_matters, reuse becomes impossible and testing any one responsibility requires setting up all others, creating a persistent and widening productivity tax across the codebase.

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

Closest to 'notable trap' (t5). The misconception field describes a documented and common gotcha: developers believe physical co-location of related concepts equals cohesion, but cohesion is about shared purpose. A class mixing user authentication and email formatting 'seems' cohesive because both involve users, yet has low cohesion. This is a well-documented SOLID/OOP lesson that most developers eventually learn, placing it at t5.

About DEBT scoring →

Also Known As

low cohesion mixed responsibilities lack of cohesion

TL;DR

A class or module that does many unrelated things — high coupling's counterpart, making code hard to understand, test, and reuse.

Explanation

Cohesion measures how closely related the responsibilities of a module are. High cohesion: a class does one thing and all its methods work toward that single purpose. Low cohesion: a class mixes unrelated concerns — a UserService that also sends emails, processes payments, and generates PDF reports. Low cohesion is often the root cause of the God Class smell. The fix is decomposition: extract responsibilities into focused classes, guided by the Single Responsibility Principle.

Common Misconception

Putting related functionality in one place always increases cohesion — cohesion is about shared purpose, not physical proximity; a class handling both user authentication and email formatting has low cohesion even though both involve users.

Why It Matters

Low cohesion classes are impossible to reuse — you cannot use the email functionality without pulling in the payment logic — and testing one responsibility requires setting up all the others.

Common Mistakes

  • Adding utility methods to existing classes because it is convenient — create a dedicated utility class instead.
  • Service classes that grow unbounded — UserService should not handle billing, reporting, and notifications.
  • Static helper classes with dozens of unrelated methods — a sign of dumping ground design.
  • Confusing low coupling (few dependencies) with high cohesion — they are independent dimensions.

Code Examples

✗ Vulnerable
// Low cohesion — UserService does everything:
class UserService {
    public function register(array $data): User { /* ... */ }
    public function sendWelcomeEmail(User $u): void { /* ... */ }
    public function generateInvoicePdf(User $u): string { /* ... */ }
    public function processSubscriptionPayment(User $u): void { /* ... */ }
    public function exportUsersToCsv(): string { /* ... */ }
}
✓ Fixed
// High cohesion — each class has one purpose:
class UserRegistrationService {
    public function register(array $data): User { /* ... */ }
}
class UserEmailService {
    public function sendWelcomeEmail(User $u): void { /* ... */ }
}
class InvoiceGenerator {
    public function generate(User $u): string { /* ... */ }
}
class SubscriptionPaymentService {
    public function charge(User $u): void { /* ... */ }
}

Added 16 Mar 2026
Edited 22 Mar 2026
Views 62
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 4 pings S 4 pings S 2 pings M 3 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Scrapy 12 Amazonbot 10 Perplexity 7 Google 5 Ahrefs 4 ChatGPT 3 SEMrush 3 Unknown AI 2 Claude 2 Majestic 1 Meta AI 1 PetalBot 1
crawler 46 crawler_json 5
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
Look for methods that use completely different instance variables — each group of methods using the same data is a candidate for extraction into its own class
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
phpmetrics LCOM4 > 2; class with methods touching unrelated properties; utility class with static methods on unrelated concerns
Auto-detectable: ✓ Yes phpmetrics phpmd phploc
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: High ✗ Manual fix Fix: High Context: Class Tests: Update


✓ schema.org compliant