session 7: practical Rich Domain Models
this presentation started out quite good, but the longer it went on, the less I suspect that the presenter has implemented many real RDM apps)
- Anemic domain == not cost–effective; no competitive advantage
- Rich Domain: Persistence is a secondary concern
- challenges: Use RDM in a 3–tier architecture; leverage existing domain modelling skills; capture domain expertise
- goals: Manage complexity of domain and of software; improve test strategies; make refactoring possible
- prerequisites: Compexity – not worth it for a 2–month project. Investment + skills; committed team; compatible process; access to domain experts (I am not sure I buy this; most of these are sucess factors for any projects but none of them are essential)
- separation of concerns (layered architecture): importance is appreciated but is not well understood in the field (is it possible to have SoC without a layered architecture? I think maybe)
- You can't managed complexity with design patterns alone.
- Encapsulation is fundamental. Getters, and especially setters are eeeviilll. Enforce class invariants; don't expose internal state.
- Immutable classes: instead of changing object state, create a new object with the changed state and return that. (n.b. that private fields are accessible from other instances of the same class). Good example: java.lang.String – methods on it all return a new string. Dramatically reduces the complexity of large, modular applications, though it's probably overkill on simpler apps
- Entity classes are generally mutable (often a requirement of the persistence technology) , though you can use immutable classes and use the EntityManager / Session merge() method to reconcile changes. This doesn't work with immutable items in immutable collections though
- Aggregate objects: Don't expose the aggregation, and don't be mutable.
- Rich domain models are very testable – easy to mock and amenable to TFD
- Don't let your tests be longer than 15 lines (!)
- lessons learned: ORM – tools will impact the deisgn (availability of immutable entity semantics). Always use field access; Avoid LazyInitialisationException (OSIV is not the answer – alternatives include AJAX*, use fetch joins; use eager loading)
lessons learned – MVC – binding generally requires untyped setters (though spring binding + propertyEditors will avoid that)
* that's a stupid recommendation; each ajax call will increase the latency of your application: L~N(ajax–calls)