Pattern Name:

Factory Method

Short Description: 

Create instances of derived classes

Usage:

Frequently used, fairly easy to implement and useful for centralizing object lifetime management and avoiding object creation code duplication

Complexity:

1 / 5

UML Class Diagram:

image

Explanation:

  • The abstract creator implements a factory method that returns an objects. It also contains a method for testing purposes that serves to validate the design.
  • Each concrete creator overrides the abstract factory method and returns a specific object concerning on the context.
  • In this example the factory method is used internally to set a property but it could also be used in an external context for creating objects when needed.
    public abstract class BookReader
    {
        public BookReader()
        {
            Book = BuyBook();
        }

        public Book Book { get; set; }

        public abstract Book BuyBook();

       
        public void DisplayOwnedBooks()
        {
            Console.WriteLine(Book.GetType().ToString());
        }
    }

    public class HorrorBookReader : BookReader
    {
        public override Book BuyBook()
        {
            return new Dracula();
        }
    }

    public class FantasyBookReader : BookReader
    {
        public override Book BuyBook()
        {
            return new LordOfTheRings();
        }
    }

    public class AdventureBookReader : BookReader
    {
        public override Book BuyBook()
        {
            return new TreasureIsland();
        }
    }
  • The abstract class defines the interface and class structure for all objects that get build by the specific concrete creators via their factory methods.
    public abstract class Book
    {
    }

    public class Dracula : Book
    {
    }

    public class LordOfTheRings : Book
    {
    }

    public class TreasureIsland : Book
    {
    }

    public class Encyclopedia : Book
    {
    }
  • There is also the possibility to create a C# specific solution that uses generics which also results in a valid factory method.
    public Book BuyBook<T>()
        where T : Book, new()
    {
        return new T();
    }
  • In the last step we add some code to test the software design and the Factory Method implementation in the language agnostic and in the C# specific versions.
    private static void FactoryMethod()
    {
        var bookReaderList = new List<BookReader>();

        bookReaderList.Add(new AdventureBookReader());
        bookReaderList.Add(new FantasyBookReader());
        bookReaderList.Add(new HorrorBookReader());

        foreach (var reader in bookReaderList)
        {
            Console.WriteLine(reader.GetType() .ToString());
            // language agnostic solution
            reader.DisplayOwnedBooks();

            Console.WriteLine();
        }

        // C# specific solution using generics
        var genericReader = new AdventureBookReader();
        Book book = genericReader.BuyBook<Encyclopedia>();
        Console.WriteLine(book.GetType().ToString());

        Console.ReadKey();
    }
  • When running the example you can see that everything is working as expected and that the correct classes are instantiated during runtime.

image

Last edited May 7, 2011 at 2:46 PM by JasonOliveira, version 4

Comments

zhusong Jan 1 at 10:40 AM 
love your idea about generics...

rajenshahu Apr 2, 2013 at 12:03 PM 
good example with detail ..... nice

vchandm23 Jul 25, 2012 at 1:54 PM 
Amazing example ...... For the first time am actually getting the concept ...... Simple and clear :) Great post ... Why you guys are reluctant in making videos on this content..... That will really reach people ...