Is it possible to use NDepend to find class partitioning in an OOP language?

88 views Asked by At

Fort first let me better explain the context and the problem.

Context

We have a big class with dozen of methods; it violates many Software Engineering principles and this is clearly visible through a code metrics measure tool. See poor cohesion, too many method, and so on.

enter image description here

The problem When we try to split the class into smaller classes the problem arise with the instance methods. They need to access one or more field / property from the class and it may be useful to put all together the methods which access a specific field / property. The issue is clearly visible when trying to move a bunch of methods to a new class with Resharper → Refactor → Extract Class.enter image description here

Is it possible to partition the methods and fields which are connected together (have an high cohesion to use code metric terminology)?

2

There are 2 answers

2
Patrick from NDepend team On BEST ANSWER

Certainly we can do something interesting here, but this requires a partition algorithm and I am not sure which one to choose.

The query could look like:

// Replace "NHibernate.Cfg.Configuration" with your "Namespace.TypeName"
let type = Application.Types.WithFullName("NHibernate.Cfg.Configuration").Single()
let dicoFields  =  type.Fields
   .ToDictionary(f => f, f => f.MethodsUsingMe.Where(m => m.ParentType == f.ParentType))
let dicoMethods = type.Methods
   .ToDictionary(m => m, m => m.FieldsUsed.Where(f => f.ParentType == m.ParentType))

// The partition algorithm on both dicos here

from pair in dicoFields 
orderby   pair.Value.Count() descending
select new { pair.Key, pair.Value } 

//from pair in dicoMethods 
//orderby   pair.Value.Count() descending
//select new { pair.Key, pair.Value} 

Does this help moving forward?

NDepend field method partition algorithm

0
Revious On

Starting from the answer of @Patrick from NDepend team I've made some further investigation arriving to a some theory and some partially solving example.

First, to find also Property used by Methods you should replace FieldsUsed with MembersUsed in the query.

I've wrote two samples:

  • In the first the alghoritm is working as expected (the partition are not overlapping)
  • In the second there is an issue (there should be no elements in common)

To understand this partial solution you can look here and here :

I've tried to ask for some advice here, and I found out that this is an optimization problem called Steiner forest which involves oriented connected Graph.

Partitioning a graph into connected subgraphs with sets of vertices that must be in the same subgraph

See also: