ahead and make a standalone
FACTORY
. But respect the rules limiting access within an
AGGREGATE
,
and make sure there are only transient references to the product from outside the
AGGREGATE.
Figure 6.15. A standalone
FACTORY
builds
AGGREGATE
.
When a Constructor Is All You Need
I've seen far too much code in which
all
instances are created by directly calling class constructors,
or whatever the primitive level of instance creation is for the programming language. The
introduction of
FACTORIES
has great advantages, and is generally underused. Yet there are times
when the directness of a constructor makes it the best choice. F
ACTORIES
can actually obscure
simple objects that don't use polymorphism.
The
trade-offs favor a bare, public constructor in the following circumstances.
The class is the type. It is not part of any interesting hierarchy, and it isn't used
polymorphically by implementing an interface.
The client cares about the implementation, perhaps as a way of choosing a
STRATEGY
.
All of the attributes of the object are available to the client, so that no object creation gets
nested inside the constructor exposed to the client.
The construction is not complicated.
A public constructor must
follow the same rules as a
FACTORY
: It must be an atomic operation
that satisfies all invariants of the created object.
Avoid calling constructors within constructors of other classes. Constructors should be dead simple.
Complex assemblies, especially of
AGGREGATES
, call for
FACTORIES
. The threshold for choosing to
use a little
FACTORY
METHOD
isn't high.
The Java class library offers interesting examples. All collections implement interfaces that
decouple the client from the concrete implementation. Yet they are all created by direct calls to
constructors. A
FACTORY
could have encapsulated the collection hierarchy. The
FACTORY
's methods
could have allowed a client to ask for the features it needed, with the
FACTORY
selecting the
appropriate class to instantiate. Code that created collections
would be more expressive, and new
collection classes could be installed without breaking every Java program.
But there is a case in favor of the concrete constructors. First, the choice of implementation can be
performance sensitive for many applications, so an application might want control. (Even so, a
really smart
FACTORY
could accommodate such factors.) Anyway, there aren't very many collection
classes, so it isn't that complicated to choose.
The abstract collection types preserve some value
in spite of the lack of a
FACTORY
because of their
usage patterns. Collections are very often created in one place and used in another. This means
that the client that ultimately uses the collection—adding, removing, and retrieving its
contents—can still talk to the interface and be decoupled from the implementation. The selection of
a collection class typically falls to the object
that owns the collection, or to the owning object's
FACTORY
.
Do'stlaringiz bilan baham: