phanalist

E0029: The “Phone Tree” Rule (Fan-in / Fan-out)

Imagine calling a company and being transferred 15 times before reaching the right person. That’s high fan-out. Now imagine you are the single point of contact for 30 different departments. That’s high fan-in.

How the rule works

During a scan, we index all classes and their dependencies from type hints, new instantiations, instanceof checks, static method calls, and property/constant access. At validation time, we compute fan-out (outgoing deps) and fan-in (incoming deps) for each class.

High fan-out means your class depends on too many things and is fragile. High fan-in means too many things depend on this class and changes require extensive testing.


❌ The “High Fan-out” Example

This class depends on 12+ classes. If any of them change, this class might break.

class ReportService
{
    public function __construct(
        private Database $db,
        private Mailer $mail,
        private PdfGenerator $pdf,
        private ExcelWriter $excel,
        private S3Storage $storage,
        private Logger $log,
        private Cache $cache,
        private Queue $queue,
        private EventBus $events,
        private Config $config,
    ) {}

    public function run(): void
    {
        $data = $this->db->query();
        $report = $this->pdf->generate($data);
        $this->storage->upload($report);
        $this->mail->send(new Notification());
    }
}

✅ The “Low Fan-out” Example

Use interfaces to reduce direct dependencies.

class ReportService
{
    public function __construct(
        private ReportRepository $reports,
        private ReportRenderer $renderer,
    ) {}

    public function run(): void
    {
        $report = $this->renderer->render($this->reports->fetch());
        $this->reports->save($report);
    }
}

Configuration

rules:
  E0029:
    max_fan_out: 10
    max_fan_in: 20

The Junior’s Rule of Thumb:

If Phanalist flags high fan-out, your class depends on too many other classes. Use interfaces, facades, or inject more abstract collaborators. If it flags high fan-in, your class is too central — consider splitting it or stabilizing its interface with tests.