Class shouldn't be too deep in inheritance tree

Rule ND1202 Object Oriented Design

Warns about classes with 4 or more base classes (third-party base classes not counted: this rule is about your design).

In theory a well-thought long inheritance chain is fine; in practice it is more often a sign of confused design, hard to work with and maintain.

How to fix

Favor Composition over Inheritance: a derived class is bound to the base class implementation, and inheritance breaks encapsulation. Composition binds to interfaces instead, preserving encapsulation with a clearer, less coupled design — a powerful way to break a long inheritance chain. See: http://en.wikipedia.org/wiki/Composition_over_inheritance and http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance

Estimated Debt: linear in the depth of inheritance.

CQLinq source

This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.

// <Name>Class shouldn't be too deep in inheritance tree</Name>
// <Id>ND1202:ClassShouldntBeTooDeepInInheritanceTree</Id>
warnif count > 0 from t in JustMyCode.Types 
where t.IsClass
let baseClasses = t.BaseClasses.ExceptThirdParty()
where baseClasses.Count() >= 4
orderby baseClasses.Count() descending

select new { 
   t, 
   baseClasses, 
   // The metric value DepthOfInheritance takes account
   // of third-party base classes. See its definition here:
   // https://www.ndepend.com/docs/code-metrics#DIT
   t.DepthOfInheritance,
   Debt = (baseClasses.Count() -2)*3.ToMinutes().ToDebt(),
   Severity = Severity.Medium
} 

//<Expl>The *{0}* derives from *{1}*. A lengthy inheritance chain indicates a confusing design that can be challenging to manage and maintain.</Expl>

//<Desc>
// Warns about classes with 4 or more base classes (third-party base classes
// not counted: this rule is about your design).
//
// *In theory* a well-thought *long inheritance chain* is fine; *in practice*
// it is more often a sign of confused design, hard to work with and maintain.
//</Desc>

//<HowToFix>
// **Favor Composition over Inheritance**: a derived class is bound to the
// base class implementation, and inheritance breaks encapsulation.
// *Composition* binds to interfaces instead, preserving encapsulation with a
// clearer, less coupled design — a powerful way to break a *long inheritance
// chain*. See:
// http://en.wikipedia.org/wiki/Composition_over_inheritance and
// http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance
//
// Estimated Debt: linear in the depth of inheritance.
//</HowToFix>

Object Oriented Design: all 14 items