Low Cohesion
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 { /* ... */ }
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
28
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Amazonbot 8
Perplexity 6
Google 3
Unknown AI 2
Ahrefs 2
Majestic 1
ChatGPT 1
Also referenced
How they use it
crawler 21
crawler_json 2
Related categories
⚡
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