This chapter is a bit more than a revision to the previous chapters. Much of what Fowler states, is outdated. Many of the questions he had at the time are not questions any more, they are certainties, some were even trendy and are currently outdated.
In any case, mixing his view at the time with my understanding of what is common practice now days, this is what I take out of this chapter.
Start your application by structuring the domain. Follow DDD principles, defining Bounded Contexts that relate to business concepts. Group your code units per conceptual relation as opposed to functional relation. For example, instead of putting all your controllers in one folder, do something like:
Consumer/Controller/... Supplier/Controller/...
And the same for deeper code units concepts:
Consumer/Event/SomeEvent/SomeEventInterface Consumer/Event/SomeEvent/SomeEvent Consumer/Event/AnotherEvent/AnotherEventListener
Leave the tooling decisions for later.
When it comes to data persistence, using the Data Mapper patterns with an ORM is a common practise now days, be it for complex or simple applications, because of ease of use and because a simple application tends to grow in complexity with time.
The global pattern to follow is MVC and the layering:
Layer | Object types | Description |
---|---|---|
Presentation (View & Controller) |
View | HTML templates usually generated using a template engine |
Input Controller | Filter and validate data | |
Application |
Application Controller | Application flow control |
Application Service | Application use cases | |
Domain (Model) |
Service | Contains business logic not associated with a specific set of data (Entity) |
Event | Represents a relevant event in the domain | |
Listener | Contains a method that handles an event | |
Entity | Data object with identity (ID), for example “User” | |
Collection | Set of data objects | |
Value Object | Data object without identity, for example “Date” | |
Persistence |
Repository | Contains the queries to a persistence tool |
ORM | Data persistence tool library |
Although in many cases we end up merging the input controller with the application controller, and sometimes the application is a simple CRUD application with no domain layer so the controllers end up talking directly to the repositories.