Refactoring Day 27 : Remove God Classes


Often with legacy code bases I will often come across classes that are clear SRP violations. Often these classes will be suffixed with either “Utils” or “Manager”. Sometimes they don’t have this indication and are just classes with multiple grouped pieces of functionality. Another good indicator of a God class is methods grouped together with using statements or comments into seperate roles that this one class is performing.

Over time, these classes become a dumping ground for a method that someone doesn’t have time/want to put in the proper class. The refactoring for situations like these is to break apart the methods into distinct classes that are responsible for specific roles.

   1: public class CustomerService

   2: {

   3:     public decimal CalculateOrderDiscount(IEnumerable<Product> products, Customer customer)

   4:     {

   5:         // do work

   6:     }

   7:  

   8:     public bool CustomerIsValid(Customer customer, Order order)

   9:     {

  10:         // do work

  11:     }

  12:  

  13:     public IEnumerable<string> GatherOrderErrors(IEnumerable<Product> products, Customer customer)

  14:     {

  15:         // do work

  16:     }

  17:  

  18:     public void Register(Customer customer)

  19:     {

  20:         // do work

  21:     }

  22:  

  23:     public void ForgotPassword(Customer customer)

  24:     {

  25:         // do work

  26:     }

  27: }

</div> </div>

The refactoring for this is very straight forward. Simply take the related methods and place them in specific classes that match their responsibility. This makes them much finer grained and defined in what they do and make future maintenance much easier. Here is the end result of splitting up the methods above into two distinct classes.

   1: public class CustomerOrderService

   2: {

   3:     public decimal CalculateOrderDiscount(IEnumerable<Product> products, Customer customer)

   4:     {

   5:         // do work

   6:     }

   7:  

   8:     public bool CustomerIsValid(Customer customer, Order order)

   9:     {

  10:         // do work

  11:     }

  12:  

  13:     public IEnumerable<string> GatherOrderErrors(IEnumerable<Product> products, Customer customer)

  14:     {

  15:         // do work

  16:     }

  17: }

  18:  

  19: public class CustomerRegistrationService

  20: {

  21:  

  22:     public void Register(Customer customer)

  23:     {

  24:         // do work

  25:     }

  26:  

  27:     public void ForgotPassword(Customer customer)

  28:     {

  29:         // do work

  30:     }

  31: }

</div> </div>

This is part of the 31 Days of Refactoring series. For a full list of Refactorings please see the original introductory post.

Refactoring Day 26 : Remove Double Negative