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.
- 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 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);
}
}
}
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 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);
}
}
}
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);
}
}
}
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.
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);
}
}
}
Prototype Method
This type of design pattern helps us to copy a created object. So we can copy two similar classes with different values.
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();
}
}
}
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();
}
}
}
That is all in this article...
Have a nice Creating Design Patterns
Burak Hamdi TUFAN
Comments