0

Currently, I have the following class design :

  1. AnimalHandler (A base class for all animals)

  2. TigerHandler extends AnimalHandler, LionHandler extends AnimalHandler, LeopardHandler extends AnimalHandler and so on.

  3. TigerHandler, LionHandler, LeopardHandler etc "HAS A" Tiger, Lion, Leopard and so on.

Now the issue is : TigerHandler, LionHandler, LeopardHandler etc are all the same(they have the same methods, etc) except that they deal with Tiger,Lion, Leopard, etc classes respectively. So if I need a new Animal group called Cheetah, I just need to copy any of the (Tiger|Lion|Leopard)Handler and do a search and replace of its "HAS A" class names like Tiger,Lion, Leopard.

Instead of copying/creating a new CheetahHandler as above, is there a way (design) that I can use ? Like, say, a GenericHandler that can deal with any of these "HAS A" classes (like Tiger,Lion, Cheetah, etc).

midhunhk
  • 5,560
  • 7
  • 52
  • 83
M-D
  • 10,247
  • 9
  • 32
  • 35

4 Answers4

4

If all your handlers do is provide type safety, and does nothing else, you can use generics instead:

public class AnimalHandler<T extends Animal> {

    private T theAnimal;

    public T getTheAnimal() {} 

    // Etc

}
NilsH
  • 13,705
  • 4
  • 41
  • 59
2

Using generics is a much better approach.

Make sure all animal classes (Tiger, Lion, Leopard) extends lets say an Animal class. Then use:

public class AnimalHandler<A extends Animal> {
    private A animal;
}

And use animal inside your code.

When you want to instantiate a tiger handler, use it as:

AnimalHandler<Tiger> tigerHandler = new AnimalHandler<>();
BobTheBuilder
  • 18,858
  • 6
  • 40
  • 61
  • I have implemented it as you mentioned (using Generics) and I also found that using a common interface also works fine(without Generics). I still have a question : If I am using the AnimalHandler in a web context and if I pass something like "mysite.com/app.do?animal=tiger", I have to check what animal value I received using an if condition and create the corresponding object as you mentioned (**AnimalHandler tigerHandler = new AnimalHandler<>();**). So there will be a lot of if (or if else) conditions. Is there a way to avoid that as well ? – M-D May 11 '13 at 09:28
0

A bit of details in terms of how each of Tiger,Lion, Leopard classes are used in each of the handler

-- If the method interfaces are all the same, and only internal functionality is different

-- if there is extension on Animalhandler you are doing inside the childHandlers

Then, then you should make AnimalHandler an abstract class (implementing iAnimalHandler) and use generics to process the Animal (Super class for each Tiger,Lion, Leopard )

gurvinder372
  • 66,980
  • 10
  • 72
  • 94
0

As others have noted, generics are a great approach, or you could use a Strategy pattern:

   class Animalhandler {
      List<Animal> animals;
      // add, remove and do stuff with animals
   }

    interface Animal {
        void makeSound();
    }
    class Cat extends Animal {
        public void makeSound() {
        // meow
        }
    }
Ray Stojonic
  • 1,260
  • 1
  • 7
  • 11