Wednesday, January 22, 2014

Object oriented design principles III


Hi Everyone, Today I am going to explain about two remaining OOP design principles I have mentioned in my first blog post.

Interface Segregation Principle-ISP

 

"Client should not force to implement interfaces they do not want to use. Instead of one common large interface many small interfaces are preferred to use."

"Many single purpose interfaces are better than one common purpose interface."
Basically ISP states,
No client should be forced to depend on methods it does not want to use.


Now I will explain what ISP really means. When we create an interface we can define several methods in it. Then when we are going to use this interface we must implement each and every method in it. Otherwise it will give some compilation errors. But sometimes client does not want to implement all methods in the interface. Such kind of situations client should not force to use methods it does not want to use .That is what interface segregation principle said.

I will explain this using a simple example with object oriented programming.

    public interface IBird
    {
        void Eat();
        void Drink();
        void Fly();
        void Swim();
    }

    public class parrot : IBird
    {
        public void Eat()
        {
            //Do some thing
        }
        public void Drink()
        {
            //Do some thing
        }
        public void Fly() 
        {
            //Do some thing
        }
        public void Swim()<=Parrot doesn't swim ,here we force it to swim
        {
            //Do some thing
        }
    }
    public class Duck : IBird
    {
        public void Eat()
        {
            //Do some thing
        }
        public void Drink()
        {
            //Do some thing
        }
        public void Fly() <=Duck doesn't fly,here we force it to fly
        {
            //Do some thing
        }
        public void Swim()
        {
            //Do some thing
        }
    }


There is an interface called IBird and it has four method definitions such as Eat(),Drink(),Fly() and Swim() .There are two classes, Parrot and Duck .Both classes are inherited by IBird interface. So both classes happened to implement four methods define in the interface. But you all know Duck does not fly and parrot does not swim. But in here duck force to fly and parrot force to swim .So this is violating interface segregation principle.

We will see how to ensure interface segregation principle in this situation. To do it we have to create two different interfaces which are also inherit from IBrid interface. Below code snippet will show this properly.

    public interface IBird
    {
        void Eat();
        void Drink();
    }

    public interface ISwimmingBird : IBird
    {
        void Swim();
    }

    public interface IFlyingBird : IBird
    {
        void Fly();
    }

    public class parrot : IFlyingBird
    {
        public void Fly()
        {
            //Do some thing
        }
        public void Eat()
        {
            //Do some thing
        }
        public void Drink()
        {
            //Do some thing
        }
    }


    public class Duck : ISwimmingBird
    {
        public void Swim()
        {
            //Do some thing
        }
        public void Eat()
        {
            //Do some thing
        }
        public void Drink()
        {
            //Do some thing
        }
    }
Here Parrot and Duck implements only methods they want to use .They do not force to use unwanted methods. That how we ensure ISP and we do not violate the principle.

Like each and every principle ISP is also a one which require additional time and effort in software design. But this provides more flexibility and more meaningful software design.

Dependency Inversion Principle-DIP


"Instead of lower level modules defining an interface that higher level module depend on, higher level modules define an interface that lower level module implement."


Let’s try to understand DIP using a real world example. Think you have several devices like phone, camera etc. These devices use cables to connect with charger or PC. They have ports or jacks to connect with charger or PC. Then if I ask, who is defined the port or jack? Cable or device?
You will definitely answer it as device. Yes, you are correct .This means port never decides what will be the device and devise decide what will be the port. In the example device is higher level module and cable is lower level module .So this shows dependency inversion principle.

This is similar to software design. Higher level module defines the interface and lower level module implements that interface and lower level module doesn’t define the interface like cable doesn’t define port or jack.

DIP according to Bob Martins definition
“A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
 B. Abstractions should not depend upon details. Details should depend upon abstractions.”

According to this higher level module should not depend on lower level modules .An abstract layer should between both layers. So both layers depend on abstraction. In abstract layer we can define interfaces to connect both layers.

When this principle is applied the higher level modules does not working directly with lower level modules. They are always using interfaces as abstract layer. 

