Refactoring Day 22 : Break Method

Today’s refactoring didn’t really come from any one source. It just named it although someone else may have something similar that’s named differently. If you know of anyone that has a name for this other than Break Method, please let me know.

This refactoring is kind of a meta-refactoring in the fact that it’s just extract method applied over and over until you decompose one large method into several smaller methods. This example here is a tad contrived because the AcceptPayment method isn’t doing as much as I wanted. Imagine that there is much more supporting code around each action that the one method is doing. That would match a real world scenario if you can picture it that way.

Below we have the AcceptPayment method that can be decomposed multiple times into distinct methods.

   1: public class CashRegister

   2: {

   3:     public CashRegister()

   4:     {

   5:         Tax = 0.06m;

   6:     }

   7:  

   8:     private decimal Tax { get; set; }

   9:  

  10:     public void AcceptPayment(Customer customer, IEnumerable<Product> products, decimal payment)

  11:     {

  12:         decimal subTotal = 0m;

  13:         foreach (Product product in products)

  14:         {

  15:             subTotal += product.Price;

  16:         }

  17:  

  18:         foreach(Product product in products)

  19:         {

  20:             subTotal -= product.AvailableDiscounts;

  21:         }

  22:  

  23:         decimal grandTotal = subTotal * Tax;

  24:  

  25:         customer.DeductFromAccountBalance(grandTotal);

  26:     }

  27: }

  28:  

  29: public class Customer

  30: {

  31:     public void DeductFromAccountBalance(decimal amount)

  32:     {

  33:         // deduct from balance

  34:     }

  35: }

  36:  

  37: public class Product

  38: {

  39:     public decimal Price { get; set; }

  40:     public decimal AvailableDiscounts { get; set; }

  41: }

As you can see the AcceptPayment method has a couple of things that can be decomposed into targeted methods. So we perform the Extract Method refactoring a number of times until we come up with the result:

   1: public class CashRegister

   2: {

   3:     public CashRegister()

   4:     {

   5:         Tax = 0.06m;

   6:     }

   7:  

   8:     private decimal Tax { get; set; }

   9:     private IEnumerable<Product> Products { get; set; }

  10:  

  11:     public void AcceptPayment(Customer customer, IEnumerable<Product> products, decimal payment)

  12:     {

  13:         decimal subTotal = CalculateSubtotal();

  14:  

  15:         subTotal = SubtractDiscounts(subTotal);

  16:  

  17:         decimal grandTotal = AddTax(subTotal);

  18:  

  19:         SubtractFromCustomerBalance(customer, grandTotal);

  20:     }

  21:  

  22:     private void SubtractFromCustomerBalance(Customer customer, decimal grandTotal)

  23:     {

  24:         customer.DeductFromAccountBalance(grandTotal);

  25:     }

  26:  

  27:     private decimal AddTax(decimal subTotal)

  28:     {

  29:         return subTotal * Tax;

  30:     }

  31:  

  32:     private decimal SubtractDiscounts(decimal subTotal)

  33:     {

  34:         foreach(Product product in Products)

  35:         {

  36:             subTotal -= product.AvailableDiscounts;

  37:         }

  38:         return subTotal;

  39:     }

  40:  

  41:     private decimal CalculateSubtotal()

  42:     {

  43:         decimal subTotal = 0m;

  44:         foreach (Product product in Products)

  45:         {

  46:             subTotal += product.Price;

  47:         }

  48:         return subTotal;

  49:     }

  50: }

  51:  

  52: public class Customer

  53: {

  54:     public void DeductFromAccountBalance(decimal amount)

  55:     {

  56:         // deduct from balance

  57:     }

  58: }

  59:  

  60: public class Product

  61: {

  62:     public decimal Price { get; set; }

  63:     public decimal AvailableDiscounts { get; set; }

  64: }

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

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Sean Chambers

I am a Senior software developer from Palm Coast, Florida. An advocate of Domain Driven Design, Behavior Driven Development, creator of FluentMigrator and community activist. I am married to my beautiful wife Erin and am the proud father of two wonderful children. I currently reside at ACI, a local insurance industry/mortgage software company that excels in creating solutions using Agile methodologies.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • cab

    I think Kent Beck defines this as composed method pattern.

  • Marek Rosa

    I think that the refactored version is missing the loop over the products and also a product should be passed to SubtractDiscounts.