Jul 9, 2013

Abstract Factory Pattern

1 comment
Provide an interface for creating families of related or dependent objects without specifying their concrete classes

Provides a way to encapsulate a group of individual factories those have common theme.
Abstract Factory emphasizes a family of product objects (either simple or complex).
Client does not know/care which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. It separates details of implementation of a set of objects from their general usage.

Example, consider a program that assists with the packaging and delivery of items for a web-based store. The company delivers two types of product. The first is a standard product that is placed in a box and delivered through the post with a simple label. The second is a delicate item that requires shockproof packaging and is delivered via a courier that requires a detailed manifest.

In this case, there are two types of object required, a packaging object and a delivery documentation object. We could use two factories to generate these related objects. The StandardPurchaseFactory will produce StandardPackaging and PostalLabel objects while the DelicatePurchaseFactory creates ShockProofPackaging and CourierManifest objects.

public abstract class Packaging { }
 
public class StandardPackaging : Packaging { }
 
public class ShockProofPackaging : Packaging { }
 
public abstract class DeliveryDocument { }
 
public class PostalLabel : DeliveryDocument { }
 
public class CourierManifest : DeliveryDocument { }

public abstract class PurchaseFactory
{
    public abstract Packaging CreatePackaging();
 
    public abstract DeliveryDocument CreateDeliveryDocument();
} 
 
public class StandardPurchaseFactory : PurchaseFactory
{
    public override Packaging CreatePackaging()
    {
        return new StandardPackaging();
    }
 
    public override DeliveryDocument CreateDeliveryDocument()
    {
        return new PostalLabel();
    }
} 
 
public class DelicatePurchaseFactory : PurchaseFactory
{
    public override Packaging CreatePackaging()
    {
        return new ShockProofPackaging();
    }
 
    public override DeliveryDocument CreateDeliveryDocument()
    {
        return new CourierManifest();
    }
}

public class Client
{
    private Packaging _packaging;
    private DeliveryDocument _deliveryDocument;
 
    public Client(PurchaseFactory factory)
    {
        _packaging = factory.CreatePackaging();
        _deliveryDocument = factory.CreateDeliveryDocument();
    }
 
    public Packaging ClientPackaging
    {
        get { return _packaging; }
    }
 
    public DeliveryDocument ClientDocument
    {
        get { return _deliveryDocument; }
    }
}

How to use the above abstract factory?
private void btnAbstractFactory_Click(object sender, EventArgs e)
{
   PurchaseFactory standardFact = new StandardPurchaseFactory();
   Client standard = new Client(standardFact);
   rtxtOutput.AppendText(standard.ClientPackaging.GetType());
   rtxtOutput.AppendText(Environment.NewLine);
   rtxtOutput.AppendText(standard.ClientDocument.GetType());
   rtxtOutput.AppendText(Environment.NewLine);
 
   PurchaseFactory delicateFact = new DelicatePurchaseFactory();
   Client delicate = new Client(delicateFact );
   rtxtOutput.AppendText(delicate.ClientPackaging.GetType());
   rtxtOutput.AppendText(Environment.NewLine);
   rtxtOutput.AppendText(delicate.ClientDocument.GetType());
}

Output
AbstractFactoryPattern.StandardPackaging
AbstractFactoryPattern.PostalLabel
AbstractFactoryPattern.ShockProofPackaging
AbstractFactoryPattern.CourierManifest

Abstract Factory Pattern in .NetBCL - DbProviderFactory

private void btnAbstractFactory_Click(object sender, EventArgs e)
{
    rtxtOutput.Clear(); 

    //Example - AbstractFactory in .Net BCL : DbProviderFactory
    DataTable dtDbProviderFactories = DbProviderFactories.GetFactoryClasses();
    dgvwOutput.DataSource = dtDbProviderFactories;

    // Creating factory of type "System.Data.SqlClient"
    CreateDbProvider("System.Data.SqlClient");
    CreateDbProvider("System.Data.OracleClient");
}

private void CreateDbProvider(string providerType)
{
  rtxtOutput.AppendText("Creating factory of type " + providerType +Environment.NewLine);
  rtxtOutput.AppendText(" - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" + Environment.NewLine);

  DbProviderFactory factory = DbProviderFactories.GetFactory(providerType);
  rtxtOutput.AppendText(factory.GetType().ToString());
  rtxtOutput.AppendText(Environment.NewLine);

  DbCommand cmd = factory.CreateCommand();
  rtxtOutput.AppendText(cmd.GetType().ToString());
  rtxtOutput.AppendText(Environment.NewLine);

  DbConnection conn = factory.CreateConnection();
  rtxtOutput.AppendText(conn.GetType().ToString());
  rtxtOutput.AppendText(Environment.NewLine);

  DbConnectionStringBuilder connStrBuilder = factory.CreateConnectionStringBuilder();
  rtxtOutput.AppendText(connStrBuilder.GetType().ToString()  + Environment.NewLine);
  rtxtOutput.AppendText(Environment.NewLine);
}

1 comment :