Explanation of Creational Design Patterns

Explanation of Creational Design Patterns

Hello everyone in this article we are going to talk about Creational Design Patterns. Previous article I have talked about design patterns. Now I want to explain the types of the design patterns. In this article I will talk about Creational Design Patterns types with examples and where can we use them.

First shortly take a look at creational design patterns.

Creational design patterns take care about creating the objects. It offers the solutions to create objects and components in OOP programming.

There are 5 types of Creational Design Patterns:
  • Factory Method
  • Abstract Factory
  • Builder
  • Prototyoe
  • Singleton

Now I will explain them one by one

Factory Method

Factory type of creational design patterns provide us to create objects or components on a central location. Thanks to factory type creating objects is seperating from the main thread and it use the interfaces to create objects. We use the same interfaces for all similar types objects. For example we will create some kind of vehicles like car, truck, bicycle, aircraft... These are all vehicles as you can see.

First we create our classes which derived from same interface. And then we make callbacks from main thread to related class via interface.

Due to we derived all similar types of classes from one interface we use if/else if blocks so much to decide which method be calledback.

Below Image you can see the simple Diagram and example of Factory Method

factory-pattern-diagram-thecodeprogram

Below Code Block You will see the Vehicle interface and than Car and truck classes derived from vehicle interface...

Vehicle interface

namespace FactoryMethod_Example
{
    public interface Vehicle
    {
        string getReady();
    }
}
Car Class

namespace FactoryMethod_Example
{
    class Car : Vehicle
    {
        public string getReady()
        {
            return "Message from Car Class";
        }
    }
}
Truck Class

namespace FactoryMethod_Example
{
    class Truck : Vehicle
    {
        public string getReady()
        {
            return "Message from Truck Class";
        }
    }
}

In my Form Load I calledback these classes one by one and get their messages. I showed that messages on a messagebox.


using System.Windows.Forms;

namespace FactoryMethod_Example
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string message = "";
            //Assignment of interface
            Vehicle _vehicle;

            //Assign class to the defined interface
            _vehicle = new Car();
            message = _vehicle.getReady() + Environment.NewLine;

            _vehicle = new Truck();
            message += _vehicle.getReady();

            MessageBox.Show(message);
        }
    }
}

Below image you can see the output of the program

Factory Method Output

Abstract Factory Method

It is similar to Factory type. The differance between factory and abstract factory usage of interfaces. At factory type we are creating an interface for all similar classes. But in abstract factory we create interface for same types classes.

For Example we create interfaces for all types of vecihles but in abstract factory we create seperate interfaces for cars, aircrafts, trucks... this is the differance between factory and abstract factory types of creational design patterns. So if we need to work multi types objects we can use factory method. So do not need write so many if / else if blocks as factory as much in this type. It is also more flexible than factory type.

Below image you can see the diagram of abstarct factory:

abstract-factory-pattern-diagram-thecodeprogram
Now lets make a simple example and write some codes:
Below ww will create a Area Calculation class and we will make calculation inside this class. also wi will derive subclasses named Circle, Square and rectangle.
AreaCalculation Class

using System;

namespace AbstractFactory_Example
{
    abstract class AreaCalculation
    {
        public static class ShapeTypes {
            public static int Circle = 1;
            public static int Square = 2;
            public static int Rectangle = 3;
        };

        public string makeCalculation(int type, int x, int y)
        {
            if (type == ShapeTypes.Circle)
            {
                //variable y does not important
                return "Area of Circle is: " + (Math.PI * x);
            }
            else if (type == ShapeTypes.Square)
            {
                //variable y does not important
                return "Area of Square is: " + (Math.Pow(x, 2));
            }
            else if (type == ShapeTypes.Rectangle)
            {
                return "Area of rectangle is: " + (x * y);
            }
            else
                return "UnKnown Shape Type";
        }
    }
}
Circle Class

namespace AbstractFactory_Example
{
    class Circle : AreaCalculation
    {
        int diameter = 0;

        public Circle(int _diameter)
        {
            this.diameter = _diameter;
        }
        
