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.
Post Footer automatically generated by Add Post Footer Plugin for wordpress.
