Skip to content

Commit c20513a

Browse files
committed
Merge branch 'feature/Add_sprout_and_wrap' of https://github.com/Coding-Cuddles/slides into feature/Add_sprout_and_wrap
2 parents a75dcf9 + fe3ffe7 commit c20513a

File tree

2 files changed

+89
-55
lines changed

2 files changed

+89
-55
lines changed

legacy-code/01-sprout-wrap-worksheet.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
### Exercise 1: Sprout a Simple Class
22

3+
Topic 1: When refactoring legacy code, how do you decide whether to extract a Sprout Method versus
4+
creating a Sprout Class? What are the trade-offs in terms of testability, cohesion,
5+
and future maintenance?
6+
7+
Topic 2: How do you recognize when legacy behavior should remain within the current class versus
8+
when it’s time to sprout a new class for better separation of concerns?
9+
10+
Topic 3: In a large legacy system with high coupling, how can Sprout Method and Sprout Class be
11+
part of a broader strategy to gradually modernize the codebase?
12+
313
- **Objective:** Implement the Sprout Method on a simple class.
414
- **Task:**
515
- Create a `Car` class with a `drive()` method that prints `"The car is driving!"`.

legacy-code/01-sprout-wrap.md

Lines changed: 79 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,24 @@
11
---
22
title: Working Effectively with Legacy Code
3-
subtitle: Chapter 6 I Need to Make a Change. What Can I Do?
3+
subtitle: Chapter 6 - I Dont Have Much Time and I Have to Change It
44
...
55

66
# Pre-work
77

88
- Book: *Working Effectively with Legacy Code* by Michael Feathers
9-
- Focus: Chapter 6 change techniques
10-
- Optional: <https://michaelfeathers.silvrback.com/the-sprout-method>
11-
12-
# Chapters
13-
14-
::: columns
15-
16-
:::: column
17-
18-
| Chapter | Time |
19-
| ---------------------------| -------- |
20-
| Warmup | 00:00:00 |
21-
| Sprout Method | 00:05:00 |
22-
| Sprout Class | 00:15:00 |
23-
| Wrap Method | 00:25:00 |
24-
25-
::::
26-
27-
:::: column
28-
29-
| Chapter | Time |
30-
| ---------------------------| -------- |
31-
| Wrap Class | 00:35:00 |
32-
| Strategy Comparison | 00:45:00 |
33-
| Summary & Q&A | 00:55:00 |
34-
35-
::::
36-
37-
:::
9+
- Focus: Chapter 6: I Dont Have Much Time and I Have to Change It
3810

3911
# Timetable
4012

41-
| Activity | Time |
42-
| ----------------------------| ------ |
43-
| Warmup & Goals | 5 min |
44-
| Sprout Method & Class | 20 min |
45-
| Wrap Method & Class | 20 min |
46-
| Compare & Discuss | 5 min |
47-
| Summary & Q&A | 10 min |
13+
| Activity | Time |
14+
|-----------------------|--------|
15+
| Greetings, Warmup | 5 min |
16+
| Sprout Method & Class | 15 min |
17+
| Exercise 1 | 15 min |
18+
| Wrap Method & Class | 15 min |
19+
| Exercise 2 | 15 min |
20+
| Summary | 10 min |
21+
| Closing | 5 min |
4822

4923
# Warmup
5024

@@ -62,37 +36,87 @@ Use this to establish mental models and prepare learners to explore change-based
6236
- Call the new method from existing one
6337
- No edits to original logic
6438

65-
## Example
39+
# Legacy Code Example
6640

6741
```python
68-
def charge(customer):
69-
return new_charge_logic(customer)
42+
class VehicleLogger:
43+
def log_trip(self, vehicle_type, distance_km, fuel_used_liters):
44+
print(f"Trip: {distance_km} km")
45+
if vehicle_type == "gasoline":
46+
efficiency = distance_km / fuel_used_liters
47+
print(f"Fuel efficiency: {efficiency:.2f} km/l")
48+
elif vehicle_type == "electric":
49+
efficiency = distance_km / fuel_used_liters # misuse of field
50+
print(f"Energy efficiency: {efficiency:.2f} km/kWh")
51+
```
7052

