Re: Immutable cyclic graph with dependency injection
On 2009-06-29 06:47:46 -0400, Philipp <djbulu@gmail.com> said:
Hello,
I have a structure with two classes, let's call them Car and
SteeringWheel for the example.
Car /owns/ a SteeringWheel: in production code, the lifetime of the
SteeringWheel is directly dependent on the lifetime of the Car.
In my design, the SteeringWheel object needs a reference to the Car
object (let's say, to transmit when the user honks).
This kind of designed-in circularity is usually a flaw. I'd be inclined
to move the logic that's in Car that needs to be shared with
SteeringWheel into its own object, which both Car and SteeringWheel
have a reference to. If only SteeringWheel is actually using that bit
of logic, I might even move it into SteeringWheel itself.
It's generally true that a graph that looks like A<->B can be
decircularized by introducing another node: A->B, A->C, B->C.
I see several
ways to build and initialize this class-graph, but none so far that I
think perfect.
If you take a strict view of immutability, you can't initialize an
immutable, circular structure. You need to introduce some formal
mutability somewhere, even if the result behaves as if it were
immutable. Alternately, break the circular references.
If you're using setters to make something mutable, you have the option
of making the setter package-visible to restrict it to code that
"should" have access to it. You can also use a post-property
initialization method: Spring calls it "afterPropertiesSet()" (it's
optional, and you can define your own with annotations), which is
called automatically to validate the properties of an object and
establish initial state when setter injection is in use (eg. throughout
the Spring libraries). You can emulate this kind of behaviour without
using a DI container, but it's somewhat less transparent.
-o