1

I'm new in design patterns and now I am learning about Factory Method pattern. I try to make an example using animals.

I have an Animal interface with two methods, breathe and walk. Implementing this interface I have two classes, Giraffe and Flamingo.

Following the pattern I have two factories, one for Giraffes and one for Flamingos and a main class like this:

if (color.equals("yellow")) {
  factory = new GiraffeFactory();
} else {
  factory = new FlamingoFactory();
}

Animal animal = factory.createAnimal();
animal.breathe();
animal.walk();

This works perfectly but now I realise that Flamingos can fly. I don't want to include this method in Animal interface because Giraffes can't.

How can I call this new method only in Flamingo Animal instances? Is cast the only solution? Or is this pattern only for objects that has the same methods from their interface?

((Flamingo) animal).fly();

Thank you so much.

  • You could create a `FlyingAnimal` interface extending `Animal`. Point is what you need in each case: If you need a method that receives an `Animal` to make him fly (calling `.fly()`), then, you actually are expecting a `FlyingAnimal`, not just an `Animal`, so you must change the method signature to receive a `FlyingAnimal` – Héctor May 21 '18 at 11:13

3 Answers3

1

Well the usage of this pattern wouldn't make much sense, the whole point is that you don't know what implementation of Animal you will get (responsibility separation), so it would be a total anti-pattern to use the knowledge. You can make a new interface Winged or something, and make Flamingo implement it. Then you can always check. remember that bats also fly when thinking of a name ;)

if (animal instanceof Winged) {
    Winged winged = (Winged) animal;
    winged.fly();
}
Jan Ossowski
  • 328
  • 1
  • 2
  • 18
  • just to be clear, I gave a solution to the specific problem You presented (however abstract), but the whole idea of design patterns is to increase code clarity, readability and usability, so it's usually case-specific what approach you want to take – Jan Ossowski May 21 '18 at 11:09
0

You can create another interface called WingedAnimal that extends Animal.

public interface WingedAnimal extends Animal { 
   public void fly();
}

public class Flamingo implements WingedAnimal {
   @Override
   public void breath() {}
   @Override
   public void walk() {}
   @Override
   public void fly() {}
}

Then write this code while creating Flamingo instance:

WingedAnimal animal = (Flamingo) factory.createAnimal();

Your code animal.fly() will work perfectly.

Quang Vien
  • 308
  • 2
  • 10
0

You can use s factory method using generics. A couple of good examples are available

  1. Here in C#
  2. Here always in C#
  3. Here in java.

I suggest you read all of them for a good understanding of the problem and possible solution approaches.

Gianpiero
  • 3,349
  • 1
  • 29
  • 42