Factory Method versus Abstract Factory

Home Forums Programming Software engineering Patterns design Factory Method versus Abstract Factory

This topic contains 0 replies, has 1 voice, and was last updated by  Васильев Владимир Сергеевич 3 months, 1 week ago.

  • Author
    Posts
  • #4101

    A recent comment to one of my articles about Abstract Factory design pattern, prompted me to write this post because there was a question I consider to be quite matter of fact and deserving a separate discussion. Once again I thank the author of this question.

    So, it is useless to deny that today there are so many design patterns that their study can be put in a separate direction in software development. It is quite impossible to know everything, and many of them are in a way similar to each other. They differ just in details. And even the name of a pattern might confuse completely.

    Let’s start…

    The main motive of both templates – Factory Method and Abstract Factory – is creating new objects (no wonder cause they both belong to creational group of design patterns in GOF classification ).

    Another idea which sounds in both patterns is decoupling – separating the logic of creating objects from the class that is initiating their creation.

    I think the best option would be to see the implementation of both Factory Method and Abstract Factory , and to compare them, but, of course, situations where we use them will be different.

    All attention to Factory Method

    This design pattern’s essence is to define a standard method of creating objects that is not associated with the constructor directly, leaving the decision as to which object to instantiate to subclasses.

    FactoryMethodIt’s very simple. We have a base interface (IToy) for all products, which can be expected to be created ever. Accordingly, you can create any number of classes based on this product, in our case we have 2 of them – Doll class and TeddyBear class.

    There is also a base class for all creators of specific products – ToyCreator. It encapsulates a method (CareateToy()) that creates a particular toy that corresponds to a common interface for all toys.

    There are two creator classes – the class responsible for the creation of dolls (DollCreator), and the class that creates teddy bears (TeddyBearCreator).

    Each factory creates a particular type of product.

    In the client, we create a collection of toys, 2 instances of the particular factories, and then by calling the CreateToy() we fill the collection (as you can see we cant avoid using polymorphism;)). Then the loop runs through the collection of toys, looking at their names.

    interface IToy 
    {  
       string Name { get; set; }
     }
     class Doll:IToy 
    {    
       public string Name { get; set; } 
    }
     class TeddyBear: IToy 
    {     
        public string Name { get; set; }
     }
     abstract class ToyCreator
     {      
       public abstract IToy CreateToy(string name); 
    }
     class DollCreator:ToyCreator 
    {   
       public override IToy CreateToy(string name) 
       { 
            return new Doll() { Name = name };    
       } 
    }
     class TeddyBearCreator: ToyCreator
     {   
       public override IToy CreateToy(string name)    
       {      
          return new TeddyBear() { Name = name };  
        }
     }
     class Program 
    {     
        static void Main(string[] args) 
        { 
            List<IToy> toys = new List<IToy>();  
            DollCreator dCreator = new DollCreator();  
            TeddyBearCreator TBCreator = new TeddyBearCreator();  
            toys.Add(dCreator.CreateToy("Barbie")); 
            toys.Add(dCreator.CreateToy("Sindy"));   
            toys.Add(TBCreator.CreateToy("Teddy"));   
            foreach (var i in toys)  
            {           
               Console.WriteLine(i.Name);   
            }
         }
     }

    Now let’s think about what is the advantage of using this pattern.

    • Instantiation of products is distanced from the client who initiates their creation.
    • The whole algorithm of creating product objects is encapsulated in factory classes.
    • The number of product types can extended , and accordingly new types of Factory classes can be created .
    • Polymorphic use of factories objects and of products objects.

    Note that each factory class can produce just one type of product (and often just one at a time). The only common thing for all products produced by all factories is the common interface IToy. Each factory that produces product does not need a “range” of the goods, and respectively, includes only one method of creating a product.

    And now … Abstract Factory

    Abstract Factory pattern allows you to define a base type for creating groups of associated objects. I repeat it once again loudly and clearly, emphasizing the first word of the phrase – a GROUP of associated objects.

    Description: there is a base type for all the factories and a base type for the products. Factory class includes a set of methods, each creating a different type of product.

    In our example we are working with the factories that produce Barbie dolls . The set of products that can be produced by all implementations of AbstractFactory is a Barby doll and Ken (of course we could not forget about him). For them, we are defining interfaces – IBarby and IKen.

    The base factory class AbstractDollFactory is ready to produce both kinds of dolls, thus it includes 2 methods – CreateBarby () and CreateKen ().

    In the client class , we are creating both kinds of dolls through appropriate factory methods.

    interface IBarbie 
    {
           string Name { get; set; }
     } 
    class Barbie : IBarbie
     { 
          public string Name { get; set; }
     }
     interface IKen
     {       
       string Name { get; set; }
     }
     class Ken : IKen
     {
           public string Name { get; set; }
     }
     abstract class AbstractDollFactory
     {
          public abstract IBarbie CreateBarbie(string name);
          public abstract IKen CreateKen(string name); }
     class USADollsFactory:AbstractDollFactory
     { 
         public override IBarbie CreateBarbie(string name) 
         { 
            return new Barbie() { Name = name };
          }
          public override IKen CreateKen(string name) 
         { 
             return new Ken() { Name = name };
          }
     }
     class Program 
    {
          static void Main(string[] args) 
         {
            USADollsFactory factory = new USADollsFactory();
            Barbie barbie = factory.CreateBarbie("Barbie with lovely long blond hair") as Barbie;         Ken ken = factory.CreateKen("Ken just for Barbie and no other doll ;)") as Ken;               Console.WriteLine(barbie.Name); 
            Console.WriteLine(ken.Name);
          }
     }

    Now let’s see what we achieve by using this pattern:

    • Distancing the client from the product which is being created
    • The algorithm for creating products is encapsulated in the methods of factory
    • We can extend the creation of different types of factories, and it guarantees to create a range of products

    What is similar

    • Both Factory Method and Abstract Factory work on creating new objects, therefore in fact, they belong to the group of creational patterns (GOF).
    • Both paterrns’ factory methods encapsulate the algorithm for creating specific products.
    • There is a base type for factories
    • There are base types for products
    • Creation of a new instance of the product is only possible through the factory.

    What is the difference

    • Abstract Factory produces GROUPS of associated products, and Factory Method produces a single specific type of product.
    • Note that with all the advantages of these two patterns, they also have disadvantages.
    • For example, in the case of Factory Method, you must create one more factory class for each new type of product.
    • And in the case of Abstract Factory, inconvenience occurs when we need to expand the range of products produced by the factory.

    Of course, this is not the only design patterns belonging to creational group of patterns. We can also name Builder, Singleton, Prototype, but for them we will talk more in other posts in this blog.

    I hope I managed to make it clear what is the difference between the described design patterns. Waiting for further questions.

You must be logged in to reply to this topic.