Interface, abstract class, both, which do you recommend using here ?

  • Thread starter Thread starter craigkenisston
  • Start date Start date
C

craigkenisston

Hi,

I will use an example to do a simplified description of my problem,
please don't laugh.
I just "believe" I would have to use either interface or abstract
classes, but I've not ever write an interface, though I know the basis
of

interfaces.

So, let's say I have a class "RoboDriver", which is a robot which
dedicated task is to drive vehicles.
So, I will have an "Vehicle" class, too.

In order for do the proper programming of RoboDriver, I need that
vehicle provides some information, like type of vehicle (car,
motorcycle,

truck), also I would need the instances to be able to tell me whether
the vehicle is automatic or standard transmition, in case of car or
trucks,

then, to ask the number of gears.

If I write an IVehicle interface, how do I manage to know the inherited
classes type ? I mean, I can't enumerate all types of vehicles, nor I
will

know if I new type is invented but due similarities (and compatibility)
my RoboDriver class will be still able to know how to handle it.

Also, how do I ask for the optional properties ? I mean, let's say I
will have to ask about the transmission type only for certain vehicle
types,

I don't find elegant to have properties like "bool
IsManualTransmision", because, what if the implementor hardcode a
"true" return and then when I

call PutGear1, I get a notimplemented exception ?

Do you get my idea ? Which is the more appropiate way to go with this ?
Any comments of any kind are welcome.
 
(e-mail address removed) wrote in
Hi,

I will use an example to do a simplified description of my
problem, please don't laugh.
I just "believe" I would have to use either interface or
abstract classes, but I've not ever write an interface, though I
know the basis of interfaces.

Craig,

I'm afraid I don't have a simple answer for you. You seem to know
the problem domain well. But I think you also need to gain an in-
depth knowledge of object-oriented design.

<preaching_mode> :-)

The design of any non-trivial class hierarchy takes a great deal of
thought. Not only because of the complexities involved, but also
because you will have to live with the design in future versions of
your application. A good design makes future codebase modifications
much easier, whereas a bad design can make them impossible.

</preaching_mode>

I suggest getting a good book on design fundamentals. One that I'm
very glad I purchased is "Fundamentals of Object-Oriented Design in
UML" by Meilir Page-Jones:

http://www.amazon.com/exec/obidos/ASIN/020169946X/qid=1110421120/sr=2
-1/ref=pd_bbs_b_2_1/103-3345454-2395801

or

http://tinyurl.com/64y6q
 
In the case you describe, I would just make Vehicle a property of
RoboDriver. Unless RoboDriver is going to, by its own definition, imply a
specialized vehicle, you would not want an interface or an abstract class.

Bus might be a candidate for using an abstract class Vehicle. Bus is a
specialized vehicle.

If vehicle defines fixed properties and procedures, such as Drive, Brake,
Turn, that all vehicles will implement in the same way, and specialized
vehicles do not need to derive from another class as well, then use a static
class.

If you are going to have a vehicle Motorcycle, which actually turns by
leaning into the turn rather than by rotating a wheel, then Vehicle might be
a good candidate for an Interface because you won't specify the steps in
turning, or any other method. You will only specify that the user of your
Vehicle interface must specify how it turns. Of course, you could still use
an abstract class and the Motorcycle could just override the base Turn()
method that says RotateWheel(); and implement its version of Turn() with
LeanLeft(); or LeanRight();.

As for properties like Transmission, create a enum with the options and set
the Transmission property type to be TransmissionTypes enum.


HTH

DalePres
MCAD, MCDBA, MCSE
 
Helge :

Thanks for your comment. I dont know if this is what you meant, but
this is what I understood :

In order to test the individual characteristics of a vehicle, could I
break the Vehicle capabilities into very small interfaces ?
I mean, for example, if a the Vehicle, which is of type car is being
driver under rain, should the RoboDriver needs to know if the car has
an Antiblock system, that case I would easly test if the Vehicle
implements IAntiBlockSystem, I avoid to have an extra boolean property
to ask this ...
is it correct ?
 
The beauty of an interface is that you do not need to know
the inherited types.


.... and beauty of Joanna, as usual, comes like my personal angel to
save me :)
Seriously, well, not too much, but you always come in by my hardest
questions.
Thank you !

