Chapter 38 Key Takeaways

Architecture

  1. Separation of concerns is the most important architectural principle. Each unit has one job: FinanceCore for domain logic, FinanceDB for persistence, FinanceUI for presentation, FinanceExport for I/O, FinanceSync for background operations.

  2. Dependencies flow downward. The UI depends on the database, the database depends on the domain model, and the domain model depends on nothing. This layering makes the system testable, maintainable, and evolvable.

  3. The domain model is the foundation. Get the classes, fields, and relationships right, and everything else follows. Get them wrong, and no amount of UI polish will save you.

Object-Oriented Design

  1. Inheritance models "is-a" relationships. TExpense is a TTransaction. TIncome is a TTransaction. This enables polymorphism — code that operates on TTransaction works with both types.

  2. The Manager pattern coordinates operations on a collection of domain objects without coupling to the database or UI.

  3. Class methods (like ValidateAmount) are appropriate for stateless operations that do not depend on instance data.

Database Design

  1. Parameterized queries prevent SQL injection. Never concatenate user input into SQL strings. Always use ParamByName.

  2. Schema migrations use a version number stored in the database. On startup, the application checks the version and applies any necessary changes. This ensures database compatibility across application upgrades.

  3. Indexes speed up common queries. Create indexes on columns used in WHERE and ORDER BY clauses.

Testing

  1. Three levels of testing. Unit tests (automated, test business logic), integration tests (automated, test database operations), manual tests (test UI behavior and usability).

  2. Separation of concerns enables testability. Because FinanceCore has no dependencies on FinanceDB or FinanceUI, it can be tested in complete isolation.

  3. Tests should be independent. Each test creates its own data, runs its assertions, and cleans up. No test depends on another test's state.

The Validate-Persist-Display Pattern

  1. Every user action follows three steps in order: (1) Validate input, (2) Persist the change to the database, (3) Display the updated state. Validate first to prevent bad data. Persist before display to ensure the UI always reflects actual state.

Cross-Platform Deployment

  1. Native compilation means no runtime dependencies. The user downloads a binary and runs it. No Python, no Java, no .NET required.

  2. Cross-platform is a source-code property. The same Pascal source compiles on Windows, Linux, and macOS. The binaries are platform-specific — you must compile (or cross-compile) for each target.

The Bigger Lesson

  1. Everything from this textbook was used. Variables, types, control flow, procedures, functions, arrays, strings, records, pointers, classes, inheritance, polymorphism, interfaces, generics, recursion, sorting, searching, trees, graphs, GUI development, databases, networking, threading, and OS integration — all thirty-seven chapters contributed to PennyWise 2.0.

  2. Discipline enables creativity. The most creative software comes from the most disciplined engineering. PennyWise is not creative despite its strong types and explicit memory management — it is creative because of them. Constraints are the scaffolding on which creativity climbs.