The TDD Guy

Adventures in Test-Driven Development!

Find Ed on GitHub!

CopperStarSystems (Ed Mays)
Copper Star Systems, LLC
Phoenix, AZ
https://www.codementor.io/copperstarconsulting
Joined on Jul 10, 2013
40 Public Repositories
AspNet-DataAccess-Example
AspNet.WebApi.Example
AspNetCore20ViewComponents
AzureFunctions.Sample
basic-mvvm-samples
bootstrap-grid-example
bootstrap-modals
CopperStarSystems.WindsorHelpers
DataTemplating-With-Triggers
DelegatesExample
DependencyInjection.GettingStarted
dev-spaces
DispatcherTimerTestingExample
dotnetcore-sample
ElmahExample
EventsExample
exploring-wcf
handlebars-task-list
international-phone-number.poc
jquery-ajax-example
mono
MVC-StudentPairingExample
mvc6-view-components
mvvm-drag-drop
MvvmMasterDetail
NetCore.Globalization.Example
postsharp-example
SelfBootstrappingAssembly
serilog-sinks-datadog-logs
tdd-hello-nunit
9 Public Gists
You are here: Home » Code Quality » Battling Complexity: Tell It to the Monkey

Battling Complexity: Tell It to the Monkey

January 15, 2017 by Ed Leave a Comment

My students often ask me “How can I tell if my code is too complex?”  There are a lot of different answers to that question, but I thought I would share my favorite complexity detection tool with you – a tiny purple stuffed monkey:

Manage complexity by explaining your code to an inanimate object
Look deep into my eyes and explain the code…

I adopted the idea from a great concept called “Rubber Duck Debugging” that I read about in the phenomenal book “The Pragmatic Programmer”.  I’m not really a duck guy so I went with a monkey instead.

The basic concept behind it all is to explain your code to your duck/monkey/other inanimate object, step by step.  If it takes you longer than 1-2 minutes to explain a method, it’s probably too complex and should be refactored to something simpler.

Well that sounds great and all, but how exactly do I reduce a method’s complexity?

Good catch – “Just simplify it” is unacceptably hand-wavey and doesn’t really provide much guidance.  One good approach for reducing complexity is called the Single Level of Abstraction Principle (SLAP).  As might be apparent from the name, SLAP recommends that all statements within a given method exist at the same “Level of Abstraction”.

OK, but what’s a Level of Abstraction?

Let’s start with an example of code that does not follow SLAP guidelines:

Admittedly this is a contrived example, but even this simplistic code takes upwards of a minute to explain to the monkey.  The main issue is that we’re bouncing around at various low levels, dealing with streams, streamreaders, lists, strings, etc. and it’s kind of hard to wrap your head around.

Contrast this with a somewhat more “SLAP-ified” version of this class:

Notice how the DoSomeWork method now reads much like a to-do list:

  • Open a file
  • Iterate over the file until we are out of data
    • Read the next line
    • Prepare the fields
    • Extract the desired data
    • Add the data to our list

Explaining the methods we extracted should take no more than a few seconds apiece since they’re mostly descriptively-named one-liners.

OK, Awesome – Surely It Can’t Get Cleaner Than That!

It’s definitely cleaner, but there’s still just a bit more complexity in DoSomeWork than I’d like to see, particularly inside the while loop.

Looking at our while loop, it appears that whatever we’re doing to each line is repetitive, in that we’re performing the same 3 steps for every single line.  In that spirit, let’s extract out a ProcessLine method that encapsulates those 3 calls:

Now we can logically drill down into the implementation:

  • At a high level, we can see that DoSomeWork opens a file, loops through it, and performs some operation on each line of the file
  • One level down is the ProcessLine function, where we can clearly see we need to get some field data, extract the desired value, and add it to a list
  • If we really need to get into the gritty details, we have the low-level methods we originally extracted

Conclusion:

Managing complexity is a vital aspect of software engineering in general.  Identifying complexity becomes easy when using Rubber Duck Debugging, while approaches like SLAP improve code readability by encapsulating low-level concepts within higher-level methods that clearly express the code’s intent in domain-specific language.

So don’t hesitate, Tell it To The Monkey!

PS:  To my readers who also happen to be fans of The Simpsons… Yes, that is a Purple Monkey Dishwasher 🙂

 

 

 

 

 

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on Google+ (Opens in new window)

Related

Filed Under: Code Quality, Practices, Refactoring, Test-Driven Development, Uncategorized Tagged With: Code Quality, SLAP, TDD

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

© 2021 · The TDD Guy