Monday, March 22, 2010

C# implementation of Abstract Factory pattern

The Abstract Factory pattern takes Factory Method Pattern step further, creating families of related products.
The abstract factory can be refined to concrete factories,
each of which can create different products of different types.

The pattern isolates the product definitions and their class names from the
client so that the only way to get one of them is through a factory. For this reason,
product families can easily be interchanged or updated without upsetting the structure
of the client.
An interesting aspect of the Abstract Factory pattern is that the whole product family
can be changed while the application is running.




//library code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AbstractFactoryPattern
{

//abstract products

//Product1
public interface IConnection
{
void Open();
void Close();
}

//Product2
public interface ICommand
{
IConnection Connection { get; set; }
string Text { get; set; }
void Execute();
}

//concrete products

//Family 1
class SqlConnection : IConnection
{
public SqlConnection() { Console.WriteLine("SQL Connection established..."); }
public void Open() { Console.WriteLine("Connection opened."); }
public void Close() { Console.WriteLine("Connection closed."); }
}

class SqlCommand : ICommand
{
public IConnection Connection { get;set; }
public string Text { get;set; }
public void Execute() { Console.WriteLine("Sql command executed..."); }
}

//Family 2
class OraConnection : IConnection
{
public OraConnection() { Console.WriteLine("Oracle Connection established..."); }
public void Open() { Console.WriteLine("Connection opened."); }
public void Close() { Console.WriteLine("Connection closed."); }
}

class OraCommand : ICommand
{
public IConnection Connection { get;set; }
public string Text { get;set; }
public void Execute() { Console.WriteLine("Ora command executed..."); }
}

//Factories
public interface IFactory
{
IConnection CreateConnection();
ICommand CreateCommand();
}

//SqlFactory
class Factory1 : IFactory
{
public Factory1() { }
public IConnection CreateConnection()
{
return new SqlConnection();
}
public ICommand CreateCommand()
{
return new SqlCommand();
}
}

// OraFactory
class Factory2 : IFactory
{
public Factory2() { }
public IConnection CreateConnection()
{
return new OraConnection();
}
public ICommand CreateCommand()
{
return new OraCommand();
}
}

// using Factory Method
public class Factories
{
public static IFactory getFactory(string type)
{
if (type == "SQL")
return new Factory1();
else
if (type == "ORA")
return new Factory2();
else
{
Exception ex=new Exception("Unknown Factory Type");
throw new ApplicationException("Unknown Type!", ex);
}
}
}
}

3 comments:

Unknown said...

//client code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AbstractFactoryPattern;

namespace AbstractFactoryClient
{
class Program
{
static void Main(string[] args)
{
IFactory f = Factories.getFactory("ORA");
IConnection conn = f.CreateConnection();
conn.Open();

ICommand cmd = f.CreateCommand();
cmd.Connection = conn;
cmd.Text = "";
cmd.Execute();

conn.Close();

Console.WriteLine("--- changing product family:---");

f = Factories.getFactory("SQL");
conn = f.CreateConnection();
conn.Open();

cmd = f.CreateCommand();
cmd.Connection = conn;
cmd.Execute();

conn.Close();

Console.ReadLine();

}
}
}

Unknown said...

---client output---
Oracle Connection established...
Connection opened.
Ora command executed...
Connection closed.
--- changing product family:---
SQL Connection established...
Connection opened.
Sql command executed...
Connection closed.

Kumait Muhammad said...

Nice work my friend, simple and direct...