๐ WAYPOINT LESSON
Checkpoint โ The Layered Checkout
โญโญ intermediateโณ 28 min read๐ Lesson 146 of 265
Compose the module: a service behind ports, dedup-then-map batch pricing, and clean guards โ the layered shape, with the seams the tests probe.
The gate (mini-build)
Three seams in one file, checked by the tests through the ports only:
- Ports โ
ICatalog { int Price(string sku); }andIBasket { void Add(string sku, int qty); int Count { get; } string FirstSku { get; } }(Count = total quantity added; FirstSku = the first sku ever added). - Service โ
Checkout(ICatalog, IBasket):Quote()returns"Total:" + price-of-FirstSku + " x " + Count; throwsInvalidOperationExceptionon an empty basket (Count == 0). Quote must work through the interfaces only โ no casting to concrete types. - Batch boundary โ
QuoteMany(string[] skus, ICatalog catalog)returns one price per sku (input order), pricing each distinct sku exactly once โ dedup, then map.
public static class Solution
{
public interface ICatalog { int Price(string sku); }
public sealed class MemCatalog : ICatalog; // "t1" -> 25, "t2" -> 40
public interface IBasket { void Add(string sku, int qty); int Count { get; } string FirstSku { get; } }
public sealed class MemBasket : IBasket;
public sealed class Checkout { public Checkout(ICatalog c, IBasket b); public string Quote(); }
public static int[] QuoteMany(string[] skus, ICatalog catalog);
public static bool Threw(Action a);
}