        internal string makeCalculation()
        {
            return makeCalculation(AreaCalculation.ShapeTypes.Circle, this.diameter, 0);
        }
    }
}
Square Class

namespace AbstractFactory_Example
{
    class Square : AreaCalculation
    {

        int width = 0;

        public Square(int _width)
        {
            this.width = _width;
        }

        internal string makeCalculation()
        {
            return makeCalculation(AreaCalculation.ShapeTypes.Square, this.width, 0);
        }
    }
}
Rectangle Class

namespace AbstractFactory_Example
{
    class Rectangle : AreaCalculation
    {
        int width = 0;
        int height = 0;

        public Rectangle(int _width, int _height)
        {
            this.width = _width;
            this.height = _height;
        }
        
        internal string makeCalculation()
        {
            return makeCalculation(AreaCalculation.ShapeTypes.Rectangle, this.width, this.height);
        }
    }
}
Form1 Class

using System;
using System.Windows.Forms;

namespace AbstractFactory_Example
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string message = "";
            //Calculate Circle Area
            Circle _circle = new Circle(5);
            message = _circle.makeCalculation() + Environment.NewLine;
            //calculate Square area
            Square _square = new Square(10);
            message += _square.makeCalculation() + Environment.NewLine;
            //calculate rectangle area
            Rectangle _rectangle = new Rectangle(5,15);
            message += _rectangle.makeCalculation();
            //show all area values
            MessageBox.Show(message);
        }
    }
}

And below image will show the output of above program:

Abstaqct Factory Example Output

Builder Method

If we have an object which has multiple subobject, a builder class create all of them and prepare the main class with all subclasses.

For example we want to create a car class. Our builder class creates all a car needs. This class creates: engine, tyres, transmissions, mirrors, seats and then create the car class with all tgese subclasses, last make them ready to use in our main program.

Below Image you can see the Builder Pattern Diagram builder-pattern-diagram-thecodeprogram

Now we will create a FileModel class and we are going to initialize them at first then we will use them at the program.

FileModel.cs

namespace BuilderPattern_Example
{

    public static class FileTypes
    {
        public static int File = 1;
        public static int Folder = 2;
    };

    public class FileModel
    {
        private string FileName = "";
        private string FilePath = "";
        private int FileSize = 0;
        private int FileType = 0;

        public FileModel(string _fileName, string _filePath, int _fileSize, int _fileType)
        {
            this.FileName = _fileName;
            this.FilePath = _filePath;
            this.FileSize = _fileSize;
            this.FileType = _fileType;
        }

        public string getFileName() { return this.FileName; }
        public string getFilePath() { return this.FilePath; }
        public int getFileSize() { return this.FileSize; }
        public int getFileType() { return this.FileType; }

        public string getFileTypeString(int _fileType) {
            return this.FileType.Equals(FileTypes.File) ? "File" : "Folder";
        }

    }
}
Form1.cs

using System;
using System.Windows.Forms;

namespace BuilderPattern_Example
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string message = "";

            //First we will initialize Files using FileModels
            FileModel textFile = new FileModel("TheText", "C:/TheText.txt", 4096, FileTypes.File);
            FileModel textFolder = new FileModel("TheFolder","C:/TheFolder", 4, FileTypes.Folder);

            //and then we will call their methods
            message = "Defined File is:" + Environment.NewLine;
            message += "File Name : " + textFile.getFileName() + Environment.NewLine;
            message += "File path : " + textFile.getFilePath() + Environment.NewLine;
            message += "File Size : " + textFile.getFileSize().ToString() + Environment.NewLine;
            message += "File Type : " + textFile.getFileTypeString(textFile.getFileType()) + Environment.NewLine+ Environment.NewLine;

            message += "Defined Folder is:" + Environment.NewLine;
            message += "Folder Name : " + textFolder.getFileName() + Environment.NewLine;
            message += "Folder path : " + textFolder.getFilePath() + Environment.NewLine;
            message += "Folder Size : " + textFolder.getFileSize().ToString() + Environment.NewLine;
            message += "Folder Type : " + textFolder.getFileTypeString(textFolder.getFileType()) + Environment.NewLine;

            MessageBox.Show(message);
        }
    }
}
Below Image you can see the output of this program: Builder Pattern Example Output

