# Reference solution — end state of exercise 3 Derived from [IceCreamForecasting-Refactoring-Kata](https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata) (same license as the kata applies to the copied `IceCream.cs`). Run with `dotnet test test/BuyersTests.csproj` — the test passes deterministically without touching the pricing service. ## What changed vs the exercise start 1. The pricing call extracted into a lambda and slid to the top: `Func priceFor = flavour => priceList.PriceFor(flavour);` — the invocation in the loop stays put (`priceFor(flavour)`). 2. The loop extracted to `ShoppingListTotal(Buyer buyer, Func priceFor)` — static-free of `PriceList`; all inputs are parameters. (C# note: this one is an instance method because `ByName` uses the `buyers` field; the *extracted loop method itself* touches no fields. If you want it `static`, extract the loop only and keep the lookup in the composed method.) 3. No-arg `ShoppingListTotal(string)` overload keeps callers working; it passes the method group `priceList.PriceFor` as the "real" pricing function. 4. The test passes a pure lambda (`_ => 2`) through the overload — deterministic, glanceable: 2 flavours × 2 scoops × 2 = 8. ## Intermediate step (between pristine and this solution) ```csharp public int ShoppingListTotal(string buyerName) { Func priceFor = flavour => priceList.PriceFor(flavour); // ← extracted & slid var buyer = ByName(buyerName); var total = 0; foreach (var flavour in buyer.Favourites) { total += buyer.ScoopsOf(flavour) * priceFor(flavour); // ← invocation stays } return total; } ``` ## Variations (debrief / second round) - `_ => 5` — everything costs 5: Anke 20, Bram 10, Celine 20. - `flavour => flavour == IceCream.Chocolate ? 10 : 1` — chocolate is expensive. - Delete `PriceList` entirely: the extracted method no longer knows it exists — a step-4 move is now unblocked (move `ShoppingListTotal(Buyer, Func)` to a class without `PriceList`). - Role-interface next step: add `DiscountFor(IceCream)` to `PriceList` (a second side-effectful method) and feel why one lambda is no longer enough — extract `IPricing` instead.