jeudi 16 septembre 2021

How to switch on subtypes in object-oriented language?

I'm coming mostly from functional languages background and I have no idea how to do this sort of pattern well in object oriented languages.

Let's say I have some Animal classes and subclasses and an AnimalManager. I want an "add" method on the AnimalManager which has different behavior depending on whether I'm adding a Cat or a Dog. Something like this (in no particular language):

class Animal
class Cat : Animal
class Dog : Animal

class AnimalManager {
  void add(Animal a) { 
    a match {
       case Cat => // do something with cats
       case Dog => // do different something with dogs
    } 
  }
}

Now what if I'm using a language like C++ which does not support matching on type in this manner. Two solutions I could think of are:

  1. Use dynamic_cast. However, I'm told dynamic cast should be avoided because it can lead to run-time errors, so this may be bad practice.
  2. Use virtual functions. I could do something like the following (again no particular language, but you should get the gist):
class Animal {
  virtual void beAdded(AnimalManager am)
}
class Cat : Animal {
  void beAdded(AnimalManager am) {
    am.doThingsWithCats(this)
  }  
}
class Dog : Animal {
  void beAdded(AnimalManager am) {
    am.doThingsWithDogs(this)
  }  
}

class AnimalManager {
  void doThingsWithDogs(Dog d) {
    // do something with dogs
  }
  void doThingWithCats(Cat d) {
    // do something with cats
  }
  void add(Animal a) {
    a.beAdded(this)
  } 
}

This is obviously extremely awkward and has other problems (now Animal needs to know about AnimalManager?).

What is the best way to do this sort of pattern in object-oriented languages? Is there some "design pattern" here I should know about?

Aucun commentaire:

Enregistrer un commentaire