Design Pattern - Daily Learning

Friday, June 11, 2010

To begin with we write a game where ducks can swim and quack. We used OO inheritance:




One way was to create a virtual function in Duck class and override in Rubberduck class. But then again we realized that requirements keep changing and there is a new type of duck added called DecoyDuck which should neither flies nor quacks. And we will have many different types of duck to be added to the game in future behaving differently and we will be forced to override everytime.


So we thought of implementing an interface for fly and quack methods. Duck that fly and quack will implement that interface. So we have separated the behaviors that vary.

Later we wanted to ducks to fly in the game. If I add fly method to Duck class then all the ducks will start flying including Rubberduck which I don't want to fly.


Identify the aspects of your application that vary and separate them from what stays the same.


Based on the above principle, fly and quack are varying. So we'll pull out both the methods and create a new set of classes to represent each behavior.


To keep things more flexible we would want to assign behaviors to the instances of Duck class during run time and should be able to change it.


Program to an interface not an implementation


So based on the second principal just mentioned, we will create interfaces for the Fly and Quack.

So Duck class will look something like this


public class Duck

{

IFlyBehavior flyBehavior;

public void PerformFly()

{

flyBehavior.Fly();

}

}


public class MallardDuck : Duck

{

public MallardDuck()

{

flyBehavior = new FlyWithWings();

}

}


So now things are loosely coupled and cal be reused. What if I have to change a fly behavior at run time. It simple now, we just have a setter for flying behavior of duck in Duck class.


SetFlyBehavior(IFlyBehavior ifb)

{

flyBehavior = ifb;

}


Let us See how we will use setter


Duck d = new MallardDuck ();

d.PerformFly();

d.SetFlyBehavior( new FlyNoWay());

d.PerformFly();






We noticed that each Duck has a FlyBehavior to which it delegates its flying behavior.

So we are not inheriting their behavior but letting them change during runtime. Putting classes them together in such a way is called Composition.


Favor Composition over Inheritance.


So with these three principals, we have learnt first design pattern called Strategy


The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.

0 comments: