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:
- 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.
- State is one collection, not five globals. A
Libraryowns astd::vector<Book>; nothing else touches it. Modules 2-4 gave you the class, Module 8 the ownership vocabulary for who holds it. - 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.