Lesson 1
Sprout Method - Reducing Risk of Adding New Features
Introduction

Welcome to this course. The focus will be "Using Sprout and Wrap Techniques for Refactoring and to Expand Capabilities"! To start off, we will explore the sprout method, a technique that can, among other things, help us safely add new features to existing codebases. This method is particularly useful when working with established codebases, where the risk of breaking existing functionality is high. By the end of this lesson, we'll understand how to use the sprout method to enhance our code's modularity and testability.

The Sprout Method Explained

The sprout method is a refactoring technique that involves creating new methods or classes to encapsulate additional functionality. This approach allows us to introduce new features without altering existing code, thereby minimizing the risk of breaking it. By isolating new behavior in separate methods, we can improve the modularity of our code, making it easier to understand and maintain. The sprout method is particularly effective in scenarios where we need to expand capabilities while preserving the original behavior.

Step-by-Step Implementation

Let's walk through a step-by-step guide on how to apply the sprout method to add new features. We'll use a simple example to illustrate the process:

C#
1public class OrderProcessor 2{ 3 public bool ProcessOrder(Order order) 4 { 5 decimal totalAmount = 0; 6 foreach (var item in order.Items) 7 { 8 decimal itemPrice = item.Price * item.Quantity; 9 totalAmount += itemPrice; 10 } 11 12 order.ProcessedAt = DateTime.Now; 13 order.OrderTotal = totalAmount; 14 return true; 15 } 16}

Suppose we want to add a surcharge to the order total. Instead of modifying the existing ProcessOrder method, we can create a new method called ProcessOrderWithSurcharge:

C#
1public bool ProcessOrderWithSurcharge(Order order, decimal surchargePercentage) 2{ 3 if (surchargePercentage < 0) 4 { 5 throw new ArgumentException("Surcharge percentage cannot be negative", nameof(surchargePercentage)); 6 } 7 8 ProcessOrder(order); 9 10 decimal surchargeAmount = order.OrderTotal * (surchargePercentage / 100); 11 order.OrderTotal += surchargeAmount; 12 order.SurchargeAmount = surchargeAmount; 13 return true; 14}

By creating a new method, we encapsulate the additional functionality without altering the existing ProcessOrder method. This approach reduces the risk of introducing bugs into the original code.

Independent Testing of New Functionality

By isolating new features in separate methods, we can write targeted tests that focus solely on the new functionality. Here's an example of how we might test the ProcessOrderWithSurcharge method:

C#
1[Fact] 2public void ProcessOrderWithSurcharge_ValidOrder_CalculatesTotalWithSurcharge() 3{ 4 // Arrange 5 var order = new Order 6 { 7 Items = new List<OrderItem> 8 { 9 new OrderItem { Price = 100, Quantity = 2 }, 10 new OrderItem { Price = 50, Quantity = 1 } 11 } 12 }; 13 decimal surchargePercentage = 10; 14 15 // Act 16 _processor.ProcessOrderWithSurcharge(order, surchargePercentage); 17 18 // Assert 19 Assert.Equal(275M, order.OrderTotal); // (200 + 50) * 1.1 20 Assert.Equal(25M, order.SurchargeAmount); // (200 + 50) * 0.1 21}

This test verifies that the ProcessOrderWithSurcharge method correctly calculates the order total with the surcharge applied.

Key Takeaways and Preparation for Practice

In this lesson, we've explored the sprout method, a powerful technique for safely adding new features to existing codebases. By creating new methods to encapsulate additional functionality, we can minimize the risk of breaking existing code and improve modularity. We've also seen how to test new functionality independently to ensure its correctness. As we move on to the practice exercises, we'll have the opportunity to apply these concepts and reinforce our understanding of the sprout method. Good luck, and enjoy the journey of enhancing our coding skills!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.