Design – Switch vs Polymorphism

designobject-oriented-design

I know this is a classic problem but it's so hard to chose the right way or the best. Let me present you a simplified version of the code.

Design 1 using switch :

public class Disease {
  private Color color;
}

public class City {
   private String name;
   private int yellowCubes;
   private int redCubes;
   private int bluesCubes;
   private int blackCubes;

   public void setCubesOnCity(int cubesNb, Disease disease) {
       cubesNb = computed again ..
       disease.subCubes(cubesNb);
       switch(disease.getColor()) {
           case Colors.BLACK:
               blackCubes += cubesNb;
           //other cases
       }
  }

  public int getCubesOnCity(Disease disease) {
      int cubesNb = 0;
      switch(disease.getColor()){
          case Colors.BLACK:
              cubesNb = this.getBlackCubes();
          // Etc
      }
      return cubesNb;
   }

 }

Design 2 with polymorphism:

public abstract class Disease {
   abstract int getCubesSetOn(City city);
   abstract void setCubesOn(City city, int cubesNb);
}

// One of sub classes
public class BlueDisease extends Disease {

  // Always needed for UI
  public Color getColor(){return Colors.BLUE;}

  @Override
  int getCubesSetOn(City city) {
      return city.getBlueCubes();
  }

  @Override
  void setCubesOn(City city, int cubesNb) {
      int totalCubes = cubesNb + city.getBlueCubes();
      city.setBlueCubes(totalCubes);
  }
}

public class City {
   private String name;
   private int yellowCubes;
   private int redCubes;
   private int bluesCubes;
   private int blackCubes;

   public void setCubesOnCity(int cubesNb, Disease disease) {
       cubesNb = computed again ..
       disease.subCubes(cubesNb);
       disease.setCubesOn(this, cubesNb);
  }

  public int getCubesOnCity(Disease disease) {
       return disease.getCubesSetOn(this);
  }
 }

Now for the additional information.
There are four diseases (four colors). It's a fixed requirement for the game with no real need for a design where it's easy to refactor if we need to add a new disease.

The problem is that I've heard so many contradictory things like switch is a code smell try to use the Command pattern (polymorphism). Don't create useless classes just to access polymorphism (favor switch or command ?). Favor composition over inheritance (switch wins because Color is included in Disease). I'm not used to the Command pattern but it doesn't seem to fit for my needs.

I know that in the grand scheme of things I achieve the same things with the two designs but this a project where I try to improve myself on design. So I would like to have opinions and advice on what should I prefer when I encounter this type of problem…

Thanks you.

Best Answer

switch, or big if elseif blocks are usually considered a code smell. ie there is probably a better solution.

In you case I would have something like..

Dictionary<colour, int> cubeCounts;
...
cubeCounts[disease.Colour] ++;
Related Topic