Skip to main content

Project Architecture: The Three Seams

intermediate25 min readLesson 127 of 204

App vs Library vs persistence: responsibilities, ownership, and where the boundaries live.

Before writing a line: the shape of the thing you are building. A small library manager with four responsibilities, each in its own class:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  App            โ€” the CLI loop (menu, I/O)  โ”‚
โ”‚    โ”‚ owned by unique_ptr                        โ”‚
โ”‚  Library        โ€” the rules (add, borrow)   โ”‚
โ”‚    โ”‚ owns                                       โ”‚
โ”‚  vector<Book>   โ€” the state (records)       โ”‚
โ”‚    โ”” serialized to                             โ”‚
โ”‚  string content โ€” the persistence (M10)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Three architecture decisions worth making consciously:

  1. The App knows menus; the Library knows rules. The app loop parses input and prints; it never edits the book vector directly. When you later swap a CLI for a GUI, the Library survives untouched.
  2. State is one collection, not five globals. A Library owns a std::vector<Book>; nothing else touches it. Modules 2-4 gave you the class, Module 8 the ownership vocabulary for who holds it.
  3. Persistence is a boundary, not a sprinkle. Exactly two functions (serialize, deserialize) convert between records and text. Module 10's parsing discipline lives here, and nowhere else.

This layering is a miniature of real systems: presentation, domain, storage. The names change; the seams do not.

Now practice

Capstone seamsThe three graded seams: borrow state machine, persistence round-trip, and validation boundary.3 challenges ยท ยท ~45 min