Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
2.28/5 (4 votes)
See more:
Hi,
Can someone help with the best way of designing the classes for the below requirement. I don't want to implement the same method multiple times. Can someone tell me even which design patter suits it better.

Tiger: Walk(), Run(), Swim()
Horse: Run(), Swim()
Tortoise: Walk(),Swim()
Fish: Swim()

Thanks,
Ramana

What I have tried:

Couldn't find a better way myself.
Posted
Updated 28-Sep-18 5:20am
Comments
F-ES Sitecore 26-Sep-18 8:56am    
Do your classes all have the same implementation? Does a fish swim the same way as a horse does?

Have you looked into abstract classes, virtual classes, inheritence?
 
Share this answer
 
Comments
Graeme_Grant 27-Sep-18 17:43pm    
Countered the 1 vote for a valid answer
You should use class inheritance (abstract classes, virtual classes as suggested in solution 1) and the Factory pattern to hide the details of the implementation behind interfaces - here is an example without interfaces: Factory Method .NET Design Pattern in C# and VB - dofactory.com[^]

Once you have the sample in place with your animals - you can have each class implement an interface and make only that interface in the return type of the factory visible.

This pattern implemented in a Library project allows you to set the animal classes to internal and make their details invisible to the outside world (only the interfaces and the Factory class should be public if you end up with the right design).
 
Share this answer
 
v2
Comments
Graeme_Grant 27-Sep-18 17:43pm    
Countered the 1 vote for a valid answer
Ramana Bellary 28-Sep-18 2:27am    
Below is what I have come with, let me know if you have any better solution.

public abstract class Creature
{
public virtual void Walk()
{

}

public virtual void Run()
{

}

public virtual void Swim()
{

}
}
public class Tiger : Creature
{

}
public class Horse : Creature
{
public override void Walk()
{
throw new Exception("Can walk");
}
}
public class Fish : Creature
{
public override void Walk()
{
throw new Exception("Can walk");
}

public override void Run()
{
throw new Exception("Can Run");
}
}
public class Tortoise : Creature
{
public override void Run()
{
throw new Exception("Can Run");
}
}
Dirk Bahle 28-Sep-18 7:19am    
Thats a great start but you can still run into problems once you are looking at a large code base - what you want to do in this case is to seal your classes away into a library project and then have only the factory method and the interface definition be visible to the outside world. Copy the code below into a library project, reference the library in the startup project and use the following line to create for example a Horse: ICreature hores = Factory.CreateHorse()

    internal abstract class Creature
    {
        public virtual void Walk()
        {

        }

        public virtual void Run()
        {

        }

        public virtual void Swim()
        {

        }
    }

    public interface ICreature
    {
        void Walk();

        void Run();

        void Swim();
    }

    internal class Tiger : Creature, ICreature
    {

    }

    internal class Horse : Creature, ICreature
    {
        public override void Walk()
        {
            throw new Exception("Can walk");
        }
    }

    internal class Fish : Creature, ICreature
    {
        public override void Walk()
        {
            throw new Exception("Can walk");
        }

        public override void Run()
        {
            throw new Exception("Can Run");
        }
    }

    internal class Tortoise : Creature, ICreature
    {
        public override void Run()
        {
            throw new Exception("Can Run");
        }
    }

    public static class Factory
    {
        public static ICreature CreateTiger()
        {
            return new Tiger();
        }

        public static ICreature CreateHorse()
        {
            return new Horse();
        }

        public static ICreature CreateFish()
        {
            return new Fish();
        }

        public static ICreature CreateTortoise()
        {
            return new Tortoise();
        }
    }
public abstract class Creature
{
public virtual void Walk()
{

}

public virtual void Run()
{

}

public virtual void Swim()
{

}
}
public class Tiger : Creature
{

}
public class Horse : Creature
{
public override void Walk()
{
throw new Exception("Can walk");
}
}
public class Fish : Creature
{
public override void Walk()
{
throw new Exception("Can walk");
}

public override void Run()
{
throw new Exception("Can Run");
}
}
public class Tortoise : Creature
{
public override void Run()
{
throw new Exception("Can Run");
}
}
 
Share this answer
 
v2
Clearly, we can apply the Strategy Design pattern for the mentioned problem. You can have different strategies like Walk, Run, Swim and change their implementation at runtime with the help of constructor dependency injection.
You can have Animal abstract class, different child class will inherit from the animal class. there will be reference for strategy interface in the animal abstract class.

C#
public abstract class Animal
  {
      IWalkBehaviour walkBehaviour;
      IRunBehaviour runBehaviour;
      ISwimBehaviour swimBehaviour;

      public Animal() { }

      public abstract void LiveLife();

      public void performWalk()
      {
          walkBehaviour.walk();
      }

      public void performRun()
      {
          runBehaviour.run();
      }

      public void performSwim()
      {
          swimBehaviour.swim();
      }

      public void SetWalkBehaviour(IWalkBehaviour walk)
      {
          walkBehaviour = walk;
      }

      public void SetSwimBehaviour(ISwimBehaviour swim)
      {
          swimBehaviour = swim;
      }

      public void SetRunBehaviour(IRunBehaviour run)
      {
          runBehaviour = run;
      }

  }

  public interface ISwimBehaviour
  {
      void swim();
  }

  public class Swim : ISwimBehaviour
  {
      public void swim()
      {
          Console.WriteLine("swim");
      }
  }

  public class NoSwim : ISwimBehaviour
  {
      public void swim()
      {
          Console.WriteLine("no swim");
      }
  }

  public interface IRunBehaviour
  {
      void run();
  }

  public class Run : IRunBehaviour
  {
      public void run()
      {
          Console.WriteLine("run");
      }
  }

  public class NoRun : IRunBehaviour
  {
      public void run()
      {
          Console.WriteLine("no run");
      }
  }

  public interface IWalkBehaviour
  {
      void walk();
  }

  public class Walk : IWalkBehaviour
  {
      public void walk()
      {
          Console.WriteLine("walk");
      }
  }

  public class NoWalk : IWalkBehaviour
  {
      public void walk()
      {
          Console.WriteLine("no walk");
      }
  }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900