Facets, Entities, Aggregates and Repositories
Every object has an explicit life cycle, beginning when new
is called and ending at garbage collection. This is
particularly true of domain objects, although they tend to outlive
the process in which they are created. Depending on the technology
used for persistence, the mid-life representation of an object would
either result from being reconstituted or, in Facets case,
simply getting a reference to a consistent view of the same object
created when new was first called.
Eric Evans' book, Domain-Driven Design,
treats the life cycle of domain objects in some detail and it is in
this life cycle that Facets has relevance to Evans' notions of
Entities, Aggregates and Repositories.
Facets
Facets is GemStone Systems' Java object database. It is comprised
of a set of C and Java processes that constitute its ACID test
compliant database attributes as well as industrial strength
server-side Java virtual machines that serve as the execution engines
for this powerful and domain-friendly Java object database.
Facets is domain-friendly because it has been built from the
ground up with the assumption that the domain model exists. In
fact, Facets' heritage is from Smalltalk where the model
portion of MVC (Model View Controller) is fundamental to the
paradigm. In truth, if you build business systems without domain
models then this paper will be of little value to you. However,
if you implement domain models in Java then there may be no
more relevant piece of a Java technology than Facets.
Entities and Value Objects
Domain models are comprised primarily of entities
and value objects. Entities are the more complex and
interesting of the two.
An object defined primarily by its identity is
called an ENTITY. ENTITIES have special modeling and design
considerations. They have life cycles that can radically change their
form and content, but a thread of continuity must be maintained.
Their identities must be defined so that they can be effectively
tracked. (Evans, 91)
(Note, in the foot note to this quoted section, Evans goes to
great pains to point out that entity models are not the
same thing as Java entity beans. If you have overloaded the
J2EE notion of entity bean with ENTITY then you will
need to remember that these are not the same thing.)
These identity based creatures are the objects in a system that
reflect that portion of the real world that is being emulated and
that one would typically like to persist to a database. They tend to
be rich in functionality, setting in motion those real world
functions that business performs. As with business, these entities
often vary shape and function over their life spans, and their roles
and functions can change over time. In my experience, it is desirable
that domain models, comprised of entities, be able to
reflect the business over time and be amenable to change in a timely
manner, thereby allowing the system in which it participates to have
a good chance of serving the agile business.
Value Object
When you care only about the attributes of an
element of the model, classify it as a VALUE OBJECT. Make it express
the meaning of the attributes it conveys and give it related
functionality. Treat the VALUE OBJECT as immutable. don't give it any
identity and avoid the design complexities necessary to maintain
ENTITIES. (Evans, 99)
Another pattern of object that
participate in domain models are value objects.
Opposite of entities these objects are identified by their
attributes not identity and, as a result, one does not care which
instance of a value object one gets as long as it correctly reflects
the attributes looked for. Value objects are often used as attributes
of entities. Evans gives a nice discussion of what distinguishes
entities from value objects and how to model each.
Facets made for POJOs
For our purposes, both entity
and value object are a plain old Java objects (POJO).
Facets was made to store POJOs easily and transparently. Facets is a
JTA/JTS compliant database with robust and sophisticated
transactional boundary management. At the same time, the machinery
for doing this is built into the Facets VM allowing for any object
that is reachable from an object bound into the root
context (a JNDI tree) to be automatically (orthogonally)
persisted at commit. As a result, while Facets is easy to work with
in terms of source code it is very sophisticated in its ability to
manage a consistent view of data, POJOs, across highly concurrent
usage.
Aggregates
An AGGREGATE is a cluster of associated objects
that we treat as a unit for the purpose of data changes. Each
AGGREGATE has a root and a boundary. The boundary defines what is
inside the AGGREGATE. The root is a single, specific ENTITY contained
in the AGGREGATE. The root is the only member of the AGGREGATE that
outside objects are allowed to hold references to, although objects
within the boundary may hold references to each other. (Evans,
127)
This notion of Aggregates is
very important to domain modeling in a world of relational
databases and Web Services. While Facets does not have the problems
that a relational database has with complex domain models, it
is worth noting that Service Oriented Architecture in general and Web
Services in particular require a component based (read: well
bounded) architecture. In my view Evans' definitions and thoughts
around Aggregates go a long way toward providing the guidance needed
to be successful at modeling in today's discrete world of SOA and Web
Services.
Repositories
The goal of domain-driven design is to create
better software by focusing on a model of the domain rather than the
technology. (Evans, 148)
Evans recognizes that when
developers are focusing on the infrastructure or framework required
to make things work they are not focused on the domain model which
expresses the business, and the result is business logic found in
areas of the system other than the domain. There is a salutary effect
to a system to have the domain fully encapsulated in the domain layer
and not sprinkled throughout. Repository is a useful pattern for
separating database infrastructure from the domain model.
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. (Evans,
151)
It is behind this REPOSITORY interface where one can
learn quite a lot about the overhead of the database upon which the
system relies. While repository does not include begin and
commit semantics it does contain all of the goo necessary to
reconstitute Java objects from its underlying persistence
mechanism. (Note, for an apples-to-apples comparison of what is
required behind a repository by TopLink versus Hibernate
versus Facets, see Dave Muirhead's paper and code example here.)
For our purposes it is sufficient to say that when using Facets there
is not much for the repository to do other than return a
reference to the root entity that is needed as all contained
entities can then be immediately found through traversal
without having to be reconstituted.
Object databases do eliminate the conversion
problem, but search mechanisms are usually still mechanistic, and
developers are still tempted to grab whatever objects they want.
(Evans, 149)
Facets uses a JNDI interface
for finding named root objects. It is extremely easy, a few lines of
code, to return the root entity only, thereby enforcing
traversal in order to access contained entities. Following
this guidance is simply a matter of enforcing good design, although
it can be readily violated if not everyone is committed to the
technique.
There are many things that
are not advisable in an object database. In a database such as Facets
where the virtual machines are so tightly integrated with the
object database, it is tempting to take all kinds of liberties and
short cuts to get at the object that is needed. However, to Evans'
point, this does not help in making clear the intent of the domain
model. In other words, there are many anti-patterns to using
Facets, as well as any other database technology, as it relates to
domain-driven design, although Facets seems more amenable to
doing just about anything you want without a readily apparent
downside.
It takes much belief in the
value of domain modeling in general and Evans' approach in
particular to stick to the design patterns, techniques and
constraints of domain-driven design. But whether one does or
does not adhere has less to do with the underlying database than with
the deep-seated belief in the desirability to do so. Facets just
happens to make domain implementation easy by removing the
considerable overhead required when using a relational database.
Facets as Aggregate database
Facets comes with a set of concurrent update
(CU) classes that are designed to be intelligent about being updated
simultaneously in different transactions without unnecessarily
reporting conflict due to concurrent write exception. (You can read
about these powerful classes in the GemStone
documentation. CU classes are designed to be
bound directly into the GemStone root context, as this is where very
large collections with much potential for concurrent conflict
typically reside. It is in these collections that I would put or add
root entities. To have many hundreds or thousands or millions
of root entities is easily managed by Facets through CU
classes. If highly concurrent write access is not anticipated, any
other Java collection could also be used for binding into the root
context as well as the root entity itself if it is appropriate
to the design of the system.
No artificial constraints
Facets does not care what the shape or behavior of the Aggregate
is, so long as it is implemented in Java. As a result, the portion of
domain-driven design that deals with modeling compromises due
to relational database impedance mismatch simply does not apply to
Facets and does not need to be discussed. In effect, the designers of
the system are free to make decisions based solely on what best
serves the domain model and the business.
Conjecture about Aggregates vis-a-vis Facets
As with any database,
Facets keeps its data, Java byte code, in a shared page caches (SPC).
It is my conjecture that as objects are accessed in a discrete
and consistent logical manner, they will also be treated that way
physically as the system runs. This will naturally cause closely
related object to end up in close proximity in the database, ideally
on the same SPC, making for very efficient data access and lower
overhead for the database to manage.
Once the business
begins thinking in terms of partitioned functionality, which
Aggregates represent, then it will be easier to identify, isolate and
discuss candidate changes within these atomic and discrete groupings
of classes thereby enabling faster time to market.
To deploy changes made to an
existing system implies transformation of existing data.
Transformation within Facets, and any other database for that matter,
should be greatly facilitated by the well contained and discrete
nature of the work due to the shape, boundary and rules for creating
and maintaining an Aggregate.
The very sophisticated
nature of Facets and the corresponding number of buttons that can be
turned to tune Facets can be made easier through the increased
understanding of the domain models hosted by way of
Aggregates. The well defined access points to root entities
and boundaries for contained entities should make for fewer
relationships to manage between objects, making the garbage
collection and other responsibilities of the database to process
faster and more efficiently.
With Aggregate as the
archetype for how to implement domain models, the variation
between domain model implementations should be much reduced providing
better opportunity for default configurations that serve the Facets
customer well.
Conclusion
While you would not know it from the length of this article, there
is very little to be said about how Facets relates to Domain-Driven
Design primarily because there is no conflict between the two.
Facets does not require the concessions offered to relational
database technology. Modeling decisions can be made simply because
they are good modeling decisions. So long as the domain model
execution is performed in a Facets VM and the repository
returns only root entities then there is little to hinder the
concepts put forth by Eric Evans in his fine book on Domain-Driven
Design.
|