0% found this document useful (0 votes)
2 views13 pages

5 AbstractFactoryPattern

Chapter 5 discusses the Abstract Factory pattern, which provides an interface for creating families of related objects without specifying their concrete classes. It emphasizes the importance of understanding the Simple Factory and Factory Method patterns before delving into the Abstract Factory pattern, illustrating its application through examples involving wild and pet animals. The chapter concludes by highlighting the advantages of decoupling client code and promoting loose coupling while also addressing potential complexities and debugging challenges.

Uploaded by

davidispl01
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views13 pages

5 AbstractFactoryPattern

Chapter 5 discusses the Abstract Factory pattern, which provides an interface for creating families of related objects without specifying their concrete classes. It emphasizes the importance of understanding the Simple Factory and Factory Method patterns before delving into the Abstract Factory pattern, illustrating its application through examples involving wild and pet animals. The chapter concludes by highlighting the advantages of decoupling client code and promoting loose coupling while also addressing potential complexities and debugging challenges.

Uploaded by

davidispl01
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

CHAPTER 5

Abstract Factory Pattern


This chapter covers the Abstract Factory pattern.

GoF Definition
Provide an interface for creating families of related or dependent objects without
specifying their concrete classes.

Note To understand this pattern, I suggest you refer to Chapter 24 and learn about
the Simple Factory pattern first. Then you can turn to Chapter 4 to learn about the
Factory Method pattern. The Simple Factory pattern does not fall directly into the
Gang of Four design patterns, so the discussion of that pattern appears in Part II of
the book. The Abstract Factory pattern will make more sense to you if you have an
understanding of both the Simple Factory pattern and the Factory Method pattern.

Concept
An abstract factory is called a factory of factories. In this pattern, you provide a way to
encapsulate a group of individual factories that have a common theme. In this process,
you do not mention or specify their concrete classes.
This pattern helps you to interchange specific implementations without changing
the code that uses them, even at runtime. However, it may result in unnecessary
complexity and extra work. Even debugging becomes tough in some cases.

55
© Vaskaran Sarcar 2018
V. Sarcar, Design Patterns in C#, [Link]
Chapter 5 Abstract Factory Pattern

Real-Life Example
Suppose you are decorating your room with two different types of tables; one is made of
wood and one of steel. For the wooden type, you need to visit to a carpenter, and for the
other type, you may need to go to a metal shop. All of these are table factories. So, based
on demand, you decide what kind of factory you need.

Computer World Example


[Link] has already implemented similar concepts to establish a connection to a
database.
To understand this pattern, you may want to extend your understanding of the
Factory Method pattern. In the Factory Method pattern, you have two factories; one
is for creating dogs and another is for creating tigers. But now suppose, you want to
categorize dogs and tigers further; you choose to get a pet animal (dog or tiger) or a wild
animal (dog or tiger) through the factories. To fulfill that demand, you introduce two
concrete factories: WildAnimalFactory and PetAnimalFactory. WildAnimalFactory is
responsible for creating wild animals, and PetAnimalFactory is responsible for creating
pet animals.

