Skip to content

Table of Contents

Month 5 · Week 3 — Exercises (architecture, DI, domain modeling, caching)

Standard-library-only Go packages with table-driven tests. They rebuild the architectural mechanics of Week 3 — ports & adapters, value objects, and the cache-aside pattern — so go test runs anywhere with no wire, no Redis, and no network.

How to run

go test ./exercises/month-05/week-3/...
# or one at a time, verbose:
go test -v ./exercises/month-05/week-3/ports

Prompts

  1. ports/ — Build a hexagonal slice: a Task entity, a TaskRepository OUTBOUND port defined next to its consumer, a Service that depends on the port via constructor injection, and an in-memory MemRepo adapter. Enforce domain sentinels (ErrNotFound, ErrExists, ErrEmptyID) and wrap with %w so errors.Is matches. A fake adapter proves the service delegates only through the port. Concepts: ports & adapters, dependency inversion, constructor injection (Days 127–128).

  2. money/ — Implement a Money VALUE OBJECT: a validating New (3-letter ISO code, normalized/upper-cased), Add/Sub that refuse mismatched currencies (ErrCurrencyMismatch), value equality via == (comparable struct), integer minor-units, and a sign-aware String(). Fields are unexported so every Money is valid by construction. Concepts: value objects, invariants, "make invalid states unrepresentable" (Day 130).

  3. cacheaside/ — Implement the cache-aside read pattern: Get returns a cached value on a live hit, otherwise calls the injected Loader, populates with a TTL, and counts hits/misses; Invalidate drops a key; expired entries reload; loader errors are NOT cached. An injected Clock makes TTL expiry deterministic (no sleeping in tests). Concepts: cache-aside, TTL/staleness, delete-on-write, injected clock (Day 132).

Results

Exercise Focus go test
ports hexagonal port + adapter + injected service
money value object / invariants / value equality
cacheaside cache-aside read-through, TTL, invalidation