Editor campaigns/Persistence and domain layer notes

Goals

 * Isolate all direct database access and code dependent on the database implementation.
 * Keep persistence logic separate from higher-level coordinating functions (logging, saving or restoring page revisions, checking user rights) and presentation logic (i18n messages, html construction, request details).
 * Expose an intuitive, opaque persistence PHP API to other layers of the system.
 * Keep open the possibility of switching out the DB implementation for a structured data store at a later date.
 * Optimize DB use:
 * Let the API consumer request only the fields needed, as per these guidelines.
 * Use unique indexes and appropriate SQL techniques to avoid locking reads.
 * Write tests as we go and aim for full code coverage.
 * Support the growth of the domain in a modular way for diverse use cases (edit-a-thons, courses, projects).

Adding general stuff that could go in core

 * Keep general additions compact.

Domain-driven design
In domain-driven design, architecture revolves around a model of what the software is “about” in the real world. That model goes in the domain layer. The main sources I've used for this are Patterns of Enterprise Application Architecture, by Martin Fowler, and Domain-Driven Design: Tackling Complexity in the Heart of Software, by Eric Evans. Here are some points from those books: This seems important since one of the problems with the last patch set (21) for the persistence layer was that some logic was hard to see.
 * "With a Domain Model [...] we build a model of our domain which, at least on a first approximation, is organized primarily around the nouns in the domain." (Fowler, p. 26)
 * "The goal of domain-driven design is to create better software by focusing on a model of the domain rather than the technology.” (Evans, p. 148)
 * "In a MODEL-DRIVEN DESIGN, the software constructs of the domain layer mirror the model concepts. It is not practical to achieve that correspondence when the domain logic is mixed with other concerns of the program. Isolating the domain implementation is a prerequisite for domain-driven design." (Evans, p. 75)
 * "The domain objects, free of the responsibility of displaying themselves, storing themselves, managing application tasks, and so forth, can be focused on expressing the domain model. This allows a model to evolve to be rich enough and clear enough to capture essential business knowledge and put it to work." (Evans, p. 70-71)
 * Domain-driven design makes a lot of sense when you expect a system to grow more complex (Evans, p. 78).
 * The problem with not following this methodology is that as a system grows, “more and more domain rules become embedded in query code or simply lost.” (Evans, p. 149) In such cases “[W]e are no longer thinking about concepts in our domain model. Our code will not be communicating about the business; it will be manipulating the technology of data retrieval.” (150)