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

Middle Man

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

Closest to 'specialist tool catches it' (d5), because detection_hints list phpmd and phpstan as the relevant tools, and automated detection is flagged as 'no' — meaning even these tools only partially surface the smell via heuristics (>50% pass-through methods). It won't be caught by a compiler or default linter, requiring a specialist static analysis tool and still needing human judgment to confirm.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), because the quick_fix describes inlining the delegation so callers call the real class directly. This is a mechanical refactor — removing the middle-man class and updating its call sites — which typically spans a handful of files within one component rather than a true cross-cutting rework.

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

Closest to 'persistent productivity tax' (b5), because middle-man classes accumulate over time (common_mistakes note they are never deleted after extraction), and they apply across web, cli, and queue-worker contexts. Every maintainer must navigate an extra indirection layer when reading or modifying code, slowing comprehension across multiple work streams without fully defining the system's architecture.

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

Closest to 'notable trap' (t5), because the misconception field states that developers commonly believe delegation is always better than direct access — a documented OOP gotcha. A competent developer familiar with delegation patterns from DDD may not recognise when wrapping crosses into valueless pass-through, making this a well-known but non-obvious pitfall that most developers eventually learn.

About DEBT scoring →

Also Known As

middle man smell over-delegation pass-through class

TL;DR

A class that does little more than delegate every method to another object — an unnecessary layer of indirection.

Explanation

The Middle Man smell occurs when a class primarily exists to forward calls to another class, offering no additional logic or value. It arises from over-application of delegation or from classes that were once more substantial but had their behaviour stripped out. The remedy is typically to remove the intermediary and call the delegate directly (inline delegation), or if the class is a legitimate abstraction, to add real behaviour to justify its existence.

Common Misconception

Delegation is always better than direct access. When a class does nothing but delegate every call to another, it adds indirection without value — callers may as well use the delegate directly, and the middle man should be collapsed.

Why It Matters

A class that does nothing but delegate to another class adds a navigation layer with no value — callers must understand two classes to achieve what one would do.

Common Mistakes

  • Service classes that are pure pass-throughs to a repository with no added logic.
  • Facade classes that expose every method of the subsystem 1:1 without simplification.
  • Not removing middle men during refactoring — they accumulate when classes are extracted but the original is never deleted.
  • Over-using delegation patterns from DDD without checking whether each layer adds value.

Code Examples

💡 Note
If a class does nothing but forward calls to another, delete it and inject the dependency directly.
✗ Vulnerable
// UserManager just delegates every call — pointless layer
class UserManager {
    public function __construct(private UserRepository $repo) {}
    public function find(int $id): ?User          { return $this->repo->find($id); }
    public function save(User $u): void           { $this->repo->save($u); }
    public function delete(int $id): void         { $this->repo->delete($id); }
}
✓ Fixed
// Remove the middle man — inject UserRepository directly where needed
class UserController {
    public function __construct(private UserRepository $users) {}
    // use $this->users directly — no useless delegation layer
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 52
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 1 ping M 0 pings T 0 pings W 0 pings T 3 pings F 0 pings S 2 pings S 0 pings M 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 0 pings F 2 pings S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 7 ChatGPT 6 Ahrefs 5 Google 3 Perplexity 2 Unknown AI 2 Claude 2 Scrapy 2 PetalBot 2 Twitter/X 2 Bing 1 Meta AI 1 Applebot 1 Brave Search 1
crawler 31 crawler_json 6
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ Quick Fix
Remove a class that only delegates to another — inline the delegation and let callers call the real class directly, or enhance the wrapper to add meaningful value
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Class where >50% of public methods just call another class method with no transformation; service that proxies every method of a dependency unchanged
Auto-detectable: ✗ No phpmd phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Class Tests: Update


✓ schema.org compliant