71-
def new_charge_logic(customer):
72-
# New behavior
73-
return 42
53+
# Improved Code Example
54+
55+
```python
56+
class VehicleLogger:
57+
def log_trip(self, vehicle_type, distance_km, fuel_or_energy_used):
58+
print(f"Trip: {distance_km} km")
59+
self._log_efficiency(vehicle_type, distance_km, fuel_or_energy_used)
60+
61+
def _log_efficiency(self, vehicle_type, distance_km, amount_used):
62+
if vehicle_type == "gasoline":
63+
efficiency = distance_km / amount_used
64+
print(f"Fuel efficiency: {efficiency:.2f} km/l")
65+
elif vehicle_type == "electric":
66+
efficiency = distance_km / amount_used
67+
print(f"Energy efficiency: {efficiency:.2f} km/kWh")
7468
```
69+
\note{
70+
Benefits:
71+
Isolated new behavior (_log_efficiency) → easier to test
72+
Minimal change to existing method → reduced risk
73+
Future changes (e.g., hybrid logic) can be added safely to the new method
74+
}
7575

7676
# Sprout Class
7777

7878
- Create a new class for new behavior
7979
- Keeps old logic intact
8080
- Ideal for complex changes needing state
8181

82-
## Example
82+
# Legacy code Example
8383

8484
```python
85-
def calculate_invoice(cust):
86-
return InvoiceCalculator(cust).run()
87-
88-
class InvoiceCalculator:
89-
def __init__(self, customer):
90-
self.customer = customer
91-
def run(self):
92-
# New logic here
93-
pass
85+
class VehicleLogger:
86+
def log_trip(self, vehicle_type, distance_km, fuel_used_liters):
87+
print(f"Trip: {distance_km} km")
88+
if vehicle_type == "gasoline":
89+
efficiency = distance_km / fuel_used_liters
90+
print(f"Fuel efficiency: {efficiency:.2f} km/l")
91+
elif vehicle_type == "electric":
92+
efficiency = distance_km / fuel_used_liters
93+
print(f"Energy efficiency: {efficiency:.2f} km/kWh")
9494
```
9595

96+
# Improved code Example
97+
98+
```python
99+
class VehicleLogger:
100+
def log_trip(self, vehicle_type, distance_km, fuel_or_energy_used):
101+
print(f"Trip: {distance_km} km")
102+
if vehicle_type == "electric":
103+
EVLogger().log_efficiency(distance_km, fuel_or_energy_used)
104+
elif vehicle_type == "gasoline":
105+
efficiency = distance_km / fuel_or_energy_used
106+
print(f"Fuel efficiency: {efficiency:.2f} km/l")
107+
108+
class EVLogger:
109+
def log_efficiency(self, distance_km, energy_kwh):
110+
efficiency = distance_km / energy_kwh
111+
print(f"Energy efficiency: {efficiency:.2f} km/kWh")
112+
```
113+
\note{
114+
Benefits:
115+
New behavior is isolated in EVLogger
116+
We avoid changing or bloating the legacy method with EV-specific logic
117+
EVLogger is easy to test independently
118+
}
119+
96120
# Wrap Method
97121

98122
- Create a method that wraps (delegates to) the old method
@@ -173,8 +197,8 @@ public:
173197
};
174198
175199
int main() {
176-
std::unique_ptr<Coffee> coffee = std::make_unique<Coffee>();
177-
MilkDecorator decoratedCoffee(std::move(coffee));
200+
auto coffee = std::make_unique<Coffee>();
201+
MilkDecorator decorated_coffee(std::move(coffee));
178202
decoratedCoffee.cost();
179203
}
180204
```

0 commit comments

Comments
 (0)