Design patterns: Factory Method vs Abstract Factory

In case a class instance shall be created, developers may give the advice to use a “factory”. This common term isn’t wrong but sometimes it’s better to define the exact type of factory you want to use. So, in this case, if you ask “Shall I use a Factory Method or an Abstract Factory” it can happen that you don’t get an answer because the differences or the patterns itself are not understand properly.

In previous articles I explained the Factory Method pattern and the Abstract Factory pattern. Please read these articles if you want to get information about the design patterns. Within this article I compare the two patterns and show their differences.

The following table shows a short summary of the most important differences between the Factory Method design pattern and the Abstract Factory design pattern.
 

Factory Method Abstract Factory
Implemented as single method Implemented as object
Factory is implemented within the object which shall be created Factory is implemented in another object independent of the objects to create
Create a  single object Creates a family if dependent objects
Can be overridden in a subclass Different abstract factories can be created
Is used to hide the details about how the class instance is created Is used to hide the details about which concreate classes are created

The following example shows an implementation of both factory patterns. At first two type of classes are implemented: queries and commands. These classes will implement the Factory Method design pattern. Within the different query and command classes the factory method of the base class is used or an own one is implemented. Additional the Abstract Factory pattern is used to create families of objects. There are two factories creating the classes for a file based data store or a database based data store.

interface IQuery
{
    string GetData();
}

interface IQueryFactory
{
    void CreateQuery();
}

//-------------------------------------------------

class Query : IQuery, IQueryFactory
{
    public Query()
    {
        CreateQuery();
    }

    public virtual void CreateQuery()
    {
        //implement object initialization logic here
    }

    public string GetData()
    {
        return "abc";
    }
}

class FileQuery : Query
{
    public override void CreateQuery()
    {
        //implement object initialization logic here
    }
}

class DatabaseQuery : Query
{
}

class OracleDatabaseQuery : DatabaseQuery
{
    public override void CreateQuery()
    {
        //implement object initialization logic here
    }
}        

//-------------------------------------------------

interface ICommand
{
    void UpdateData(string data);
}
        
interface ICommandFactory
{
    ICommand CreateCommand();
}

//-------------------------------------------------    
    
class Command : ICommand, ICommandFactory
{
    public virtual ICommand CreateCommand()
    {
        return new Command();
    }

    public void UpdateData(string data)
    {
        // ...
    }
}

class DatabaseCommand : Command
{

}

class FileCommand : Command
{
    public override ICommand CreateCommand()
    {
        return new FileCommand();
    }
}

//-------------------------------------------------

interface IEnvironmentFactory
{
    IQuery GetQuery();
    ICommand GetCommand();
}

class DatabaseBasedEnvironment : IEnvironmentFactory
{
    public ICommand GetCommand()
    {
        return new DatabaseCommand();
    }

    public IQuery GetQuery()
    {
        return new DatabaseQuery();
    }
}

class FileBasedEnvironment : IEnvironmentFactory
{
    public ICommand GetCommand()
    {
        return new FileCommand();
    }

    public IQuery GetQuery()
    {
        return new FileQuery();
    }
}
Advertisements
Dieser Beitrag wurde unter .NET, C#, Clean Code, Design Pattern veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s