Factory Design
Pattern in C#?
As per Gang of Four, the Factory Design Pattern is “Define an interface for creating an object
but let sub-classes decide which class to instantiate. The Factory method class
defers instantiation it uses to the sub-classes”. In the Factory pattern,
we create product objects without exposing the logic to the end user.
he Factory Design
Pattern is a creational pattern that provides a way to instantiate objects
without exposing the creation logic to the client. Instead, the client uses a
factory method to create the object. This pattern is useful when the exact type
of object required cannot be predicted until runtime.
Real-Time Example:
Shape Creation
Imagine a graphics
application that needs to create various shapes like circles, squares, and
rectangles. The exact type of shape to create might depend on user input or
some other runtime condition. The Factory Design Pattern can be used to handle
this.
Step 1: Define the
Product Interface
public interface IShape
{
void Draw();
}
Step 2: Implement Concrete Products
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Circle");
}
}
public class Square : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Square");
}
}
public class Rectangle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Rectangle");
}
}
Step 3: Define the Factory Class
public static class ShapeFactory
{
public static IShape GetShape(string shapeType)
{
switch (shapeType.ToLower())
{
case "circle":
return new Circle();
case "square":
return new Square();
case "rectangle":
return new Rectangle();
default:
throw new ArgumentException("Invalid shape type");
}
}
}
Step 4: Use the Factory Pattern
class Program
{
static void Main(string[] args)
{
IShape shape1 = ShapeFactory.GetShape("circle");
shape1.Draw();
IShape shape2 = ShapeFactory.GetShape("square");
shape2.Draw();
IShape shape3 = ShapeFactory.GetShape("rectangle");
shape3.Draw();
}
}
Explanation
- IShape: The product interface that defines the Draw method.
- Circle, Square, and Rectangle: Concrete product classes
that implement the IShape interface.
- ShapeFactory: The factory class with a GetShape method
that takes a shape type as an argument and returns an instance of the
corresponding shape. The factory uses a switch statement to decide which
shape to create.
- Program: The client code that uses the factory pattern to create different
shapes and calls their Draw method.
Summary
The Factory Design
Pattern:
- Provides a way to instantiate objects
without exposing the creation logic.
- Helps in creating objects where the exact
type may not be known until runtime.
- Encapsulates the object creation logic in
a single place, making it easier to manage and extend.
In this example, the ShapeFactory
class encapsulates the logic for creating different shapes. The client code
simply calls the GetShape method with the desired shape type, and the factory
takes care of creating the correct shape instance. This makes it easy to add
new shapes to the application without modifying the existing client code.
Difference B/w Factory and Factory Method design pattern
👉👉👉👉👉 Factory Method design pattern
The terms
"Factory" and "Factory Method" both refer to creational
design patterns in object-oriented programming, but they have distinct purposes
and implementations. Here's a detailed explanation of the differences between
the Factory Pattern and the Factory Method Pattern:
Factory Pattern
Also known as the
"Simple Factory" pattern, this is a design pattern where a separate
class (the factory) is responsible for creating instances of different classes
based on provided input.
Characteristics
- Static Methods: The Factory typically uses
static methods to create objects.
- Single Responsibility: Centralizes object
creation logic in one place, making it easier to manage and modify.
- Not a GoF Pattern: The Factory Pattern is
not one of the original "Gang of Four" (GoF) design patterns but
is still widely used.
Example
public interface IShape
{
void Draw();
}
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Circle");
}
}
public class Square : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Square");
}
}
public class ShapeFactory
{
public static IShape GetShape(string shapeType)
{
switch (shapeType.ToLower())
{
case "circle":
return new Circle();
case "square":
return new Square();
default:
throw new ArgumentException("Invalid shape type");
}
}
}
// Usage
class Program
{
static void Main(string[] args)
{
IShape shape1 = ShapeFactory.GetShape("circle");
shape1.Draw();
IShape shape2 = ShapeFactory.GetShape("square");
shape2.Draw();
}
}
Factory Method Pattern
The Factory Method
Pattern defines an interface for creating an object, but lets subclasses decide
which class to instantiate. The Factory Method Pattern lets a class defer
instantiation to subclasses.
Characteristics
- Inheritance: Relies on inheritance, where
a base class defines the factory method, and derived classes implement
this method.
- More Flexible: Allows subclasses to alter
the type of objects that will be created.
- GoF Pattern: It is one of the original
"Gang of Four" design patterns.
Example
public interface IShape
{
void Draw();
}
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Circle");
}
}
public class Square : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Square");
}
}
public abstract class ShapeFactory
{
public abstract IShape CreateShape();
public void DrawShape()
{
IShape shape = CreateShape();
shape.Draw();
}
}
public class CircleFactory : ShapeFactory
{
public override IShape CreateShape()
{
return new Circle();
}
}
public class SquareFactory : ShapeFactory
{
public override IShape CreateShape()
{
return new Square();
}
}
// Usage
class Program
{
static void Main(string[] args)
{
ShapeFactory factory1 = new CircleFactory();
factory1.DrawShape();
ShapeFactory factory2 = new SquareFactory();
factory2.DrawShape();
}
}
Key Differences
- Intent:
- Factory Pattern: Centralizes object creation logic in a
single method or class.
- Factory Method Pattern: Uses inheritance to allow subclasses to
decide which class to instantiate.
- Implementation:
- Factory Pattern: Typically uses static methods and does
not rely on inheritance.
- Factory Method Pattern: Uses abstract or virtual methods that
subclasses override to create specific instances.
- Flexibility:
- Factory Pattern: Less flexible as it centralizes
creation logic.
- Factory Method Pattern: More flexible as it allows subclasses
to customize the creation process.
- Design Complexity:
- Factory Pattern: Simpler to implement and understand.
- Factory Method Pattern: More complex, but offers greater
extensibility.
When to Use
- Factory Pattern: When you have a straightforward object
creation process that can be centralized and doesn't need to be extended
or customized.
- Factory Method Pattern: When you anticipate that the object
creation process will need to be extended or customized by subclasses.
Each pattern has its
own strengths and use cases, and the choice between them depends on the
specific needs of your application.