10 December, 2012

Open Close Principle


Open Close Principle is an Object Oriented Design principle. It is first introduced by Betrand Meyer in 1988. He says “Software entities (Class, module, function etc.) should be open for extension, but closed for modification”. An entity is “Open for extension” means that its behavior can be extended to accommodate new demand. The entity is “closed for modification” means that the existing source code of the module is not changed or minimum change when making enhancement. It is clear that if a system cannot accommodate change easily, its life cycle will end fast.

Sometimes code changes introduce heavy risk. At the time of changing, you must ensure that changes will not break the system. Sometimes it takes huge regression testing. This risk can be minimized if no changes are made to existing code.

So, our intention should be writing code in such a way that new functionality should be added with minimum changes or not changes in the existing code.  It should be done in a way to allow the adding of new functionality as new classes, keeping as much as possible existing code unchanged. The major advantages of “open close principle” is that it undergo changes and its value will be tremendous. It required almost no regression testing.


Let’s introduce open close principle with an example. Suppose, in our application, we need a “Area calculator” which calculate area of rectangle. However, in this occasion we just create a class AreaCalculator then there will be a method RectangleArea in this class which just calculates area of rectangle. It works fine. In the middle of the application development, we need to calculate area of Triangle and Circle. In this occasion, what should we do? We just add another two method TriangleArea and CircleArea and can do the job. But several problems will arise here – for each new shape you have to add new unit of code. Developer must have to know the logic to calculate area of new shape. Adding a new shape might effect in existing functionalities. So, it will take huge cost of regression testing. This is actually violate, open close principle.

We implement the same problem abide by open close principle by the following way. Here Rectangle, Triangle and Circle class inherit the Shape class and implement CalculateArea Method. In this way, if you need to calculate area of x shape just add a class of x and then implement shape and calculate area of x without modifying exiting code.

Class diagram:


Open Close Principle Implementation by C#:

Step 1: Create abstract Shape class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OCP
{
    public abstract class Shape
    {
        public abstract double CalculateArea();
    }
}

Step 2: Create Rectangle class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OCP
{
    public class Rectangle : Shape
    {
        public double Height { get; set; }
        public double Width { get; set; }

        public Rectangle(double height, double width)
        {
            this.Height = height;
            this.Width = width;
        }
    
        public override double CalculateArea()
        {
            return Height * Width;
        }
    }
}

Step 3: Create Triangle class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OCP
{
    public class Triangle : Shape
    {
        public double Base { get; set; }
        public double Height { get; set; }

        public Triangle(double vbase, double vheight)
        {
            this.Base = vbase;
            this.Height = vheight;
        }

        public override double CalculateArea()
        {
            return 1 / 2.0 * Base * Height;
        }
    }
}


Step 4: Create circle class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OCP
{
    public class Circle : Shape
    {
        public double Radius { get; set; }


        public Circle(double radius)
        {
            this.Radius = radius;
        }

        public override double CalculateArea()
        {
            return Math.PI * Radius * Radius;
        }
    }
}


Step 5: Client class which uses Rectangle, Triangle and Circle class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OCP
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Shape objShape = new Rectangle(20, 30);
            Console.WriteLine("Area of Rectangle: " + objShape.CalculateArea());

            objShape = new Triangle(20, 30);
            Console.WriteLine("Area of Triangle: " + objShape.CalculateArea());

            objShape = new Circle(4);
            Console.WriteLine("Area of Circle: " + objShape.CalculateArea());


            Console.ReadKey();
        }
    }
}

07 December, 2012

Iterator Design Pattern


Iterator pattern is a design pattern which is used to traverse aggregate object often called container and access container’s object without exposing it’s underlying representation. Iterator pattern decoupled algorithm from aggregate object or container. In some cases, algorithms are container specific. We often use collection in C# and then we traverse the collection without knowing it’s internal details. Collection is grouping of some object. Objects can be same type or different type. Collection in fact actively used iterator pattern. 

 
The above figure is UML class diagram for Iterator Pattern. The main idea behind the iterator pattern is to take the responsibility of traversing container and put it to the iterator object. The iterator object will maintain the state of the iteration, keeping track of the current item and track for the next item to iterate.

Benefits:
1.       Access element of container without exposing it’s internal details.
2.       Provides a uniform interface for traversing different collection (aggregate object).
3.       Provides multiple simultaneous traversals in a collection.

Implementation:
Let’s come to the point. We are going to implement iterator design pattern. I am using here a collection for fruits item. The main actor in here:

IIterator – Interface to define Iterator (Concrete iterator class)
Iterator – Concrete iterator class which is used to iterate elements.
ICollection – Interface to define aggregate.
Collection – Concrete aggregate class.

I used FruitItem class as item class here.

Step 1: Create Item class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    /// 
    /// Item class
    /// 
    public class FruitItem
    {
        public string Id { get; set; }
        public string Name { get; set; }

    }

}

Step 2: Create IIterator Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    /// 
    /// Interface for Iterator
    /// 
    public interface IIterator
    {
        FruitItem First();
        FruitItem Next();
        FruitItem CurrentItem { get; }
        bool IsDone { get; }
    }
}

Step 3: Create concrete Iterator class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    /// 
    /// Concrete Iterator Class
    /// 
    public class Iterator : IIterator
    {

        private Collection collection;
        private int current = 0;
        private int step = 1;

        public Iterator(Collection vCollection)
        {

            this.collection = vCollection;

        }

        public FruitItem First()
        {
            current = 0;
            return (FruitItem)collection[current];
        }

        public FruitItem Next()
        {
            current ++;

            if (!IsDone)
                return (FruitItem)collection[current];
            else
                return null;
        }


        public bool IsDone
        {
            get { return current >= collection.Count; }
        }


        public FruitItem CurrentItem
        {
            get { return (FruitItem) collection[current]; }
        }

        // Gets or sets stepsize
        public int Step
        {
            get { return step; }
            set { step = value; }

        }


    }
}


Step 4: Create collection interface.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    /// 
    /// Interface for Aggregate class
    /// 
    public interface ICollection
    {
        Iterator CreateIterator();
    }
}

Step 5: Create concrete collection class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace IteratorPattern
{
    /// 
    /// Concrete aggregate class
    /// 
    
    public class Collection : ICollection
    {
        private ArrayList lstFoodItem = new ArrayList();

        public Iterator CreateIterator()
        {
            return new Iterator(this);
        }


        // Get counted items
        public int Count
        {
            get 
            { 
                return lstFoodItem.Count;
            }

        }



        // Indexer

        public object this[int index]
        {

            get { return lstFoodItem[index]; }

            set { lstFoodItem.Add(value); }

        }
    }
}


Step 6: Create client class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    class Program
    {
        public static void Main(string[] args)
        {
            Collection collection = new Collection();

            collection[0] = new FruitItem() { Id = "1", Name = "Mango" };
            collection[1] = new FruitItem() { Id = "2", Name = "Orange" };
            collection[2] = new FruitItem() { Id = "3", Name = "Banana" };
            collection[3] = new FruitItem() { Id = "4", Name = "Apple" };
            collection[4] = new FruitItem() { Id = "5", Name = "Lichi" };
            collection[5] = new FruitItem() { Id = "7", Name = "Tamarind" };


            // Create iterator
            Iterator iterator = new Iterator(collection);
            Console.WriteLine("Items by iterating over collection");

            for (FruitItem item = iterator.First(); !iterator.IsDone; item = iterator.Next())
            {
                Console.WriteLine(item.Name);
            }

            Console.ReadLine();
        }
    }
}

Output: