The refactoring is now published as Slice on sammancoaching.org: https://sammancoaching.org/refactorings/slice.html - git mv ideas/split-loop-with-lambda -> ideas/slice-with-lambda - rename learning-hour file and update frontmatter name - update paths in tools/rehearse scripts and report title - update prose: 'Split Loop with Lambda' -> 'Slice with Lambda' in learning hour, exercise READMEs, storyboard, solution comments - link the published Slice refactoring from the pattern draft
43 lines
2.1 KiB
Markdown
43 lines
2.1 KiB
Markdown
# Exercise 3 — Buyers (Slice with Lambda, the pure rep)
|
|
|
|
A third, minimal example in the same kata theme: the sellers exist
|
|
(`DailyForecasts` — Steve, Julie, Francis), the buyers don't. This adds them:
|
|
`Buyers` computes a buyer's shopping-list total, and `PriceList` stands for an
|
|
external pricing service (it adds random surge pricing, so the test is flaky).
|
|
|
|
Written in **C#** (MSTest, .NET 10; verified with `dotnet test` on SDK
|
|
10.0.4xx — pristine test is flaky by design, solution is deterministic).
|
|
Run with `dotnet test test/BuyersTests.csproj`.
|
|
|
|
Contents:
|
|
|
|
- `csharp/` — pristine exercise repo: one loop, **one** lambda-able expression
|
|
(`priceList.PriceFor(flavour)`), nothing else. No printing, no conditionals,
|
|
no void calls.
|
|
- `solution/` — end state: extracted static method taking
|
|
`Func<IceCream, int> priceFor`, a no-arg overload passing the method group,
|
|
and a deterministic test with a pure lambda (`_ => 2`).
|
|
|
|
`IceCream.cs` is copied from
|
|
[IceCreamForecasting-Refactoring-Kata](https://github.com/emilybache/IceCreamForecasting-Refactoring-Kata)
|
|
(same license as the kata applies).
|
|
|
|
## Where this sits in the sequence
|
|
|
|
| example | lambda | teaches |
|
|
|---|---|---|
|
|
| 1. `longRangeForecast` weather loop (Java) | `LongFunction<Boolean>` | the pattern + the drift trap |
|
|
| 3. `Buyers` shopping list (C#, this one) | `Func<IceCream, int>` | the move in its purest form: one expression, nothing else |
|
|
| demo/next: `printSalesForecasts` → `SalesScorer`, `PriceList` → `Pricing` | role interface | when one function isn't enough (two side-effectful methods to stub) |
|
|
|
|
Next-time arc: marketing adds surge discounts, `PriceList` grows
|
|
`DiscountFor(...)` — two methods to stub → extract a role interface
|
|
(`IPricing`) instead of two lambdas. See the demo script's closing note.
|
|
|
|
## Verified
|
|
|
|
Built and run with `dotnet test` (SDK 10.0.4xx): solution green deterministically,
|
|
pristine test flaky (failed 2 of 3 runs, passed 1 — both surges rolled 0).
|
|
MSTest bumped to 3.6.4 (kata ships 2.1.1, whose transitive Newtonsoft.Json trips
|
|
a NU1903 vulnerability warning).
|