Code intermediate
Code intermediate

Reputation: 13

instantiating two unrelated subclasses using factory design pattern?

As per my understanding, We can use factory if we have same method implemented by subclasses, something like this

interface IAnimal
{
    void Eat();
}
class Bird : IAnimal
{
    public void Eat()
    {
        // bird eats grain
    }
}

class Tiger : IAnimal
{
    public void Eat()
    {
        // Tiger eats meat
    }
}

our factory

class AnimalFactory
{
    public IAnimal GetInstance(int type)
    {
        // dependind on type we can return
        // animal
    }
}

but what if we have another different method in the subclasses like Fly() in Bird class and Walk() in Tiger class?

class Bird : IAnimal
{
    public void Eat()
    {
        // bird eats grain
    }
    public void Fly()
    {

    }
}

class Tiger : IAnimal
{
    public void Eat()
    {
        // Tiger eats meat
    }
    public void Walk()
    {
 
    }
}

What is the best way to implement? I think, since subclasses do not implement completely one interface, so we should not use a factory design pattern? Of course we can still use and client can use Fly() and Walk() method by casting it back to the respective classes.

But my question is, is this still a valid use case for implementing factory design pattern?

Is my understanding correct?

Upvotes: 1

Views: 153

Answers (1)

Stephen Jennings
Stephen Jennings

Reputation: 13234

If you are using a factory and the calling code cares whether the returned animal can fly or walk, then the factory needs to return a more-derived type.

interface IAnimal { void Eat(); }
interface IFlyingAnimal : IAnimal { void Fly(); }
interface IWalkingAnimal : IAnimal { void Walk(); }

class Tiger : IWalkingAnimal
{
    public void Eat() { }
    public void Walk() { }
}

class Bird : IFlyingAnimal
{
    public void Eat() { }
    public void Fly() { }
}

// The factory lets the caller choose which type of animal it wants:

class AnimalFactory
{
    public IFlyingAnimal GetFlyingAnimal() { return new Bird(); }
    public IWalkingAnimal GetWalkingAnimal() { return new Tiger(); }
}

// or, you can use separate factories:

class FlyingAnimalFactory
{
    public IFlyingAnimal Get() { return new Bird(); }
}

class WalkingAnimalFactory
{
    public IWalkingAnimal Get() { return new Tiger(); }
}

This may or may not be the right solution, depending on the code you are writing. You should choose a pattern that fits your needs.

Your original factory accepts an int type parameter, which makes me think the calling code probably knows it needs a Tiger or a Bird. So other solutions might be to not use a factory, or have the factory return a Tiger specifically:

public void AnimalFactory
{
    public Tiger GetTiger() { return new Tiger(); }
    public Bird GetBird() { return new Bird(); }
}

Upvotes: 1

Related Questions