Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Identify Shotgun Surgery Using NDepend

DZone's Guide to

How to Identify Shotgun Surgery Using NDepend

A method suffers from shotgun surgery if it is called many times from many other classes. You can identify it by looking at changing methods and changing classes.

· Performance Zone
Free Resource

Discover 50 of the latest mobile performance statistics with the Ultimate Guide to Digital Experience Monitoring, brought to you in partnership with Catchpoint.

In the previous articles. in this series we’ve seen:

In this article, we’ll see how to identify an afferent (incoming) coupling code smell: Shotgun Surgery.

Shotgun Surgery Detection Strategy

A method suffers from shotgun surgery if it is called many times from many other classes. Object-Oriented Metrics in Practice by Michele Lanza and Radu Marinescu proposes the following detection strategy for Shotgun Surgery:

(CM > Short Memory Cap) AND (CC > Many)

This detection strategy uses two metrics:

  • CM (Changing Methods): The number of methods that call the measured method.
  • CC (Changing Classes): The number of classes in which the changing methods are defined.

This detection strategy uses generally-accepted meaning thresholds. I used seven as the value for short memory cap and 10 for many.

Metrics Definitions

Let’s go over the definitions for the used metrics and how to implement them with NDepend. For a more detailed definition, be sure to check Appendix A.2 of Object-Oriented Metrics in Practice. If you’re not familiar with CQLinq, check out the NDepend documentation or my blog post on how to query your code base.

CM (Changing Methods)

This metric counts the number of distinct methods that call the measured method. We only care about our own code for both caller methods and measured methods. However, since framework code doesn’t call our code, we can rely on the NbMethodsCallingMe NDepend metric.

// <Name>CM</Name>
from m in JustMyCode.Methods
let cm = m.NbMethodsCallingMe
orderby cm descending
select new { m, cm }

CC (Changing Classes)

This metric counts the number of classes in which the changing methods are defined.

// <Name>CC</Name>
from m in JustMyCode.Methods
let changingClasses = m.MethodsCallingMe.Select(method => method.ParentType).ToHashSet()
let cc = changingClasses.Count()
orderby cc descending
select new { m, cc, changingClasses }

Putting It All Together

Now that we know how to compute each of the required metrics, let’s see how the detection strategy looks like:

// <Name>Shotgun Surgery</Name>
warnif count > 0
// ** Thresholds **
let ShortMemoryCap = 7
let Many = 10

// ** Detection Strategy **
from m in JustMyCode.Methods
let methodsCallingMe = m.MethodsCallingMe
let changingClasses = methodsCallingMe.Select(method => method.ParentType).ToHashSet()
let cm = m.NbMethodsCallingMe
let cc = changingClasses.Count()

where
 // Operation is called by too many other methods
 cm > ShortMemoryCap && 
 // Incoming calls are from many classes
 cc > Many
select new { m, cm, cc, changingClasses, methodsCallingMe }

And that's it!

Is your APM strategy broken? This ebook explores the latest in Gartner research to help you learn how to close the end-user experience gap in APM, brought to you in partnership with Catchpoint.

Topics:
performance ,ndepend ,tutorial

Published at DZone with permission of Victor Chircu, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}