Home » Blog » Simple Factory Design Pattern

Simple Factory Design Pattern

simple-factory-design-pattern

The Simple Factory pattern provides a way of creating objects without describing the exact class of objects that will be created.

It is also known as a Static Factory Method pattern.

Getting Started

The Simple Factory pattern defines a static method that is responsible for creating objects, and this method is typically called a “factory method”.

The factory method takes one or more parameters that are used to determine which type of object to create, and it returns an instance of the appropriate class.

What Problems does Simple Factory Pattern Solve

  • The Simple Factory pattern solves the problem of creating objects in a way that is decoupled from the client code using a factory method.
  • The factory method takes care of the responsibility of determining which class to instantiate and creating an instance of that class.
  • This allows for flexibility in the system, as new classes can be added and used by the factory method without affecting the client code.

Code & Explanation

class DocumentFactory
{
    public static IDocument CreateDocument(string documentType)
    {
        if (documentType == "PDF")
            return new PdfDocument();
        else if (documentType == "Word")
            return new WordDocument();
        else
            throw new ArgumentException("Invalid document type.");
    }
}

interface IDocument
{
    void Open();
    void Save();
}

class PdfDocument : IDocument
{
    public void Open()
    {
        Console.WriteLine("PDF Document Open");
    }

    public void Save()
    {
        Console.WriteLine("PDF Document Save");
    }
}

class WordDocument : IDocument
{
    public void Open()
    {
        Console.WriteLine("Word Document Open");
    }

    public void Save()
    {
        Console.WriteLine("Word Document Save");
    }
}

In this example, the DocumentFactory class defines a static method called CreateDocument that takes a string parameter indicating the type of document to create.

This method checks the value of the documentType parameter and returns an object of the appropriate class.

The IDocument interface defines the behavior that all document classes should implement, PdfDocument and WordDocument classes are concrete implementations of this interface.

Client Code

private static void Main(string[] args)
        {
            IDocument document = DocumentFactory.CreateDocument("PDF");
            document.Save();
            document.Open();

            Console.ReadLine();
        }

The client code can use the DocumentFactory class to create objects, but the type of objects that will be created is determined by the value of the documentType parameter that is passed to the factory method.

Output

PDF Document Save
PDF Document Open

This pattern is a prime example of run time polymorphism – we have a base IDocument and in the run time, we create objects of either PDFDocument or WordDocument class.

Refactoring

We can replace the if/else blocks in the DocumentFactory by using a Dictionary, let’s see it in action:

public static class DocumentFactory
    {
        private static Dictionary<string, IDocument> container = new Dictionary<string, IDocument>();

        static DocumentFactory()
        {
            container.Add("PDF", new PdfDocument());
            container.Add("Word", new WordDocument());
        }

        public static IDocument CreateDocument(string documentType)
        {
            return container[documentType].Clone();
        }
    }

We have created a Dictionary<string, IDocument> with a string key and IDocument value, and in the static constructor, we are adding the concrete types, along with the document type.

In the CreateDocument() method, we just return the dictionary value (IDocument instance) as per the key (documentType).

We have created a Clone() method to eliminate the return of the same IDocument instance in the case of different calls.

Clone() method

We have defined Clone() in the IDocument interface, and have implemented them in the concrete classes. Let’s have a look:

    public interface IDocument
    {
        void Save();

        void Open();

        IDocument Clone();
    }
    public class PdfDocument : IDocument
    {
        public void Open()
        {
            Console.WriteLine("PDF Document Open");
        }

        public void Save()
        {
            Console.WriteLine("PDF Document Save");
        }

        public IDocument Clone()
        {
            return (IDocument)MemberwiseClone();
        }
    }

Let’s run the app and see the output:

PDF Document Save
PDF Document Open

GitHub

The full solution is available at – https://github.com/anurag1302/design-patterns

Design Pattern Series

Separate articles on Design patterns are available:

Conclusion

In this article, we have learned about the Simple Factory pattern, and how it helps to decouple the object creation process from the client code.

Leave a Reply

Your email address will not be published. Required fields are marked *