Avoid types with poor cohesion
Matches types with Lack Of Cohesion of Methods (LCOM, range [0-1]) higher than 0.84: a poorly cohesive class. A class is utterly cohesive when all its methods use all its instance fields. Only types with enough methods and fields are matched to avoid bias. LCOM metric: https://www.ndepend.com/docs/code-metrics#LCOM
How to fix
Split the type into smaller, more cohesive types implementing the same logic. Right-click a matched type > "Show on the Dependency Graph" to visualize fields usage by methods and plan the refactoring.
Estimated Debt: linear from 5 minutes (low poorCohesionScore) to 4 hours (high).
Estimated Debt: linear from 5 minutes (low poorCohesionScore) to 4 hours (high).
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>Avoid types with poor cohesion</Name>
// <Id>ND1007:AvoidTypesWithPoorCohesion</Id>
warnif count > 0 from t in JustMyCode.Types where
t.LCOM > 0.91 &&
t.NbFields > 10 &&
t.NbMethods > 10
// Don't take account of properties and events accessors and backing fields
let fields = t.Fields.Where(f => !f.IsStatic && f.ParentProperty == null && f.ParentEvent == null).ToArray()
let methods = t.Methods.Where(m => m.ParentProperty == null && m.ParentEvent == null).ToArray()
where fields.Length > 8 && methods.Length > 8
let poorCohesionScore = 1/(1.01 - t.LCOM)
orderby poorCohesionScore descending
select new {
t,
t.LCOM,
methods,
fields,
poorCohesionScore,
Debt = poorCohesionScore.Linear(5, 5, 50, 4*60).ToMinutes().ToDebt(),
// The annual interest varies linearly from interest for severity Medium for low poorCohesionScore
// to 4 times interest for severity High for high poorCohesionScore
AnnualInterest = poorCohesionScore.Linear(5, Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes,
50, 4*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes)).ToMinutes().ToAnnualInterest()
}
//<Expl>
// The *{0}* has a *Lack Of Cohesion of Methods* score of {1}. This means that
// its methods and fields are loosely related. Identify different responsibilities
// within the class and split them into separate classes if necessary.
//</Expl>
//<Desc>
// Matches types with **Lack Of Cohesion of Methods** (LCOM, range [0-1])
// higher than 0.84: a **poorly cohesive class**. A class is utterly cohesive
// when all its methods use all its instance fields. Only types with enough
// methods and fields are matched to avoid bias. LCOM metric:
// https://www.ndepend.com/docs/code-metrics#LCOM
//</Desc>
//<HowToFix>
// Split the type into smaller, more cohesive types implementing the same
// logic. Right-click a matched type > "Show on the Dependency Graph" to
// visualize fields usage by methods and plan the refactoring.
//
// Estimated Debt: linear from 5 minutes (low poorCohesionScore) to 4 hours
// (high).
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Code Smells: all 10 items
- Avoid types too big ND1000
- Avoid types with too many methods ND1001
- Avoid types with too many fields ND1002
- Avoid methods too big, too complex ND1003
- Avoid methods with too many parameters ND1004
- Avoid methods with too many overloads ND1005
- Avoid methods potentially poorly commented ND1006
- Avoid types with poor cohesion ND1007
- Avoid methods with too many local variables ND1008
- Avoid unmaintainable code ND1009