3

I have a car maintenance garage program that has an abstract Vehicle class that has several derived classes like Car MotorCycle, etc. Each of those derived vehicles in turn is either a fuel or an electric vehicle. So instead of having a FuelCar, ElectricCar, FuelMotorCycle, ElectricMotorCycle etc, I'm trying to implement it using composition.

The problem now is that I would have to check all the time if it's an electric or fuel vehicle, and then do as cast (that's like reinterpret_cast from c++) accordingly, or would have to wrap each as cast with try catch. It adds complexity to the code.

Another option was removing the EnergySource empty class and have each vehicle to hold both Fuel and Electric and to initialize only one in the ctor, but it doesn't seem right to have a fuel car that also have an electric part (even if that part is null). Although this seems the simplest of the three.

Any suggestions on what is the best approach?

Here's the UML diagram of what I currently have:

enter image description here

Code: http://pastebin.com/Rt5HccHC

2

@radarbob those members are specified, I didn't choose them.

My sympathies.


... Hybrid cars shouldn't be allowed and are irrelevant.

Ok. Then you'd better not have both a Fuel and Electric properties in Vehicle. It "sends the wrong message."


... I don't see how placing properties in interfaces help here, I'm still in square one.

Throughout the StackExchange universe I see the way over-use of interfaces (the keyword kind). I think it is an exuberant mis-application and mis-understanding of "code to interfaces not implementation."


... Lastly, you mean a solid rhombus en.wikipedia.org/wiki/Class_diagram#Relationships

Jessica Simpson on UML


... Anything else you would like to add?

Yes.

Wrap a Vehicle in a VehicleEnergy class

Given the design as shown, pass a Vehicle instance into a VehicleEnergy class with appropriate wrapper methods, or properties, to query the vehicle-EnergySource kind that it is. But I don't see how you can get around the fact that somewhere, somehow you have to interrogate the object.

This feels like a good separation of concerns compromise. I wonder if the flurry of comments on this thread is the result of - a symptom of - conflicting concerns.

I think this hybrid design (pun intended) expresses the separate aspects and then expresses their interaction in a coherent interface (the non-keyword kind).

The Vehicle object can always be used as-is, or disguise itself, so to speak.

Oh, yes... I might use the factory pattern and pass in an enum for the vehicle-enery desired. There will be no enum member for a hybrid vehicle so this becomes a strongly typed way of communicating that "hybrid" is undefined.

  • For the record, usually when I say "code to an interface", I'm not talking about the keyword. – RubberDuck May 8 '16 at 3:16
  • By "wrap" do you mean to have nested classes or vehicle would be a data member of VehicleEnergy ? – shinzou May 8 '16 at 9:23
  • @kuhaku I think he's talking about the decorator pattern. en.m.wikipedia.org/wiki/Decorator_pattern – RubberDuck May 8 '16 at 10:58
  • "wrap" == Vehicle contained in a VehicleEnergy class. I see that Vehicle already contains a EnergySource property. I see the Vehicle doing no more that it must to appropriately expose that property; likewise for EnergySource expressing itself. Then a separate class has the burden of that "interplay functionality." It isolates any messiness of dynamic functionality and potential sub-class proliferation; and essentially expresses vehicle-energysource dynamics as an independent construct. This certainly should avoid the "2 EnergySource property problem" mentioned in the OP. – radarbob May 9 '16 at 13:03
  • re: "decorator pattern. Conceptually I was thinking more like a facade. The thought was to keep "vehicle + energy" identity separate from Vehicle. My spidey-sense is telling me there may be some bigger picture domain/design conflicts here in extending Vehicle functionality, but that is no more than a vague suspicion – radarbob May 9 '16 at 13:08
4

A car has an Engine and Fuel whether it be combustion or electric. They're your abstract base classes. Then, a car has a Engine and it shouldn't care if that engine is a CombustionEngine or an ElectricEngine.

  • This would be the same as the UML diagram only EnergySource = Engine, I don't see how it solves the problem. – shinzou May 7 '16 at 17:01
  • 3
    Please explain why your code needs to know the type. If a car needs to know what type of engine it has, you're breaking the Liskov Substitution Principle and aren't coding to interfaces. I think that's likely your problem. Can we see some example code? – RubberDuck May 7 '16 at 17:11
  • 1
    enum anyone? Also, all the Fuel and Electric class members are nonsensical. These are more like attributes of a fuel tank, or of a vehicle. – radarbob May 7 '16 at 21:16
  • 2
    "you can't mix electricity with a petrol engine or petrol fuel with an electric engine." What is a hybrid vehicle if not that? – radarbob May 7 '16 at 21:36
  • 1
    The OP's concept is broken. You just cannot proliferate hybrid classes based on what should be properties just so the compiler "answers the questions about what it is" at compile time, vice actual code at run time. As RubberDuck says you really must get a better understanding of properties. Go back to the drawing board. Our answers will not get any better until then. P.S. a solid arrow means composition, not inheritance. – radarbob May 7 '16 at 21:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.