mardi 11 septembre 2018

Strategy Pattern violating Liskov's substitution principle

I am implementing Strategy Pattern for implementing behaviour of different types of ducks . Here is the code:

public abstract class Duck
{
  IFlybehaviour flybehaviour;
  Duck()
  {
  }
  public void PerformFly()
  {
   flybehaviour.fly();
  }
}

public class SimpleDuck
{
  public SimpleDuck(IFlybehaviour flybehaviour)
  {
    flybehaviour = new GeneralFlybehaviour();
  }
}

public interface IFlybehaviour 
{
  public void fly();
}
public class GeneralFlybehaviour
{
  public void fly()
  {
    Console.WriteLine("I can fly as a duck");
  }
}

In the main method
void main()
{
  Duck d = new SimpleDuck();
  d.PerformFly();
}

This obeys both "Open Closed Principle" and "Liskov's Substitution Principle" where I am able to create 50 different types of ducks like SimpleDuck,FlyingDuck etc.

Now I need a class ComplicatedDuck where it has a special power to grant wishes of its disciples lets say:

public class ComplicatedDuck
{
  public ComplicatedDuck(IFlybehaviour flybehaviour)
  {
    flybehaviour = new GeneralFlybehaviour();
  }

 public void GrantWishes()
 { 
   Console.WriteLine("Wish Granted")
 }
}

With this change we know that it is violating "Liskov's Substitution principle" where this subclass will not replace its Baseclass completely.

Suppose if I add one more function in "abstract class Duck" then all the inherited members atleast need to provide a implementation saying that "I dont grant special wishes" .

In this scenario which is the better solution , adding a method in ComplicatedDuck class or extending the BaseClass

Note : Same concept works for Java also just replacing ":" by "implements" keyword.

Aucun commentaire:

Enregistrer un commentaire