There is a solution called IOC (Inversion of control) to ensure dependency inversion principle .I am not going to talk about it .There are lot of articles related to IOC in web. You can refer one of them to understand it.

In this article I have explained about Interface segregation principle and dependency inversion principle .I think you could get the basic idea of these two principles and you could understand how we apply these principles when you are going to design a program or application.

There are more principles other than those categorized as SOLID by uncle Bob. I am not going to describe each and every principle in detail now but they are,
·         Program to Interface Not Implementation.
·         Don't Repeat Yourself.
·         Encapsulate What Varies.
·         Depend on Abstractions, Not Concrete classes.
·         Least Knowledge Principle.
·         Favor Composition over Inheritance.
·         Hollywood Principle.
·         Apply Design Pattern wherever possible.
·         Strive for Loosely Coupled System.
·         Keep it Simple and Sweet / Stupid.

Finally we come to the end of OOP design principles session and I hope you all understand the real value of these principles and I hope you will think to apply these principles as much as possible when you are going to design and develop a program module.

“ SOLID is not a must to follow but it is a best practice in object oriented programming .It can manage changes , it can provide more flexible, maintainable, Extendable software design”
 

Monday, January 6, 2014

Object oriented design principles II

Hi all,Sorry I could not continue my blog post for a long time since I was too busy.So today I got a holiday and I thought to continue my writing .
I have explained about two basic object oriented principles in my first blog post.Hope you could understand both principles well.Now I am going to explain about a remaining  principle I have mentioned on my earlier post .

Liskov Substitution Principle -LSP
Objects in program module should be replaceable with instance of their sub-types without altering the correctness of that program.
  
Derived types must be completely substitutable  for their sub-types .


When designing and developing a program module we always follow basic OOP concepts as much as possible.Every time we design a program we create a class hierarchy for the module.That means we use inheritance (parent child relationships) .So we create Parent classes , sub classes to do our functions.

In liskov substitution principle says if a program module use a base class ,then the reference to a base class (instance of base class) can be replaceable with a instance of sub class without effecting the functionality of the program. In simply it says object instance of base class should be replaceable with its a instance of sub-type without doing any changes .

I will explain this with a well known example .This explains violation of liskov substitution principle.

There are two classes called Rectangle and Square.Square is a sub class of Rectangle .So its inherited from Rectangle.And there is an another class called RectangleFactory. There is a method to returning a Rectangle object.As u can see we are going to use Factory design pattern here.


class Rectangle
    {
        protected int bWidth;
        protected int bHeight;
        public void setWidth(int width)
        {
            bWidth = width;
        }

        public void setHeight(int height)
        {
            bHeight = height;
        }

        public int getWidth()
        {
            return bWidth;
        }

        public int getHeight()
        {
            return bHeight;
        }

        public int getArea()
        {
            return bWidth * bHeight;
        }
    }

    class Square : Rectangle
    {
        //In sqare width=height
        public void setWidth(int width)
        {
            bWidth = width;
            bHeight = width;
        }

        public void setHeight(int height)
        {
            bHeight = height;
            bWidth = height;
        }
    }

    static class RectangleFactory
    {
        public static Rectangle getRectangle()
        {
            return new Square();
        }
    }

    //Test class for testing the example

    class Test
    {
        public void testMethod()
        {
            Rectangle rec = RectangleFactory.getRectangle();
            rec.setHeight(5);
            rec.setWidth(10);
            int area = rec.getArea();
            Console.WriteLine("Area of rectangle is " + area);
        }
    }

From this program you will expect answer as "Area of rectangle is 50" .But this will give you 100 instead of 50.That means this will violate LSP. Because Square is a sub-type of Rectangle but its not a replaceable with rectangle object without changing the code.
As LSP says,
"we must make sure that new derived classes are extending the base classes without changing their behavior"

But in above program we changed the setWidth() and setHeight() methods in sub class. That's why we are getting wrong result and violate Lisskov substitution principle.

I hope you guys understand the idea behind liskov substitution principle And i hope u will think about this principle when you going to develop a system.You have to try  not to violate these principles.Its not a must but its a best practice in object oriented programming.