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

Middle Man

quality Intermediate

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 20
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 2 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 3 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S
No pings yesterday
Amazonbot 7 Google 3 Perplexity 2 Unknown AI 2 ChatGPT 2 Ahrefs 1
crawler 15 crawler_json 2
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