Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whether to model a car object (and its parts such as engine) with has-a (composition) or is-a (inheritance)?

I am developing a class library which will include the object Car.

The dilemma is, Car itself will be a class with fields such as Registration Number, and other general information on the car.

But a car has an engine, chassis, etc. These objects need to be modelled too. Should they be classes embedded within Car? If not, what is the usage scenario of an embedded class?

I've learnt that composition is "part of", so you can model seperate classes and use the engine type, for example, at the field level of the car to achieve this. However, "aggregation", which is a "has a" relationship with the type being passed in the ctor, also applies (a car "has an" engine).

Which way do I go?

EDIT: I am currently on homework hence the lack of a reply from me. The class library is for a web app based around cars. I am a professional developer (I develop in .NET for a living but as a junior) so this is not a homework question.

Thanks

like image 719
GurdeepS Avatar asked Dec 18 '22 04:12

GurdeepS


2 Answers

It really depends on your application.

For example, you could implement the wheels as separate classes, containing information about what tyre is on it, how worn it is, etc. but if your app doesn't even care about the wheels then the entire class is a waste of code.

I can see three use cases for composition:

  • The owning class has gotten overly complicated and should be broken down.
  • The owning class has multiple copies of a set of properties that could be mapped into a class. This allows you to bind all those properties together.
  • The contained object may need to be inspected or considered separately from the object that owns it (eg. you might want to move the Engine object to another car) or may be replaced as a single unit.

In summary: Use composition as a tool for encapsulating complexity or eliminating repetition. If it doesn't serve one of those purposes it probably isn't worth making a new class for.

like image 61
Adam Luchjenbroers Avatar answered Dec 19 '22 19:12

Adam Luchjenbroers


A class should have as few responsibilities as possible and encapsulate and delegate other functionality to other classes. Lots of a small, simple classes that do one thing is a sign of a readable, stable codebase.

Yes, a car will "have" an engine, but I'd suggest using an interface for this and similar "has a" relationships. Again, depending on the professor, you might get bonus points for having a factory create different cars (appropriate, no?):

public class Car
{
    private Engine engine;
    public Car(Engine engine)
    {
        this.engine = engine;
    }

    public void accelerate()
    {
        this.engine.goFaster();
    }

    public void decelerate()
    {
        this.engine.goSlower();
    }

}

public interface Engine
{
    public void goFaster();
    public void goSlower();
}


public class ReallyFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes really fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class NotAsFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes not as fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class CarFactory()
{
    public static Car createFastCar()
    {
         return new Car(new ReallyFastEngine());
    }

    public static Car createNotAsFastCar()
    {
         return new Car(new NotAsFastEngine());
    }
}
like image 44
Dave Sims Avatar answered Dec 19 '22 19:12

Dave Sims