phanalist

E0020: The “Family Tree” Rule (Depth of Inheritance Tree - DIT)

Imagine trying to understand the rules of a game. If there is one rulebook, it’s easy. But what if the rulebook says “Also read book B,” and book B says “Also read book C,” and book C says “Also read book D”? By the time you get to the end, you have to keep 4 different books in your head at once!

Depth of Inheritance Tree (DIT) measures how many “parent” classes your class has in its family tree.

How the rule works

Every time a class extends another class, the depth goes up by 1.

If your inheritance tree gets too deep (default > 4), it becomes incredibly hard for a developer to know what methods and properties a class actually has, because they are scattered across 5 different files!


❌ The “Too Deep” Example

To understand AdminUser, you have to open 5 different files.

class Model {}
class Authenticatable extends Model {}
class User extends Authenticatable {}
class StaffUser extends User {}

// VIOLATION! Depth is 4!
class AdminUser extends StaffUser {} 

✅ The “Flat” Example

Favor composition (using other classes) or interfaces over deep inheritance chains.

interface Authenticatable {}
class Model {}

// Depth is only 1! Much easier to understand.
class AdminUser extends Model implements Authenticatable {
    private RolePermissions $permissions;
}

Configuration

rules:
  E0020:
    max_depth: 4

The Junior’s Rule of Thumb:

If Phanalist flags your class for DIT, it means your family tree is too complicated. Stop using extends to share code, and start using Composition (passing objects in the constructor) or Traits!