Prototype Method

This type of design pattern helps us to copy a created object. So we can copy two similar classes with different values.

Below Image will show the diagram of the prototype pattern.

prototype-pattern-diagram-thecodeprogram

We will create an abstract class and we will initialize a class and then copy this initialized class to anther same type class

StudentPrototype.cs

namespace PrototypePattern_Example
{
    public abstract class StudentPrototype
    {
        public abstract StudentPrototype Clone();
    }
}
Student.cs

namespace PrototypePattern_Example 
{
    class Student : StudentPrototype
    {
        private int Number;
        private string Name;
        private string Surname;
        private int Grade;

        public Student(int _number, string _name, string _surname, int _grade)
        {
            this.Number = _number;
            this.Name = _name;
            this.Surname = _surname;
            this.Grade = _grade;
        }

        public override StudentPrototype Clone()
        {
            //MemberwiseClone: creates shallow copy of the current object.
            return this.MemberwiseClone() as StudentPrototype;
        }

        public int getNumber() { return this.Number; }
        public string getName() { return this.Name; }
        public string getSurname() { return this.Surname; }
        public int getGrade() { return this.Grade; }
    }
}
Program.cs

using System;

namespace PrototypePattern_Example
{
    class Program
    {
        static void Main(string[] args)
        {
            //First initialize ona class and copy it to other class
            Student stu_one = new Student(33, "Burak Hamdi", "TUFAN", 12);
            Student stu_two = (Student)stu_one.Clone();

            //now get values of second class
            string message = "Cloned Student Data:" + Environment.NewLine;
            message += "Name : " + stu_two.getName() + Environment.NewLine;
            message += "Surname : " + stu_two.getSurname() + Environment.NewLine;
            message += "Number : " + stu_two.getNumber().ToString() + Environment.NewLine;
            message += "Grade : " + stu_two.getGrade().ToString() + Environment.NewLine;

            Console.WriteLine(message);
            Console.ReadLine(); 

        }
    }
}

Below Image will show the output of the program.

prototype pattern output

Singleton Method

With singleton type, we can create a class to use globally. We use related class in all program and we do not need to create it again. We use the static word to make callbacks and we do not use the new word with this related class. Because it has created at ine time and we do not create it again. At singleton type, due to we create it at one time, we have to be careful to create it safely. If there is a problem at the creating this class, it may throw faults during the processing.

SingletonClass.cs

namespace SingletonPattern_Example
{
    public class SingletonClass
    {
        static SingletonClass singletonInstance;
        public string singletonValue = "";

        static SingletonClass()
        {
            singletonInstance = new SingletonClass();
        }

        public static SingletonClass getSingletonInstance()
        {
            return singletonInstance;
        }
    }
}
Program.cs

using System;

namespace SingletonPattern_Example
{
    class Program
    {
        static void Main(string[] args)
        {
            //Here we do not want to use new keyword in singleton Pattern
            //do not initialize singleton class with new keyword
            SingletonClass new_singleton = new SingletonClass();

            //So we will initialize the singleton class with its instance
            //and declared a value to its variable
            SingletonClass singleton = SingletonClass.getSingletonInstance();
            singleton.singletonValue = "The Singleton Example";

            //Now we will use same instance to initialize a second Singleton class
            SingletonClass second_singleton = SingletonClass.getSingletonInstance();

            //Now print the value that we declared before
            Console.WriteLine(second_singleton.singletonValue);
            Console.ReadLine();
        }
    }
}

Below image show the output of the program...

Singleton Pattern Example Output

That is all in this article...

Have a nice Creating Design Patterns

Burak Hamdi TUFAN


Tags


Share this Post

Send with Whatsapp

Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment. Check your inputs!

Comments

  • There is no comment. Be the owner of first comment...