Illustration
Wikipedia describes a typical structure of this pattern, which is similar to Figure 5-1
([Link]

56
Chapter 5 Abstract Factory Pattern

Figure 5-1. Abstract Factory pattern

I will follow a similar structure in the implementation in this chapter. [Link]


is the client looking for some animals (which are dogs and tigers in this case). You are
exploring the construction process of both pets and wild animals in this implementation.
In this example, you have two concrete factories: WildAnimalFactory and
PetAnimalFactory. You can guess that they are responsible for creating the concrete
products of dogs and tigers. WildAnimalFactory will create wild animals (wild dogs and
wild tigers), and PetAnimalFactory will create pet animals (pet dogs and pet tigers). For
your reference, the participants and their roles are summarized here:

• IAnimalFactory: Abstract factory.

• WildAnimalFactory: Concrete factory. This will create wild dogs and


wild tigers.

• PetAnimalFactory: Another concrete factory. This will create pet


dogs and pet tigers.

• ITiger and IDog: Abstract products in this case.

• PetTiger, PetDog, WildTiger, and WildDog: These are the concrete


products in this example.
57
Chapter 5 Abstract Factory Pattern

Class Diagram
Figure 5-2 shows the class diagram.

Figure 5-2. Class diagram

Solution Explorer View


Figure 5-3 shows the high-level structure of the parts of the program.

58
Chapter 5 Abstract Factory Pattern

Figure 5-3. Solution Explorer View


59
Chapter 5 Abstract Factory Pattern

Implementation
Here’s the implementation:

using System;

namespace AbstractFactoryPattern
{
    public interface IDog
    {
        void Speak();        
        void Action();
    }

    public interface ITiger


    {
        void Speak();        
        void Action();
    }

    #region Wild Animal collections


    class WildDog : IDog
    {
        public void Speak()
        {
            [Link]("Wild Dog says: Bow-Wow.");
        }        
        public void Action()
        {
            [Link]("Wild Dogs prefer to roam freely in
jungles.\n");
        }
    }
    class WildTiger : ITiger
    {
        public void Speak()
        {
            [Link]("Wild Tiger says: Halum.");

60
Chapter 5 Abstract Factory Pattern

        }
        public void Action()
        {
            [Link]("Wild Tigers prefer hunting in jungles.\n");
        }
    }
    #endregion

    #region Pet Animal collections


    class PetDog : IDog
    {
        public void Speak()
        {
            [Link]("Pet Dog says: Bow-Wow.");
        }
        public void Action()
        {
            [Link]("Pet Dogs prefer to stay at home.\n");
        }        
    }
    class PetTiger : ITiger
    {
        public void Speak()
        {
            [Link]("Pet Tiger says: Halum.");
        }
        public void Action()
        {
            [Link]("Pet Tigers play in an animal circus.\n");
        }        
    }
    #endregion
    //Abstract Factory
    public interface IAnimalFactory
    {
        IDog GetDog();

61
Chapter 5 Abstract Factory Pattern

        ITiger GetTiger();
    }
    //Concrete Factory-Wild Animal Factory
    public class WildAnimalFactory : IAnimalFactory
    {
        public IDog GetDog()
        {
            return new WildDog();
        }

        public ITiger GetTiger()


        {
            return new WildTiger();
        }
    }
    //Concrete Factory-Pet Animal Factory
    public class PetAnimalFactory : IAnimalFactory
    {
        public IDog GetDog()
        {
            return new PetDog();
        }

        public ITiger GetTiger()


        {
            return new PetTiger();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            [Link]("***Abstract Factory Pattern Demo***\n");

            //Making a wild dog through WildAnimalFactory


            IAnimalFactory wildAnimalFactory = new WildAnimalFactory();
            IDog wildDog = [Link]();            
62
Chapter 5 Abstract Factory Pattern

            [Link]();
            [Link]();
            //Making a wild tiger through WildAnimalFactory
            ITiger wildTiger = [Link]();            
            [Link]();
            [Link]();

            [Link]("******************");

            //Making a pet dog through PetAnimalFactory


            IAnimalFactory petAnimalFactory = new PetAnimalFactory();
            IDog petDog = [Link]();            
            [Link]();
            [Link]();
            //Making a pet tiger through PetAnimalFactory
            ITiger petTiger = [Link]();            
            [Link]();
            [Link]();

            [Link]();
        }
    }
}

Output
Here’s the output:

***Abstract Factory Pattern Demo***

Wild Dog says: Bow-Wow.


Wild Dogs prefer to roam freely in jungles.

Wild Tiger says: Halum.


Wild Tigers prefer hunting in jungles.

******************
Pet Dog says: Bow-Wow.
Pet Dogs prefer to stay at home.

Pet Tiger says: Halum.


Pet Tigers play in an animal circus.
63
Chapter 5 Abstract Factory Pattern

Q&A Session
1. I am seeing that both the IDog and ITiger interfaces are
containing methods that have the same names. For example,
both interfaces contain the methods Speak() and Action().
Is that mandatory?

Answer:

No. You can use different names for your methods. Also, the
number of methods can be different in these interfaces. However,
in Chapter 24, I covered the Simple Factory pattern, and in
Chapter 4, I covered the Factory Method pattern. In this chapter,
I am continuing the examples from those chapters, which is why
I have kept the methods Speak() and Action() in this example.

2. What are the challenges of using an abstract factory like this?

Answer:

Any change in the abstract factory will force you to propagate


the modification to the concrete factories. If you follow the
design philosophy that says “Program to an interface, not to an
implementation,” you need to prepare for this. This is one of the
key principles that developers should always keep in mind. In
most scenarios, developers do not want to change their abstract
factories.

In addition, the overall architecture may look complex. Also,


debugging becomes tricky in some scenarios.

64
Chapter 5 Abstract Factory Pattern

3. How can you distinguish a Simple Factory pattern from a


Factory Method pattern or an Abstract Factory pattern?

Answer:

I discussed the differences of a Simple Factory pattern and a


Factory Method pattern in the “Q&A Session” section of Chapter 4.

Let’s revise all three factories as shown in the following diagrams.

Here’s the Simple Factory pattern:

IAnimal preferredType=null;
ISimpleFactory simpleFactory = new SimpleFactory();            
#region The code region that will vary based on users preference            
preferredType = [Link]();

Figure 5-4 shows the Simple Factory pattern.

Figure 5-4. Simple Factory pattern

Here’s the Factory Method pattern:

// Creating a Tiger Factory


IAnimalFactory tigerFactory =new TigerFactory();
// Creating a tiger using the Factory Method
IAnimal aTiger = [Link]();

.......
// Creating a DogFactory
IAnimalFactory dogFactory = new DogFactory();
// Creating a dog using the Factory Method
IAnimal aDog = [Link]();
65
Chapter 5 Abstract Factory Pattern

Figure 5-5 shows the Factory Method pattern.

Figure 5-5. Factory Method pattern

Here’s the Abstract Factory pattern:

//Making a wild dog through WildAnimalFactory


IAnimalFactory wildAnimalFactory = new WildAnimalFactory();
IDog wildDog = [Link]();            
.....
//Making a wild tiger through WildAnimalFactory
ITiger wildTiger = [Link]();            
.....
//Making a pet dog through PetAnimalFactory
IAnimalFactory petAnimalFactory = new PetAnimalFactory();
IDog petDog = [Link]();            
.....
//Making a pet tiger through PetAnimalFactory
ITiger petTiger = [Link]();

Figure 5-6 shows the Abstract Factory pattern.

66
Chapter 5 Abstract Factory Pattern

Figure 5-6. Abstract Factory pattern

Conclusion
In short, with the Simple Factory pattern, you can separate the code that will vary from
the rest of the code (basically, you decouple the client code). This approach helps you to
manage the code more easily. Another key advantage of this approach is that the client is
unaware of how the objects are created. So, it promotes both security and abstraction.
However, this approach can violate the open-close principle. You can overcome this
drawback using the Factory Method pattern, which allows subclasses to decide how the
instantiation process will be completed. Put simply, you delegate the object creation to
the subclasses that implement the factory method to create objects.
The abstract factory is basically factory of factories. It creates the family of related
objects, but it does not depend on the concrete classes.
Lastly, I tried to keep the examples simple. A factory method promotes inheritance,
and its subclasses need to implement the factory method to create objects. But in some
implementations, you may clearly notice that the Abstract Factory pattern can promote
object composition by creating the related objects using the methods that are exposed in
a factory interface.
These factories promote loose coupling by reducing the dependencies on concrete
classes.

67

You might also like