Introduction
In this article, We are going to explore the need of following design patterns in our daily programming routine and one example of a creational design pattern with the help of a Factory pattern.
Overview
As a developer, we tend to write a code on daily basis.
What is the important key while writing any code?
The very obvious answer is that we need to follow some practices (SOLID Principles) and coding standards while writing any code.
So, let's get started with a few flaws of coding that need to be taken care of for better application performance.
Design Flaws
- Much of the time, we force the classes to depend on each other. This scenario lands into making classes tightly coupled.
- Some developers, put more stress on the classes by adding more responsibilities to them. Sometimes the functionality is irrelevant to the class where it has been included.
- In a few scenarios, the same code gets repeated to multiple places. We can say the code duplicity occurs in the system/ application which may reduce your application performance.
In this article, we are going to discuss the Factory design pattern.
What is a Factory Pattern?
The factory pattern is a creational design pattern. It is mainly used when we want to provide more flexibility to our code.
Instead of making a direct constructor call using a new keyword, the Factory pattern defines a method. Derived classes can override this method to change the class of the objects that will be created.
Here, we conclude that a Factory pattern is one of the creational design pattern, which solves the problem of creating product objects without mentioning their concrete classes.
Let's see how we can achieve this with a practical example.
Below is the example of creating the Factory design pattern for the Vehicle class:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace FactoryPattern
- {
- class Program
- {
- abstract class Vehicle
- {
- public abstract ICar FactoryMethod();
- public string ConcreteMethod()
- {
-
- var car = FactoryMethod();
- var result = "This is concrete method : " + car.DisplayMessage();
- return result;
- }
- }
- class BMWCar : Vehicle
- {
- public override ICar FactoryMethod()
- {
- return new BMW();
- }
- }
- class AudiCar : Vehicle
- {
- public override ICar FactoryMethod()
- {
- return new Audi();
- }
- }
- interface ICar
- {
- string DisplayMessage();
- }
-
- class BMW : ICar
- {
- public string DisplayMessage()
- {
- return "This is BMW Class implementation ";
- }
- }
- class Audi : ICar
- {
- public string DisplayMessage()
- {
- return "This is Audi Class implementation ";
- }
- }
- class Client
- {
- public void Main()
- {
- Console.WriteLine("Method for BMW.");
- ClientCode(new BMWCar());
-
- Console.WriteLine("");
-
- Console.WriteLine("Method for Audi.");
- ClientCode(new AudiCar());
- }
-
- public void ClientCode(Vehicle vehicle)
- {
- Console.WriteLine("Client: I'm not aware of the derived class," +
- "but it still works.\n" + vehicle.ConcreteMethod());
- }
- }
-
- static void Main(string[] args)
- {
- new Client().Main();
- Console.ReadLine();
- }
-
- }
-
-
-
-
-
-
- }
Let's step into the coding explanation,
Line No. 11
The Vehicle class declares the factory method (ConcreteMethod) i.e. supposed to return an object of a car class. The deriving class of the vehicle class usually provides the implementation of this method.
Note that the Vehicle may also provide some default implementation of the factory method (ConcreteMethod).
Despite the name, Vehicle's primary responsibility is not creating cars. Mainly, it contains some core business logic that relies on Car objects, returned by the factory method(Concrete Method). Derived subclasses can indirectly change that business logic by overriding the factory method and returning a different type of vehicle object i.e. car from it.
Line No. 17
Call the factory method to create a car object.
Line No. 18
Use a car object.
Line No. 22 to 35
BMWCar and AudiCar override the Concrete Method to create an object of respective car type.
Note that the signature of the method still uses the abstract car type, even though the concrete car is actually returned from the method. This way the BMWCar and AudiCar can stay independent of concrete car classes.
Line No 36
Car declares method - DisplayMessage that all concrete cars must implement.
Line No. 42 to 54
Concrete cars provide implementation of the Car interface.
Line No. 68
The client code works with an instance of a concrete Vehicle, through its base interface. As long as the client keeps working with Vehicle via the base interface, you can pass it to any Vehicle’s subclass.
After a successful build and execution, you will see the below output screen:
Summary
In the above article, We explored the need for following design principles(SOLID) and patterns in our daily programming routine to avoid design flaws and one of the examples of a creational design pattern with the help of a Factory pattern. I hope you liked the article
Until next time - Happy Reading
Cheers