views:

121

answers:

3

Hello

I have some algorithms to do that are very similar in very aspects but are all different.

I'll try to give an example of what I mean.

Let's assume I have a Robot class. This class should be the "base" of all classes. It provides basic mechanisms to make the robot work in its environment. It might or not have to work by itself (with this I mean it can either be an abstract class, that is useless by itself, or if possible, to have basics mechanisms to be ready to work).

All robots have hands. But some robots will have human-like hands, other will have blades, other will have razors. I could do a base class called RobotBase and then create RobotHumandHand, RobotBladeHand and RobotRazorHand. But they also can have different heads, different eyes, different legs, different arms, etc. Is there any easy way I can address this? I'd like to put this in a way that is a bit like LEGO, so I could just define a robot and "add" the pieces I want. Maybe through interfaces? I am not even aware if those exist in python(that's the language I'll be using).

Any comments / suggestions are really appreciated! Thanks!

+1  A: 

I'm not a Python guy, but a quick look indicates they support multiple inheritance which can be used like Java Interfaces (Python does not seem to support interfaces). So you can have essentially superclasses for RobotHand then RobotHumanHand, RobotBladeHand, etc, Same with eyes, feet what have you. This is a reasonable way to do what you want to do.

Francis Upton
Yes, that seems a nice idea.
devoured elysium
No. It's not really a nice idea.Don't use multiple inheritance in Python.In fact, don't use inheritance unless you want to reuse __implementation__ of interface.To be used interchangeably, Python objects need only to implement compatible methods and that's a preferred style.More like Smalltalk than Simula.My experience is that trying to use Simula (or Java, or C++) way of using subclasses in Python only makes things more difficult.
Tomek Szpakowicz
+3  A: 

I think your robot should have a list of ports i.e. a number of injected components each robot may have. Your Robot class will be a container of RobotParts. You can have specific parts to have specific interfaces. RobotHand extends RobotPart and Robot class has a field that holds a list of RobotHand implementations (you can limit it to 2 hands, but in general case there could be more). You can do the same with RobotHead that will inherit from RobotPart and also there will be a field in Robot class holding implementation of RobotHead. In its turn RobotHead may hold a list of RobotEye implementations and so on. Then your specific Robot implementations may inherit their behavior from base class or take advantage of configuration e.g. by using RobotBladeHands if available.

Superfilin
Good ideas here, this has the advantage (over my suggestion) of keeping state for multiple instances of parts in a generic way.
Francis Upton
This is totally what you want. You want to use object composition, also known as the "has-a" relationship. A `robot` has-a set of hands, has-a head, etc. Contrast with the "is-a"relationship. `RobotBladeHands` is-a kind of `RobotHands`.
steveha
+4  A: 

The design patterns I'd probably go with for such a problem are: Dependency Injection and a framework to go with it, the Composite pattern, and the Builder pattern. They should basically let you separate the creation of your Robots from their use.

Qberticus
from that post I read "Basically, instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies in to the constructor". This seems perfect to me. But how would I implement this in python? How can I make the base see it has a new MoveArm() method defined by the ArmBlade class, and not use it's standard implementation? (I am assuming my main class has a MoveArm()).
devoured elysium
@devoured elysium: Slow down. Take a breath. When you say "different implementation", that's the point. As long as all the method functions have the same *name*, they're allowed to have different implementations. Your composite object's "moveArm" just calls an Arm's "move", without knowing what kind of arm it is.
S.Lott