4.2 Who's in Control?
Close to the center of my universe
are my two little girls. One
Christmas, we splurged a little and traded in our out-of-date 19-inch
TV for a much larger model. We set the new television up. A little
later, I looked around the room: one of my daughters was staring with
a blank, passive face at frantic Disney images on the TV. The other
kid had the cardboard box. With her mother, she had carved out doors
and a window, and was actively jumping and dancing around the passive
box. The contrast was striking. On one side, I saw an active toy, and
a passive kid; on the other side, a passive toy and an active kid.
Since then, I've repeated the experiment, albeit
more intentionally. I've filled my house with
passive toys that let the kids actively build, imagine, create, or
act (at least, when I can pry them away from the TV).
4.2.1 Active Domain Models
Modern programming is undergoing
a similar transition from active to
passive domain models. Figure 4-1 shows the
organization of classic services in a client-server application.
Designers put services on the bottom, so their clients could build
applications that use the
services directly. Essentially, active
business logic invoked services as needed. The passive services
presented an interface, and waited idle until invoked. Early
programmers found it easy to build applications with active business
layers. When they needed a transaction, they called a function like
BeginWork. When they needed data, they asked for
it directly from the database. Easy development gave way to complex
maintenance and foiled attempts at extension, because the
architecture muddied and entangled concerns between layers.
Figure 4-1. This client-server model lets service logic intrude into the business logic, increasing coupling and complicating code
commingling of business
entities and business
rules. The entities themselves, representing the
central concepts of the problem domain, manage their own state and
their interactions with other entities. This makes changing them more
difficult, since structural changes will at the very least entail
wading through the logic, and usually involve editing it as well.When your model actively reaches into other areas of your
application, passive services like persistence, logging, and security
tend to cut across all aspects of an application. Said another way, a
crosscutting concern applies to every aspect of an application.
Object-oriented technologies do not handle crosscutting concerns very
4.2.2 The Power of Passive Models
You've seen that active models
tend to couple much more tightly
to individual services. Lately, new object-oriented architectures
make an improvement over the all-controlling domain model. Figure 4-2 shows that the business domain model can
relinquish control and act like other passive services. The business
domain model, if anything, is just another service, albeit an
important one. Usually, peer relationships exist between the model
and services. You should strive to diminish them. Using this
paradigm, controllers marshal data between the model and other
services as needed. Controllers model the rules of the application,
while the domain model represents the entities. Whole frameworks,
like Struts or JDO, solve this problem for user-interface development
Figure 4-2. A better architecture has controllers dictating program control
hard-wired peer interfaces directly between the business layers and
individual services. The next natural step in development evolution
is to build a model with generic services that have no advanced
knowledge about the model at all. It's a difficult
problem that raises some complex questions:How can a service support a business object without explicit
knowledge of it? For example, how can you save an
Account object without knowing about the account
in advance?How can you build a business model that uses services in a complex
way, without prior knowledge of those services? For example, how can
you make sure that the first four business rules execute in one
transaction, while the next two occur in another?How can services react to events in a business model?
These are issues are about establishing transparency. If you
haven't dealt with these issues before, it may sound
like I am promoting anything but better, faster, and lighter Java.
Stay with me, though. These techniques can help you dramatically
simplify other areas of your architecture. They are worth the effort.