Re-using related functionality amongst unrelated classes
Hi, I have classes like these:
abstract class Entity
abstract class SpaceShip extends Entity implements Thrustable
class Astronaut extends Entity implements Thrustable
Thrustable has:
- thrust()
- brake()
- afterburner()
What I want to do is share the same thrusting methods for both spaceships and astronauts (and some others too possibly).
I really don't want to make Entity Thrustable nor would I like the idea to create another abstract class just to make a base for all Thrustables.
I guess I could just try to delegate the functionality to some small class, but it'd be nice to know what's the design pattern for this. And is there somekind of good naming scheme for things like this.
Something like BasicThrustBehaviour comes first into my mind, though I didn't have in mind that I would ever change the thrusting behaviour. I always prefer to find good and appropriate names for my methods and classes.
What would be a good way to organize the classes? I'd imagine that if there's lot of related functionality like this there'd be many little classes around.
Thanks
[1165 byte] By [
mc3712a] at [2007-10-2 3:21:14]

In similar situations I use services classes. In this
cause you could create a service called
public class ThrusterService {
public void accelerate(Thrustable thrustable) {
...
}
public void brake(Thrustable thrustable) {
...
}
public void afterburn(Thrustable thrustable) {
...
}
}
Still, the unrelated classes using this service must
implement a minimum common contract, but you can move
all active code to the service class.
In most cases you can make services stateless singletons
that are provided by a factory or a micro kernel like
Hivemind.
parza at 2007-7-15 21:48:42 >

public abstract class AbstractThrustable extends Entity implements Thrustable{
// implementation of Thrustable method
}
public class SpaceShip extends AbstractThrustable{
}
public class Astronaut extends AbstractThrustable{
}
> I really don't want to make Entity Thrustable nor
> would I like the idea to create another abstract
> class just to make a base for all Thrustables.
That's very sensible.
> I guess I could just try to delegate the
> functionality to some small class, but it'd be nice
> to know what's the design pattern for this. And is
> there somekind of good naming scheme for things like
> this.
What you've suggested is an idiom which in Java sometimes is called implement/delegate. It's really a way to simulate multiple inheritance of implementation using an interfaces to inherit a type and a delegated object to supply the implementation.
One advantage is that the delegated object can be switched at runtime which isn't possible if the implementation is statically inherited ala C++. Another advantage is that it removes the ambiguities that can arise from multiple inheritance of implementation ala C++.
So this idiom is the Java way of doing dynamic multiple inheritance of implementation. (a C++ programmer could use it too of course -:).
Well, implement/delegate would look like this,
interface Thrustable {
void accelerate();
void brake();
}
//
class ThrustService1 implements Thrustable {
public void accelerate() {
}
public void brake() {
}
}
//
class ThrustService2 implements Thrustable {
//...... Alternate implementation
}
//
class SpaceShip extends Entity implements Thrustable {
private Thrustable t = new ThrustService1(); // can be passed via constructor/method
public void accelerate() {
t.accelerate(); // delegate
}
public void brake() {
t.brake(); // delegate
}
}
//
public class Astronaut extends Entity implements Thrustable {
private Thrustable t = new ThrustService1(); // can be passed via constructor/method
public void accelerate() {
t.accelerate(); // delegate
}
public void brake() {
t.brake(); // delegate
}
}
Great, thanks for the replies. I'll start playing with these ideas.
Here's another idea.Astronauts and Spaceships implements Movable and contain Thrusters (which act upon Movables.) The advantage of this is that your movable interface is now generic to all forces in the simulation.
> Here's another idea.> > Astronauts and Spaceships implements Movable i dont think they 'move' in the same way, but they might crash similarly, so do not forget to implment the crashable interface.
>Here's another idea.
>Astronauts and Spaceships implements Movable and contain >Thrusters (which act upon Movables.) The advantage of this is that your >movable interface is now generic to all forces in the simulation.
That's a great idea and I think it really makes most sense this way. As a matter of fact I already had Thrusters-class but it was nothing but a visual representation.
And yeah I didn't plan to make the movement of astronauts and spacehips to differ in anyway (except speed ;).
Thanks
> >Here's another idea.
> >Astronauts and Spaceships implements Movable and
> contain >Thrusters (which act upon Movables.) The
> advantage of this is that your >movable interface is
> now generic to all forces in the simulation.
>
> That's a great idea and I think it really makes most
> sense this way. As a matter of fact I already had
> Thrusters-class but it was nothing but a visual
> representation.
> And yeah I didn't plan to make the movement of
> astronauts and spacehips to differ in anyway (except
> speed ;).
I would keep the visual representation as a separate wrapper class. This will tend to provide a cleaner design.