Our Thoughts

Single Responsibility Refactoring with Resharper

Posted by Kris Coleman on Jun 14, 2017 11:00:00 AM
Find me on:

I was working on a deadline – trying to move quickly and get it done. I needed to write a class to continue my work, but once I had finished, I couldn’t help but notice that I had violated the Single Responsibility Rule.

Here’s a class outline.

Class Outline

Notice that there are two things going on here.

  1. Getting Invoices
  2. Processing Invoices 

(There’s a third thing too.. translating. But that’s a static method, so we won’t count that.)

Stick the cursor at the top of the class, in the class name. Then use Resharper to Extract a class.

Extract a class

My current class is a Processor, and my second class should be a Finder. So I’ll call my extracted class a “Finder”. When I start to select which methods that I want to move to my extracted class, Resharper will warn me about dependent methods that will break my build if I don’t grab them too.

Select methods to move to extracted class

All I need to do is “Fix the Hate” and select all of my “Find” methods to isolate my “Find” responsibility. Then everything is happy.

Isolate Find Responsibility

Resharper will automatically add a field at the top of my class for my new extracted class.

Added Resharper Field

And it also updates ALL of my usages of those methods to the new extracted class. Changing from this:

Original method

To this:

Updated method

What a nice class outline.

Class outline

And the processor looks a lot cleaner.

Processor

I now have two single Responsibilities. All I really have to do now is refactor a bit for Inversion of Control. I’ll do that using Resharper’s Extract Interface, and then I’ll create a new constructor and pass in a concrete of my new IFinder interface.

Put your cursor at the top of the Finder class, and you can extract interface from the Resharper menu.

Extract interface form Resharper

Extract interface from Resharper modal

Extract interface from Resharper result

Then I’ll change from this:

Rename Original

To this:

Rename updated

and initialize it from a new Constructor. 

New constructor 1

New constructor 2

And boom! I refactored for both Single Responsibility and the Dependency Inversion Principles.                   

Fixing usages is easy.

Fixing usages 1

Fixing usages 2

Now, all I need to do is implement Dependency Injection!

 

 

Be a better programmer: Best Practices and Test Driven Development

Topics: Development Trends