pattern question - inheritance

Here's my pattern question:

Vehicle Object

SUV Object extends Vehicle Object

Sedan Object extends Vehicle Object

DecisionMaker Class -- Decides what vehicle to use in the program depending on the weather e.g:

public Class DecisionMaker{

public Vehicle whatVehicleToUse(){

if(raining)

returnnew SUV()

else

returnnew Sedan()

endif

}

The method whatVehicleToUse() returns the supertype object Vehicle. If the SUV Object or the Sedan object has domain-specific functionality embedded I can't get to it. For e.g if the SUV object has a method switchto4WD() I can't invoke it on the Vehicle object.

I thought of doing a Vehicle interface with all possible Vehicle related methods in it, but that doesn't seem like the right approach either.

Any help on how to do this the right way is appreciated! Thanks.

Aamer

[1295 byte] By [aamya] at [2007-10-2 21:01:34]
# 1

You need to keep your dealings with vehicles at a more abstract level. What you're trying to do by calling switchto4WD() is something that is not generally applicable to vehicles. Since 4WD is not a generic vehicle thing, it will be encapsulated inside the SUV class.

The vehicle class should have a (maybe abstract) method like adjustForSnow() or goingOffRoad(). The SUV class would then implement that method by going into 4WD. The Sedan and other Vehicle sub-classes would take their own appropriate action.

Your Vehicle class will specify methods that let any Vehicle know things that it will need to react to, like it's dark, it's snowing, snow has accumulated, whatever. Each vehicle subclass will deal with that in it's own unique way such as going into 4WD, turning on lights, maybe doing nothing. Let the non-generic specifics (such as 4WD) be encapsulated inside the sub-classes.

If 4WD is something you really must deal with at the Vehicle level, then make some of your Vehicle subclasses implement a FourWheelDrive interface. You could deal with it as follows:

if (myVehicle instanceof FourWheelDrive) {

FourWheelDrive myFwd = (FourWheelDrive) myVehicle;

myFwd.doFwdStuff();

}

BillKriegera at 2007-7-13 23:46:31 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

[snip]

> Any help on how to do this the right way is

> appreciated! Thanks.

>

> Aamer

IMO your design is fundamentally busted. I assume your purpose for the DecisionMaker class was to localize the code for dealing with different weather conditions (as it applies to what sort of vehicle to use) in one place. Thus the client code (the code that uses the DecisionMaker class) doesn't need to concern itself with what sort of vehicle it's got, with respect to, say, the weather. So the client code should not be aware of how the weather would impact its use of the returned vehicle, IMO.So the client code should not be worrying about calling switchTo4WD (for instance).

So, that said - maybe your *vehicle* should be aware of the weather. So when you build the Vehicle in the DecisionMaker maybe you should tell it what the weather is (since the DecisionMaker had to know this) and thus when the client code calls, I dunno, "goSomewhere()" the concrete Vehicle would know how to respond (by shifting into 4-Low if it could, for instance)

Good Luck

Lee

tsitha at 2007-7-13 23:46:31 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

If you create a Driver abstraction then you can have a 4WheelDriveDriver class that 'knows' about the 4WheelDriveVehicle class. Then your decision maker class becomes an AbstractFactory pattern and you have getDriver and a getVehicle methods. The abstract Factory is responsible for making sure the driver and vehicle are compatible.

dubwaia at 2007-7-13 23:46:31 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

thanks for all the responses, I really appreciate it.

Bill-- I agree that all non-generic specifics should be encapsulated inside the sub-classes. I need to implement about 20 rules which will dictate what vehicle will be used before the start of a trip. After that decision has been made, I really need 'full access' to the functionality of the sub-classed vehicle object (e.g SUV, Sedan, Bike).

Situations like rain has stopped so stop using 4WD, can be taken of like you mentioned, i.e have the superclass know things that it will need to react to, and have the subclass deal with that in its own way. But what happens when you come across a situation where you want to access a piece of functionality that is really specific to the sub-class? And what if those specfic pieces of functionality are in large numbers? Can't have too many (if instanceOf abc then 1 else 0). For e.g a luxury car can have the ability to warm your seats, automatic windshield wipers, it can fly, it can go into space, it can have leather seats and a ton of other functionality. For each piece of subclass functionality, I would have to put something in my superclass which is what I don't like and am looking for an alternative.

Is this a recurring problem that you guys face? Or is it a one-off problem with really has no good solution? Or am I just approching the problem incorrectly?

I may not be explaining myself correctly, forgive me for I am a novice at OOP concepts.

aamya at 2007-7-13 23:46:31 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

After reading my last post, I realize the stupidity of my questions.....I think I got it now.

In cases where I know exactly what Vehicle I am dealing with I can always do mySpecificVehicle = (SpecificVehicle) genericVehicle

Thanks a bunch!! this process really help me.

I have realized that the best way to learn patterns is by looking at someone else's code and see how they have implemented it. Is there a particular application who source code I could look at to better my understanding of OOP principles?

aamya at 2007-7-13 23:46:31 > top of Java-index,Other Topics,Patterns & OO Design...