Assemblies with poor cohesion (RelationalCohesion)

Rule ND1405 Architecture

Warns about assemblies with a wrong Relational Cohesion: the number of relationships between the assembly's types divided by the number of types (average types used per type). Classes inside an assembly should be strongly related, so cohesion should be high. Assemblies with fewer than 20 types are ignored.

How to fix

Matches reveal either specific coding constraints (like generated code) or design issues; in the latter case plan refactoring to increase overall design and maintainability.

Severity is Low: Relational Cohesion informs about code structure but is not actionable. Fixing actionable Architecture and Code Smells issues will necessarily increase the scores.

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>Assemblies with poor cohesion (RelationalCohesion)</Name>
// <Id>ND1405:AssembliesWithPoorRelationalCohesion</Id>

warnif count > 0 from a in Application.Assemblies 

// Build the types list on which we want to check cohesion
// This is the assembly 'a' type, minus enumeration
// and types generated by the compiler.
let types = a.ChildTypes.Where(
   t => !t.IsGeneratedByCompiler &&
        !t.IsEnumeration &&
         JustMyCode.Contains(t))
        // Absolutly need ToHashet() to have fast Intersect() calls below.
        .ToHashSetEx()

// Relational Cohesion metrics is relevant only if there are enough types
where types.LongCount()> 20

// R is the total number of relationship between types of the assemblies. 
let R = types.Sum(t => t.TypesUsed.Intersect(types).Count())

// Relational Cohesion formula
let relationalCohesion = (double)R / types.Count
where relationalCohesion  < 0.8

select new { 
  a, 
  a.ChildTypes,
  relationalCohesion, 
  a.RelationalCohesion,
  
  Debt = 10.ToMinutes().ToDebt(),
  Severity = Severity.Low
}

//<Expl>
// The *{0}* has a *Relational Cohesion* value of {2}.
// This suggests that the types within this assembly are loosely coupled, 
// potentially signaling an architectural concern.
//</Expl>

//<Desc>
// Warns about assemblies with a wrong *Relational Cohesion*: the number of
// relationships between the assembly's types divided by the number of types
// (average types used per type). Classes inside an assembly should be
// strongly related, so cohesion should be high. Assemblies with fewer than
// 20 types are ignored.
//</Desc>

//<HowToFix>
// Matches reveal either specific coding constraints (like generated code) or
// design issues; in the latter case plan refactoring to increase overall
// design and maintainability.
//
// Severity is **Low**: *Relational Cohesion* informs about code structure
// but **is not actionable**. Fixing actionable **Architecture** and
// **Code Smells** issues will necessarily increase the scores.
//</HowToFix>

Architecture: all 13 items