Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OOP: When to create derived classes, and when to implement features with conditionals?

When should I continue to make derived classes, and when should I just add conditionals to my code? eg for a missile

class Object;
class Projectile : public Object;

class Missile : public Projectile;
class MissileGuided : public Missile;

Or should I implement that last one in the missile's code?

void Missile::Update()
{
    if(homing && ObjectExists(Target))
        TurnTowards(Target.Pos)

    Pos += Motion;
}

I'm thinking that for all the finer details the second one is better, because you start getting combinations of things (eg some missiles may not show on the radar, some may be destroyable, some may acquire new targets if the original is destroyed or out of range, etc)

However then the same could be said for regular projectiles sharing properties of missiles in some cases (eg may be destroyable, large projectiles may show on radar, etc)

And then further I could say that projectiles share properties with ships (both move, on collision they do damage, may show on radar, may be destroyable...)

And then everything ends up back as like 3 classes:

class Entity;
class Object : public Entity;
class Effect : public Entity;

Where is a good point to draw the line between creating derived classes, and implementing the features in the method with flags or something?

like image 468
Fire Lancer Avatar asked Oct 19 '08 08:10

Fire Lancer


People also ask

What are the three 3 main features of OOP?

There are three major features in object-oriented programming that makes them different than non-OOP languages: encapsulation, inheritance and polymorphism.

What is the purpose of using a derived class?

Derived classes are used for augmenting the functionality of base class by adding or modifying the properties and methods to suit the requirements of the specialization necessary for derived class.

What are 4 major features that required for object based programming?

Object-oriented programming has four basic concepts: encapsulation, abstraction, inheritance and polymorphism.

What are the four 4 basic concepts of OOP languages?

The main ideas behind Java's Object-Oriented Programming, OOP concepts include abstraction, encapsulation, inheritance and polymorphism.


1 Answers

You may want to consider using strategy pattern instead of both approaches and encapsulate behaviours within external classes. Then the behaviours can be injected into the Missile class to make it GuidedMissile or SpaceRocket or whatever else you need.

This way excessive branching of logic within the Missile class could be avoided and you would not need to go into logical complexities associated with the deep inheritance.

Wikipedia has a collection of samples of the pattern usage in several languages: http://en.wikipedia.org/wiki/Strategy_pattern

interface INavigable {
  Course calcCourse (Position current, Destination dest);
}


Class GeoStationaryRocketCPU implements INavigable {
  Course calcCourse (Position current, Destination dest) {
     return dest.getShortestRouteTo (current).getCourse();
  };

}

Class GuidedMissileCPU implements INavigable {
  Course calcCourse (Position current, Destination dest) {
      return dest.getLowestAltRouteTo (current).getCourse();
  };

}



class Missile {
  INavigable CPU;

  void setCPU (INavigable CPU) {
     this.CPU = CPU;
  }

  void fly ()
  {

     ...
     course = this.CPU.calcCourse (pos, dest);
     ...
  }

}

As suggested by another collegue, you could consider using Decorator pattern as well. Just to highlight couple of design issues that might be important in your context if you were to take that route:

  1. To replace just a certain aspect of object's behaviour you'd need to decorate the entire class.
  2. If the public interface of the decorated class (let say missile) to be ever changed (even some functionality unrelated to its navigation aspect) you would have to change all of the decorating classes (i.e. GuidedMissile, Rocket, FireworkRocket etc) to pass on the interface.
  3. In Decorator you would expect that a decorator would add functionality, not replace it. It works by adding invoking its functions then calling the base class method. In the scenario above this would lead to being able to have a GuidedMissileCPU that decorates a GeoStationaryRocketCPU -- clearly this is not what you want. You want it to choose a different navigation strategy not layer navigation strategies on top of one another.

Nonetheless, when provided with a ready-made immutable implementation of Missile decoration could be the key to "unlocking" it and implementing the strategy pattern, to provide the Missile with all sorts of required behaviours.

like image 107
jordan.baucke Avatar answered Oct 04 '22 01:10

jordan.baucke