Chapter 38 Key Takeaways
Architecture
-
Separation of concerns is the most important architectural principle. Each unit has one job:
FinanceCorefor domain logic,FinanceDBfor persistence,FinanceUIfor presentation,FinanceExportfor I/O,FinanceSyncfor background operations. -
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.
-
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
-
Inheritance models "is-a" relationships.
TExpenseis aTTransaction.TIncomeis aTTransaction. This enables polymorphism — code that operates onTTransactionworks with both types. -
The Manager pattern coordinates operations on a collection of domain objects without coupling to the database or UI.
-
Class methods (like
ValidateAmount) are appropriate for stateless operations that do not depend on instance data.
Database Design
-
Parameterized queries prevent SQL injection. Never concatenate user input into SQL strings. Always use
ParamByName. -
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.
-
Indexes speed up common queries. Create indexes on columns used in
WHEREandORDER BYclauses.
Testing
-
Three levels of testing. Unit tests (automated, test business logic), integration tests (automated, test database operations), manual tests (test UI behavior and usability).
-
Separation of concerns enables testability. Because
FinanceCorehas no dependencies onFinanceDBorFinanceUI, it can be tested in complete isolation. -
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
- 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
-
Native compilation means no runtime dependencies. The user downloads a binary and runs it. No Python, no Java, no .NET required.
-
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
-
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.
-
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.