PHP Doctrine Model – Abstract Class vs Interface

doctrineentityPHPsymfony

In Doctrine, assuming I want to implement different types of vehicles. Maybe a car, a plane, a bicycle and so on … all these vehicles have many different properties but also very common things like they are all made of a material.

So if i want to get this material … should i implement a abstract class Vehicle with a property material and implement getter/setter or should i define a interface IVehicle and define the getter/setter in there to be sure there is really a method for getting and setting the material? Or should i even use both in combination?

It feels "professional" using the interface … but it feels wrong to define getter/setters in interfaces, so my personal feeling is:

Don't use an interface, just use the abstract class.

But is the abstract class approach protected against misuse? For example on another place i definitely expect a Material type returning from the getMaterial() function … is the abstract class approach also save for not returning complete unexpected things (like the interface does)?

So if i extend this vehicle for another concrete class, a developer should not be able to return unexpected things, but should also be able to change the logic in the particular method if needed.

Best Answer

You wouldn't use an interface unless you absolutely needed to. Using your example of vehicles, supposing your program supports Vehicle abstract class. Classes which derive from this include Car, Motorcycle, Bus, etc. You use this in your program and everything is fine.

Then tomorrow your boss comes up to you and asks that you also deal with trains.. Trains are different. They work on rails, they have stops, they can't reverse. They are implemented entirely differently from your Vehicle abstract class which at least allows free range of direction and are implemented as such.

It makes sense at this point to add an interface called Transportation which deals with taking something from point A to point B. This fits both Vehicle and your new Train class. Your program would then prefer Transportation whenever applicable throughout and you would use it only in terms of taking a person from point A to point B.

The interface fits here because:

  1. What you need from the class isn't specific to Vehicle (you merely need to move from one point to another).
  2. Implementation of one class is entirely different from the implementation of another.

Needless to say, if you only have one implementation (which is to say, prior to the need to create Train class), then a Transportation class is superfluous and unnecessary. It only adds to the complexity of your program with no obvious benefit.

In other words, it isn't about looking professional or not. You write the program in such a way as to minimize complexity whenever possible. Interfaces are an acceptable complication of your program should it fit the above two points. Otherwise, don't be afraid to use the real or abstract class instead.

Related Topic