Calculating Lack of Cohesion of Methods with Roslyn

Tags: roslyn, LCOM, metrics

The single responsibility principle is the first of the SOLID principles. While that doesn't make it the most important, it is one of the important design concerns in object-oriented programming.

Lack of Cohesion of Methods (LCOM) is one of the metrics which can be used to analyze whether a class is violating the single responsibility principle. The metric calculates whether the fields in a class are used across the methods and properties, or whether there is a split. A split means that some methods access some fields and some methods access other fields. This means there is no internal interaction between these pillars, and they be in separate classes so they will be changed for only a single reason.

The formula for calculating LCOM (Henderson-Sellers) is:

LCOM HS = (memberCount – sumFieldUsage/fieldCount)/(memberCount - 1)

Where:

memberCount = number of methods in class (including getter/setter methods and constructors.
fieldCount = number of instance fields in the class.
sumFieldUsage = the sum of the number of methods accessing a particular field.

Calculating LCOM

Using Roslyn it is possible to calculate the LCOM from the source code.

var MemberKinds = { CommonSymbolKind.Event, CommonSymbolKind.Method, CommonSymbolKind.Property };
ClassDeclartionSyntax classDeclaration = SomeClassDeclaration;
var symbol = (ITypeSymbol)semanticModel.GetDeclaredSymbol(classDeclaration);
var members = symbol.GetMembers();
var memberCount = members.Where(x => MemberKinds.Contains(x.Kind)).Count();
var fields = members.Where(x => x.Kind == CommonSymbolKind.Field).ToArray();
var fieldCount = fields.Length;

var sumFieldUsage = (double)fields
	.Sum(f => f.FindReferences(solution)
			   .SelectMany(x => x.Locations)
			   .Count());

var lcomhs = (memberCount - sumFieldUsage / fieldCount) / (memberCount - 1);

For lcomhs values of 1 or greater indicate cause for concern if there are more than 10 members and more than 10 fields.

In my opinion having more than 10 fields in a class should be cause for cnocern in itself. This is one of the problems with metrics, that they were thought up in a time where coding practices were different because languages were different. You may want to experiment which thresholds work for your setup.

Latest Tweets