Re: IoC, DI, and a mess...
On Thu, 31 Jan 2008 19:53:11 -0500, Daniel Pitts =
<googlegroupie@coloraura.com> wrote:
Hmm, I thought I posted this earlier, but Google says otherwise. If
this is a repeat, please respond to the *other* post.
So, I have a RobotFactory, which creates and Robot, all its
components, and then wires the components to the robot. This is my
attempt at using IoC and dependency injection for this.
The wiring is done in one method (shown below). The factory can be
configured once, and then used several times to create new robots that=
are the same. The application can have many different RobotFactory
instances.
The problem I have, is that this wiring looks like a mess. I'm trying=
to think of ways that could simplify this construct will still giving
me the IoC.
void configureRobot(Robot robot) {
robot.setThrottle(createThrottle());
robot.getThrottle().setRobot(robot);
Not sure if this is getting too far off pattern, but I'll throw this out=
.. =
If you have methods
Robot.setThrottle
and
Throttle.setRobot
Then it is not obvious to a caller that if one sets one, the same caller=
=
must also set the other. A caller could easily miss those connections. I=
f =
you are using setters to set everything up post-construction, I would le=
an =
towards a mechanism like:
public class Robot {
....
private Throttle _throttle=null;
public void setThrottle(Throttle throttle) {
if (throttle==_throttle)
return;
// Decouple the old throttle
if (_throttle!=null)
_throttle.setRobot(null);
// Replace the throttle reference
_throttle=throttle;
// Configure required coupling
if (_throttle!=null)
_throttle.setRobot(this);
}
}
public class Throttle {
....
private Robot _robot=null;
public void setRobot(Robot robot) {
if (robot==_robot)
return;
// Decouple the old robot
if (_robot!=null)
_robot.setThrottle(null);
// Replace the robot reference
_robot=robot;
// Configure required coupling
if (_robot!=null)
_robot.setThrottle(this);
}
}
In this case, the set methods now avoid having object partially set, but=
=
instead completely set the reference to the parameter.
Myself; I like to make objects immutable and fields final by default =
unless there is a good reason for them not to be. The downside of this i=
s =
it means the constructor has to pick up some of the work. However, that =
=
can still be written as:
public class RobotFactory {
public Robot createRobot() {
return new Robot(this);
}
// package accessible method, but also overridable
protected Throttle createThrottle(Robot robot) {
return new Throttle(robot);
}
}
public class Robot {
private final Throttle _throttle;
//package protected constructor
Robot(RobotFactory factory) {
_throttle=factory.createThrottle(this);
...
}
}
I'm sure someone has come up with this pattern before and named it, but =
I =
don't know off the top of my head. Until I hear the proper name, I tend =
to =
think of this as a "Puppy Pattern", since the objects still need to be =
nurtured by their, erhm parent, before they're ready to be released into=
=
the real-world. It is of course the parent's responsibility to make sure=
=
not to feed anything to the pup that it's not yet big enough to handle.
Anyway, that might be so different it's not really DI anymore, but maybe=
=
this was food for thought for you ;)
HTH,
-Zig