BTW, in your comment it seems you're assuming that both the driver and
the vehicle are automated robots. That makes it look too simple.
With a real robot and a real vehicle, ok, I know it is a an example,
but just suppose, you could not just put the robot and expect an
IncreaseSpeed and DecreaseSpeed buttons in the panel, I mean, the
driver would need to know for an automatic transmission, to softly
press the acceletator pedal, or for a manual, to press the clutch, set
the gear, press the acceleator while releasing the clutch, etc.
That's what I expect in my design, a class (the robodriver) that should
be handle to deal with objects that share common use and some
functionality, but that could look and feel totally different.
 
So driving a motorized vehicle requires DrivingPosition(float[] array),
accelerate(int increment), brake(int rate), turn(degrees angle),
direction(bool isForward) etc. The robot driver has GPS and logic to
navigate from a start GPS position using a map to a end GPS position by
calling on the abstract or interface methods in IDriveable.

Robot driver needs to load a concrete class that implements the
IDriveable interface or inherits from AbstractDriveable. So it finds a
vehicle class Corvette 2005 and loads the Corvette2005Driveable class
and tries to navigate from point A to point B.

Robot driver is able to respond to the implementation details of say
accelerate(int increment) {
RightFoot.Position(x,y,z);
...
}

Robot may not have the proper CREDENTIALS however:

try
{
this.Bind(new Corvette2005Driveable());
}
catch(InvalidCredentialsException e)
{
this.Voice("Too hot for me.");
}
finally
{
this.Walk();
}

Regards,
Jeff
That's what I expect in my design, a class (the robodriver) that should
be handle to deal with objects that share common use and some
functionality, but that could look and feel totally different.
 
BTW, in your comment it seems you're assuming that both the driver and
the vehicle are automated robots. That makes it look too simple.
With a real robot and a real vehicle, ok, I know it is a an example,
but just suppose, you could not just put the robot and expect an
IncreaseSpeed and DecreaseSpeed buttons in the panel, I mean, the
driver would need to know for an automatic transmission, to softly
press the acceletator pedal, or for a manual, to press the clutch, set
the gear, press the acceleator while releasing the clutch, etc.
That's what I expect in my design, a class (the robodriver) that should
be handle to deal with objects that share common use and some
functionality, but that could look and feel totally different.

Unfortunately, when designing such interactions, you have to eliminate much
of what humans do either instinctively or by reasoning.

Ok, if you want the Driver to have feedback, then that would possibly
include things like : EngineSpeed which would be polled by the Driver
(something some real drivers forget to do :-)), some means of telling the
Driver that the engine speed is either too low or too high (equivalent to
hearing the engine revs) so that they are prompted to change gear, some
logic to inform the Driver as to the gradient of the road so that that gets
factored into the decision as to which gear to select, etc...

Depending on whether the car had an automatic transmission or not would
decide whether certain feedback like prompting when to change gear gets
fired.

So, in summary, you are going to have to be very careful to allocate
responsibilities distinctly between the Driver and the Vehicle and make sure
that the Vehicle interface includes callbacks as well as methods and
properties.

I'd be interested to keep up with your progress :-)

Joanna
 
Thanks for your comment. I dont know if this is what you meant, but
this is what I understood :

In order to test the individual characteristics of a vehicle, could I
break the Vehicle capabilities into very small interfaces ?

Yes,...

Of course this won't help you if the properties of a vehicle can change
after cration of it's corresponding object.
I mean, for example, if a the Vehicle, which is of type car is being
driver under rain, should the RoboDriver needs to know if the car has
an Antiblock system, that case I would easly test if the Vehicle
implements IAntiBlockSystem, I avoid to have an extra boolean property
to ask this ...
is it correct ?

Yes.

There was another suggestion in there too. That you implement several
robodrivers, that each works with vehicles with specific properties.

If some of these separate classes can share some logic, then you can do
it in one of the standard ways: inheritance or compostition of
helper-classes.

Finally, you need a function of a kind that can accept a vehicle as
input and give a suitable driver. There are many ways to achieve this
mapping, starting with the simplest:

IDriver FetchDriver(IVehicle v) {
if ( v instanceof MyFirstVehicle )
return new MyFirstDriver();
else
throw new NotSupportedException(
string.Format("No driver available for IVehicle type {0}",
v.GetClass().FullName));
}

ranging to complicated lookuptables and type and/or instance
property-based selection.

Of course, all of this only makes sense if you have a way to treat
different drivers the same, for example if the all have something like
Goto(double x, double y). otherwise each vehicle can just be in a 1-1
relation with the appropriate driver, reacable as a non-vritual on those
specific.
 
Back
Top