I have tried to implement the Head First Duck problem with Startegy. I am trying to implement the Decoy Duck, which intially don't have the facility to Quack or Fly is implemented by calling a a default constructor( I know this duck don't have the ability to Fly or Quack). All other Ducks are intitialized by calling the overriden consturctor. In the book a duck with no Fly is implemented with a class FlyNoFly which implements the IFly interface.
For my solution, i am not using this class. Instead, i am checking in the base duck class the Fly propery whether a valid instance is passed for it or not (by if(Fly != null) . if the Fly has a valid reference, then only i am invloking the fly method on that. Else i am throwing a default message.
I want to know whether my implementation is violating any design principle / Whether this is a valid implementation.
Thanks TutuMon
public abstract class Duck
{
public IFlyable Fly { get; set; }
public IQuackable Quack { get; set; }
public void PerformQuack()
{
//Is this checking valid as per OO?
if (Quack != null)
Quack.Quack();
else
Console.WriteLine("Quack Operation Not supported");
}
public void PerformFly()
{
//Is this checking valid as per OO?
if (Fly != null)
Fly.Fly();
else
Console.WriteLine("Fly Operation not supported");
}
public abstract void Swim();
}
public class MallardDuck : Duck
{
public MallardDuck()
{
}
public MallardDuck(IFlyable fly, IQuackable quack)
{
Fly = fly;
Quack = quack;
}
public override void Swim()
{
Console.WriteLine("Mallard Duck is Swimming");
}
}
//No Fly and Quack behaviour by default
public class DecoyDuck : Duck
{
public DecoyDuck()
{
}
public DecoyDuck(IFlyable fly, IQuackable quack)
{
Fly = fly;
Quack = quack;
}
public override void Swim()
{
Console.WriteLine("DecoyDuck Duck is Swimming");
}
}
public interface IFlyable
{
void Fly();
}
public class FlyWithWings : IFlyable
{
public void Fly()
{
Console.WriteLine("You are flying with wings");
}
}
public class RocketFly : IFlyable
{
public void Fly()
{
Console.WriteLine("Rocket Powered Fly");
}
}
public interface IQuackable
{
void Quack();
}
public class RealQUack :IQuackable
{
public void Quack()
{
Console.WriteLine("This is Real Quack");
}
}
public class PowerQuack : IQuackable
{
public void Quack()
{
Console.WriteLine("Powerful Quacking ");
}
}
public class Program
{
public static void Main(string[] args)
{
Duck mallard = new MallardDuck
{Fly=new FlyWithWings(),Quack=new RealQUack()}
mallard.PerformQuack();
mallard.PerformFly();
// He can't Quack or Fly by default
// So i am calling the default constructor.
Duck decoy = new DecoyDuck();
decoy.PerformQuack();
decoy.PerformFly();
// Adding behaviours on the fly
decoy.Fly = new RocketFly();
decoy.Quack = new PowerQuack();
decoy.PerformQuack();
decoy.PerformFly();
Console.Read();
}
}
No, this is not the correct implementation.
The Strategy pattern is used to avoid the use of if (..)
in Object Oriented Code. If you would use the FlyNoFly class you would avoid the if ( null )
check and you can use the same constructor for all Duck objects.