|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
For Java EE applications based on type-dependent algorithms, a domain-driven design that leverages object-orientation is better than a procedurally implemented service-oriented architecture. Adam Bien explains how and why object-oriented persistence makes your domain-driven application's code more efficient, maintainable, and testable. Level: Advanced
In "Lean service architectures with Java EE 6," I discussed how to implement a maintainable service-oriented architecture (SOA) that is based on anemic persistent objects and transient, stateless services. In this follow-up article, you'll learn about an architectural approach that is the exact opposite of that. What ties together the two architectures is that both can be implemented with Java EE 6 and, in particular, Enterprise JavaBeans (EJB).
As I'll explain in this article, you can build domain-driven applications with "real" objects -- objects that comprise encapsulated state and well-defined behavior. Whereas SOA is stateless and tries to hide a component's implementation, domain-driven applications are mostly stateful and aim to expose the domain objects to the user as directly and conveniently as possible.
The vast majority of J2EE and Java EE applications are built in a procedural way. The business logic is decomposed into tasks and resources, which map, respectively, to services and anemic, persistent entities. Such an approach works surprisingly well until type-specific behavior for domain objects must be realized. Then the lack of object orientation in the persistence layer can cause problems.
Attempts to implement object-oriented algorithms with procedural techniques end up in many instanceof checks and/or lengthy if-statements. Such type checks are required because in the SOA world, domain objects are anemic, so inheritance doesn't pay
off. Even if inheritance is used to design the domain model, object orientation's most powerful feature -- polymorphic behavior
-- isn't leveraged at all.
The anemic domain model forces you to implement type checks outside the anemic entities, in services or service facades. To make their internal state accessible to the services and service facades, the anemic structures (technically they are not objects, by definition) must expose their internal state to the outside world too -- through field accessors (getters/setters) -- requiring a lot of plumbing.
In data-driven use cases such as master data management (CRUD), you can implement workflow-related, procedural behavior efficiently with service facades and few anemic entities. A domain-driven architecture, on the other hand, is perfect for more-complex, type-dependent algorithms in more-interactive applications. Most nontrivial Java EE projects require both approaches.
The crucial artifact in any domain-driven application is a domain object. A domain object can be considered a real-world artifact in the given project context. The challenge is to grasp the context and not try to model a perfect, theoretical world. Pragmatism rules. Domain objects are just cohesive classes with encapsulated state and related behavior. They use inheritance naturally, where appropriate.