Friday 15 January 2010

Beyond Technologies: Domain Driven Design - Factories and Repositories

Introduction
In this post I sum up the most important concepts about Domain Driven Design.
I recommend you when you read this post not to think in technologies. Put away the technical knowledge and think from an upper level, from an architectural level.


Encapsulating with FACTORIES
A FACTORY encapsulates the knowledge needed to create a complex object or AGGREGATE, which may itself have no responsibility in the domain model but is still part of the domain design. Provide an interface that encapsulates all complex assembly and that does not require the client to reference the concrete class of the objects being instantiated.
There are some PATTERNS to design FACTORIES
1. FACTORY METHOD
2. ABSTRACT FACTORY
3. BUILDER
Requirements for a FACTORY are:
§          Each creation method is atomic and enforces all invariants of the created object or AGGREGATE.
§          A FACTORY should only be able to produce an object in a consistent state.
§          For an ENTITY, this means the creation of the entire AGGREGATE, with all the invariants satisfied, but probably with optional elements still to be added.
§          For an immutable VALUE OBJECT, this means that all attributes are initialized to their correct final state. If the interface makes it possible to request an object that can not be created correctly, then an exception should be raised or some other mechanism should be invoked that will ensure that no improper return value is possible.
§          The FACTORY should be abstracted to the type desired, rather than the concrete classes created.


Accessing with REPOSITORIES
The goal of domain-driven design is to create better software by focusing on a model of the domain rather than the technology.
A REPOSITORY represents all objects of a certain type as a conceptual set. It acts like a collection, except with more elaborate querying capability. Objects of the appropriate type are added and removed, and the machinery behind the REPOSITORY inserts them or deletes them from the database.
Clients request objects from the REPOSITORY using query methods that select objects based on criteria specified by the client, typically the value of certain attributes. The REPOSITORY retrieves the requested object, encapsulating the machinery of database queries and metadata mapping. Repositories can implement a variety of queries that select objects based on whatever criteria the client requires.





A REPOSITORY lifts a huge burden from the client, which can now talk to a simple, intention-revealing interface, and ask for what it needs in terms of the model. To support all this requires a lot of complex technical infrastructure, but the interface is simple and conceptually connected to the domain model.
For each type of object that needs global access, create an object that can provide the illusion of an in-memory collection of all objects of that type. Set up access through a well-known global interface. Provide methods to add and remove objects, which will encapsulate the actual insertion or removal of data in the data store. Provide methods that select objects based on some criteria and return fully instantiated objects or collections of objects whose attribute values meet the criteria, thereby encapsulating the actual storage and query technology. Provide REPOSITORIES only for AGGREGATE roots that actually need direct access. Keep the client focused on the model, delegating all object storage and access to the REPOSITORIES.


REPOSITORIES have many advantages, including the following:
·         
          1. They present clients with a simple model for obtaining persistent objects and managing their life cycle.
2. They decouple application and domain design from persistence technology, multiple database strategies, or even multiple data sources.
3. The communicate design decisions about object access.
4. They allow easy substitution of a dummy implementation, for use in testing.


The REPOSITORY will delegate to the appropriate infrastructure services to get the job done.
Note: Leave the transaction control to the client who presumably has the context to correctly initiate and commit units of work. Transaction management will be simpler if the REPOSITORY keeps its hands off.







References
Eric Evans 2004. Domain Driven Design. Tackling Complexity in the Heart of Software. Addison-Wesley.



No comments:

Post a Comment