Immutable cyclic graph with dependency injection

Discussion in 'Java' started by Philipp, Jun 29, 2009.

  1. Philipp

    Philipp Guest

    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). I see several
    ways to build and initialize this class-graph, but none so far that I
    think perfect.

    What is the best way to create and initialise that structure?

    A few of my previous ideas are:
    1) Build graph dependency in constructor:
    public class Car {
    private final SteeringWheel wheel;
    public Car() {
    wheel = new SteeringWheel(this);
    }
    }
    public class SteeringWheel {
    private final Car car;
    public SteeringWheel(Car car) {
    this.car = car;
    }
    }

    Cons: a) /this/ pointer leaks in constructor b) Car is not unit-
    testable without SteeringWheel

    2) Use a setter and a static factory
    public class Car {
    private SteeringWheel wheel;
    public void setWheel(SteeringWheel wheel) {
    this.wheel = wheel;
    }
    public static Car newInstance(){
    Car c = new Car();
    SteeringWheel s = new SteeringWheel(c);
    c.setWheel(s);
    return c;
    }
    }
    public class SteeringWheel {
    private final Car car;
    public SteeringWheel(Car car) {
    this.car = car;
    }
    }
    Cons: a) field /wheel/ in Car cannot be made final (I like
    immutability) b) I must always check if wheel was correctly set as
    nothing enforces the correct construction sequence

    3) The JavaBean way:
    public class Car {
    private SteeringWheel wheel;
    public void setWheel(SteeringWheel wheel) {
    this.wheel = wheel;
    }
    public static Car newInstance(){
    Car c = new Car();
    SteeringWheel s = new SteeringWheel();
    c.setWheel(s);
    s.setCar(c);
    return c;
    }
    }
    public class SteeringWheel {
    private Car car;
    public void setCar(Car car) {
    this.car = car;
    }
    }

    Cons: Same problems as 2, but with added insecurity

    Are there constructs to build that graph which bundle all advantages?
    ie. testable through dependency injection, immutable (for thread
    safety) and guaranteing the invariants (example: wheel is not null)

    Thanks for your answers
    Philipp
     
    Philipp, Jun 29, 2009
    #1
    1. Advertising

  2. "Philipp" <> wrote in message
    news:
    > 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). I see several ways to build and initialize this
    > class-graph, but none so far that I think perfect.
    >
    > What is the best way to create and initialise that
    > structure?
    >
    > A few of my previous ideas are:
    > 1) Build graph dependency in constructor:
    > public class Car {
    > private final SteeringWheel wheel;
    > public Car() {
    > wheel = new SteeringWheel(this);
    > }
    > }
    > public class SteeringWheel {
    > private final Car car;
    > public SteeringWheel(Car car) {
    > this.car = car;
    > }
    > }
    >
    > Cons: a) /this/ pointer leaks in constructor b) Car is
    > not unit- testable without SteeringWheel
    >
    > 2) Use a setter and a static factory
    > public class Car {
    > private SteeringWheel wheel;
    > public void setWheel(SteeringWheel wheel) {
    > this.wheel = wheel;
    > }
    > public static Car newInstance(){
    > Car c = new Car();
    > SteeringWheel s = new SteeringWheel(c);
    > c.setWheel(s);
    > return c;
    > }
    > }
    > public class SteeringWheel {
    > private final Car car;
    > public SteeringWheel(Car car) {
    > this.car = car;
    > }
    > }
    > Cons: a) field /wheel/ in Car cannot be made final (I like
    > immutability) b) I must always check if wheel was
    > correctly set as nothing enforces the correct
    > construction sequence
    >
    > 3) The JavaBean way:
    > public class Car {
    > private SteeringWheel wheel;
    > public void setWheel(SteeringWheel wheel) {
    > this.wheel = wheel;
    > }
    > public static Car newInstance(){
    > Car c = new Car();
    > SteeringWheel s = new SteeringWheel();
    > c.setWheel(s);
    > s.setCar(c);
    > return c;
    > }
    > }
    > public class SteeringWheel {
    > private Car car;
    > public void setCar(Car car) {
    > this.car = car;
    > }
    > }
    >
    > Cons: Same problems as 2, but with added insecurity
    >
    > Are there constructs to build that graph which bundle all
    > advantages? ie. testable through dependency injection,
    > immutable (for thread safety) and guaranteing the
    > invariants (example: wheel is not null)
    >


    I have changed the steering wheel in my car, more that once. During the
    process, the steering wheel property of my car was definitely null. The car
    was absulute useless during that time, and it threw an Exception if it was
    tried to drive with. Starting the engine is no problem, but steering it was
    pain.
     
    Donkey Hottie, Jun 29, 2009
    #2
    1. Advertising

  3. Philipp

    Philipp Guest

    On Jun 29, 12:52 pm, Sabine Dinis Blochberger <>
    wrote:
    > Philipp wrote:
    > > 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). I see several
    > > ways to build and initialize this class-graph, but none so far that I
    > > think perfect.

    >
    > > What is the best way to create and initialise that structure?

    >
    > The steering wheel doesn't necessarily need a reference to the car. It
    > can fire an event of honk, and the car would have a listener for it. I
    > think this is the observer pattern (I'm not good with names).


    This is basically the setter method. Having an addHonkListener
    (HonkListener) in SteeringWheel instead of a setCar(Car) is really the
    same thing. It is certainly good to use interfaces (Car implements
    HonkListener), and using a Collection internally gets rid of the null
    check.

    private void sendHonk(){
    if(car != null){
    car.honk();
    }
    }

    is replaced by
    private void sendHonk(){
    for(Iterator it = honkListeners.iterator(); it.hasNext();){
    HonkListener hl = (HonkListener)it.next();
    hl.honk();
    }
    }

    But I do not get thread safety: adding an additional honk listener to
    the steering wheel may or may not be seen by another thread.

    Phil
     
    Philipp, Jun 29, 2009
    #3
  4. Philipp

    Philipp Guest

    On Jun 29, 12:58 pm, "Donkey Hottie" <> wrote:
    > "Philipp" <> wrote in message
    >
    > news:
    >
    >
    >
    >
    >
    > > 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). I see several ways to build and initialize this
    > > class-graph, but none so far that I think perfect.

    >
    > > What is the best way to create and initialise that
    > > structure?

    >
    > > A few of my previous ideas are:
    > > 1) Build graph dependency in constructor:
    > > public class Car {
    > >  private final SteeringWheel wheel;
    > >  public Car() {
    > >    wheel = new SteeringWheel(this);
    > >  }
    > > }
    > > public class SteeringWheel {
    > >  private final Car car;
    > >  public SteeringWheel(Car car) {
    > >    this.car = car;
    > >  }
    > > }

    >
    > > Cons: a) /this/ pointer leaks in constructor b) Car is
    > > not unit- testable without SteeringWheel

    >
    > > 2) Use a setter and a static factory
    > > public class Car {
    > >  private SteeringWheel wheel;
    > >  public void setWheel(SteeringWheel wheel) {
    > >    this.wheel = wheel;
    > >  }
    > >  public static Car newInstance(){
    > >    Car c = new Car();
    > >    SteeringWheel s = new SteeringWheel(c);
    > >    c.setWheel(s);
    > >    return c;
    > >  }
    > > }
    > > public class SteeringWheel {
    > >  private final Car car;
    > >  public SteeringWheel(Car car) {
    > >    this.car = car;
    > >  }
    > > }
    > > Cons: a) field /wheel/ in Car cannot be made final (I like
    > > immutability) b) I must always check if wheel was
    > > correctly set as nothing enforces the correct
    > > construction sequence

    >
    > > 3) The JavaBean way:
    > > public class Car {
    > >  private SteeringWheel wheel;
    > >  public void setWheel(SteeringWheel wheel) {
    > >    this.wheel = wheel;
    > >  }
    > >  public static Car newInstance(){
    > >    Car c = new Car();
    > >    SteeringWheel s = new SteeringWheel();
    > >    c.setWheel(s);
    > >    s.setCar(c);
    > >    return c;
    > >  }
    > > }
    > > public class SteeringWheel {
    > >  private Car car;
    > >  public void setCar(Car car) {
    > >    this.car = car;
    > >  }
    > > }

    >
    > > Cons: Same problems as 2, but with added insecurity

    >
    > > Are there constructs to build that graph which bundle all
    > > advantages? ie. testable through dependency injection,
    > > immutable (for thread safety) and guaranteing the
    > > invariants (example: wheel is not null)

    >
    > I have changed the steering wheel in my car, more that once. During the
    > process, the steering wheel property of my car was definitely null. The car
    > was absulute useless during that time, and it threw an Exception if it was
    > tried to drive with. Starting the engine is no problem, but steering it was
    > pain.


    Funny :)

    You mean: instead of enforcing invariants, throw exception if they are
    not met?
    Not sure that this is a good idea. But maybe there is no better way...

    Phil
     
    Philipp, Jun 29, 2009
    #4
  5. "Philipp" <> wrote in message
    news:
    > On Jun 29, 12:58 pm, "Donkey Hottie" <>
    > wrote:
    >> I have changed the steering wheel in my car, more that
    >> once. During the process, the steering wheel property of
    >> my car was definitely null. The car was absulute useless
    >> during that time, and it threw an Exception if it was
    >> tried to drive with. Starting the engine is no problem,
    >> but steering it was pain.

    >
    > Funny :)
    >
    > You mean: instead of enforcing invariants, throw
    > exception if they are not met?
    > Not sure that this is a good idea. But maybe there is no
    > better way...
    >


    If you do not want NullPointerException you have to implement some kind of
    checkList() throws CheckListException.

    That's what the do in airplanes before they steer them.

    With cars, it usually goes with the NPE..
     
    Donkey Hottie, Jun 29, 2009
    #5
  6. On 2009-06-29 06:47:46 -0400, Philipp <> 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
     
    Owen Jacobson, Jun 29, 2009
    #6
  7. Philipp

    markspace Guest

    Philipp wrote:

    > But I do not get thread safety: adding an additional honk listener to
    > the steering wheel may or may not be seen by another thread.



    Needs synchronization then.

    Use CopyOnWriteArrayList if you have a recent version of Java. Use
    Collections.synchronizedList( List ) if you need to support older Java
    installations.
     
    markspace, Jun 29, 2009
    #7
  8. Philipp

    Tom Anderson Guest

    On Mon, 29 Jun 2009, Owen Jacobson wrote:

    > On 2009-06-29 06:47:46 -0400, Philipp <> said:
    >
    >> 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).
    >>
    >> 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.


    Whilst i wouldn't call this strict, or a good idea (seriously - not *at
    all*), you *can* change final references after construction - you can do
    it with sun.misc.Unsafe. But of course, that's not a feature of java :).

    tom

    --
    We must perform a quirkafleeg
     
    Tom Anderson, Jun 29, 2009
    #8
  9. On 2009-06-29 15:48:53 -0400, Tom Anderson <> said:

    > On Mon, 29 Jun 2009, Owen Jacobson wrote:
    >
    >> On 2009-06-29 06:47:46 -0400, Philipp <> said:
    >>
    >>> 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).
    >>>
    >>> 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.

    >
    > Whilst i wouldn't call this strict, or a good idea (seriously - not *at
    > all*), you *can* change final references after construction - you can
    > do it with sun.misc.Unsafe. But of course, that's not a feature of java
    > :).


    Once upon a time, the JVM itself treated final identifiers like any
    other identifier in the same category, and allowed bytecode that
    directly modified final locals, fields, etc.. javac makes assumptions
    about final fields (by inlining constant expressions) that rely on that
    never happening.

    I have no idea, nor do I want to know, if that's still true.

    -o
     
    Owen Jacobson, Jun 29, 2009
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dennis Lerche

    Cyclic Dependency problem

    Dennis Lerche, May 11, 2004, in forum: C++
    Replies:
    6
    Views:
    11,228
    Khaled.Jouda
    Jul 5, 2010
  2. Nick Forrington

    Cyclic dependency

    Nick Forrington, Nov 16, 2004, in forum: C++
    Replies:
    6
    Views:
    466
    Nick Forrington
    Nov 17, 2004
  3. Replies:
    3
    Views:
    636
    Michael Mair
    Apr 22, 2006
  4. Replies:
    4
    Views:
    426
    Sakis
    May 17, 2006
  5. Emilio Mayorga
    Replies:
    6
    Views:
    352
    Martien Verbruggen
    Oct 8, 2003
Loading...

Share This Page