The Factory Pattern is a creational design pattern that provides an interface for creating objects without specifying their exact class. The factory method encapsulates object creation, making it easier to manage and modify. This pattern allows for decoupling the code that uses the objects from the code that creates them.
Problems - A document system without Factory
Scenario: A common real-world example of the Factory Design Pattern is the creation of different types of documents in a document processing application. Consider a scenario where you have a document editor application that can create different types of documents, such as Resume, Report, and Letter.
If a factory pattern is not used in a document generation system, several problems can arise.
Problems
A common real-world example of the Factory Design Pattern is the creation of different types of documents in a document processing application. Consider a scenario where you have a document editor application that can create different types of documents, such as Resume, Report, and Letter.
A diagram can help clarify the structure and interactions in the Factory Design Pattern. Here’s a visual representation of the Factory Pattern for creating different types of documents.
Client Code - Requests a document creation by using the factory interface (IDocumentFactory).
Factory Interface -The client interacts with the factory interface, requesting a document.
Concrete Factory - The specific factory (e.g., PdfDocumentFactory) creates and returns an instance of the corresponding document type (e.g., PdfDocument).
Document Creation - The client interacts with the IDocument interface to use the document, without needing to know the details of the document's creation.
Example
Here’s the entire code example using the Factory Pattern in C#.
// Product interface
public interface IDocument
{
void Create();
}
// Concrete Products
public class Resume : IDocument
{
public void Create()
{
Console.WriteLine("Creating a Resume");
}
}
public class Report : IDocument
{
public void Create()
{
Console.WriteLine("Creating a Report");
}
}
public class Letter : IDocument
{
public void Create()
{
Console.WriteLine("Creating a Letter");
}
}
// Factory interface
public interface IDocumentFactory
{
IDocument CreateDocument();
}
// Concrete Factories
public class ResumeFactory : IDocumentFactory
{
public IDocument CreateDocument()
{
return new Resume();
}
}
public class ReportFactory : IDocumentFactory
{
public IDocument CreateDocument()
{
return new Report();
}
}
public class LetterFactory : IDocumentFactory
{
public IDocument CreateDocument()
{
return new Letter();
}
}
class Program
{
static void Main()
{
// Client code using the Factory pattern
IDocumentFactory resumeFactory = new ResumeFactory();
IDocument resume = resumeFactory.CreateDocument();
resume.Create(); // Output: Creating a Resume
IDocumentFactory reportFactory = new ReportFactory();
IDocument report = reportFactory.CreateDocument();
report.Create(); // Output: Creating a Report
IDocumentFactory letterFactory = new LetterFactory();
IDocument letter = letterFactory.CreateDocument();
letter.Create(); // Output: Creating a Letter
}
}
Output
Resume
, Report
,
Letter
). It only depends on the IDocumentFactory
and
IDocument
interfaces.
Invoice
) needs to be added, you can simply create a new
InvoiceFactory
and Invoice
class without modifying any
existing code.A transport booking system allows users to book various modes of transportation, such as Car, Bus, or Bicycle. Each type of transport has different characteristics and booking procedures, but the system should be able to handle them all through a unified interface. Using the Factory Pattern, the transport system can dynamically create and manage different vehicle objects.
Example
// Transport interface
public interface ITransport
{
void Book();
}
// Concrete Transport Classes
public class Car : ITransport
{
public void Book()
{
Console.WriteLine("Car has been booked.");
}
}
public class Bus : ITransport
{
public void Book()
{
Console.WriteLine("Bus has been booked.");
}
}
public class Bicycle : ITransport
{
public void Book()
{
Console.WriteLine("Bicycle has been booked.");
}
}
// Factory interface
public interface ITransportFactory
{
ITransport CreateTransport();
}
// Concrete Factories
public class CarFactory : ITransportFactory
{
public ITransport CreateTransport()
{
return new Car();
}
}
public class BusFactory : ITransportFactory
{
public ITransport CreateTransport()
{
return new Bus();
}
}
public class BicycleFactory : ITransportFactory
{
public ITransport CreateTransport()
{
return new Bicycle();
}
}
// Client code
class Program
{
static void Main(string[] args)
{
// Simulating user input for transport selection
string transportType = "Bus"; // Can be "Car", "Bus", or "Bicycle"
ITransportFactory factory = GetTransportFactory(transportType);
if (factory != null)
{
ITransport transport = factory.CreateTransport();
transport.Book(); // Booking the transport
}
else
{
Console.WriteLine("Invalid transport type.");
}
}
// Factory selection logic
public static ITransportFactory GetTransportFactory(string transportType)
{
switch (transportType)
{
case "Car":
return new CarFactory();
case "Bus":
return new BusFactory();
case "Bicycle":
return new BicycleFactory();
default:
return null;
}
}
}
Output