Skip to content

Day 133 — Week Review + Recall

Month 5 · Week 3 · ⬅ Day 132 · Day 134 ➡ · Journal index

🎯 Learning Objective

Consolidate Week 3 — hexagonal architecture, manual & wire DI, domain modeling, ADRs, and cache-aside — through active recall and a written retrospective.

📚 Topics

  • Ports & adapters · constructor injection · wire codegen
  • Value objects vs entities · ADRs · cache-aside + TTL

📖 Reading / Sources

📝 Notes

  • This is a lighter review day — the full retrospective, re-quiz, metrics, and next-week goals live in week-3-review.md.
  • One-line throughline: good architecture is about controlling dependencies and protecting invariants. Ports point dependencies inward, DI supplies them at the edge, value objects guard validity at the boundary, ADRs record why, and cache-aside adds speed without coupling the core to Redis → [[hexagonal]] [[dependency-injection]] [[value-object]].
  • The pattern that recurred all week: the core depends on an interface; a concrete adapter is plugged in at a single composition root — true for the repository port, the injected clock, and the cache.

💻 Code Examples

// The week in one shape — a core that owns its port and receives the adapter:
type AccountRepository interface {
    Find(id string) (*Account, error)
    Save(a *Account) error
}
func NewLedger(repo AccountRepository) *Ledger { return &Ledger{repo: repo} }

Run this week's stdlib models: go run ./examples/month-05/hexagonal · .../manualdi · .../domainmodel · .../cacheaside

🏋️ Exercises / Practice

Exercise Status Link
All Week 3 exercises pass go test exercises/month-05/week-3

🐛 Mistakes Made

  • None new today — review day. Carried-over fixes (interface-in-consumer, delete-on-write, unexport-then-validate) are logged in their day notes.

❓ Open Questions

  • See the consolidated open questions in the week review.

🧠 Active Recall (answer without looking)

  1. Q: Where do you define a repository interface in a hexagonal Go project, and why there?
AIn the *consumer* (the domain core) package, not the adapter. Go satisfies interfaces implicitly, so the core declares the port it needs and the adapter implements it — keeping the dependency arrow pointing inward and avoiding an import cycle.
  1. Q: Contrast manual DI with wire, and contrast a value object with an entity.
AManual DI wires the graph by hand in a composition root; `wire` *generates* that same wiring as plain Go at compile time (no reflection/runtime container). A value object is identity-less, immutable, and compared by value; an entity has an identity that persists through field changes and is compared by identity.

🪶 Feynman Reflection

Week 3 turned "a gRPC service that works" into "a gRPC service built to last." I learned to put the business rules in a clean core, let it depend only on interfaces it owns, and plug real infrastructure in at one wiring point — by hand, or with wire. I learned to make bad data impossible by validating value objects at the boundary, to write down why I chose each big thing in an ADR, and to bolt on a cache without letting Redis bleed into the domain. The unifying idea is the same one from interceptors last week: depend on a shape, inject the thing.

🕳️ Knowledge Gaps

  • Unit-of-work / transactions across repositories, and cache-stampede defenses in production — top of the follow-up list.

✅ Summary

Week 3 done: I can lay out a hexagonal service, wire it with manual or wire DI, model a domain with value objects and entities, record decisions as ADRs, and add cache-aside caching with TTL. Confidence solidly in the 3–4 band.

⏭️ Next Steps / Prep for Tomorrow


Time spent Difficulty Confidence
90 min 🟦⬜⬜⬜⬜ 🟦🟦🟦🟦⬜

Suggested commit: docs(journal): month 5 week 3 review (day 133)