Provides a way to encapsulate a group of individual factories those have common theme (related) without specifying their concrete classes.
Requirement: If you have created many factories or looking to create, client code become complex and scattered to call many factories. In that case abstract factory provides a centralized & simple way to call different individual factories using abstract factory.
Client only knows about Abstract factory & calls only Abstract factory for all individual factories.
Use: Client is able to call different related concrete factories from a single point of contact.
Client doesn't know about concrete classes & concrete factories. Client is aware only with abstract factory & abstract products (Interfaces).
Sample Code:
public class ConnectionFactory : AbstractFactory
- Its an important creational pattern
- Abstract factory is an extension on factory pattern
Requirement: If you have created many factories or looking to create, client code become complex and scattered to call many factories. In that case abstract factory provides a centralized & simple way to call different individual factories using abstract factory.
Client only knows about Abstract factory & calls only Abstract factory for all individual factories.
Use: Client is able to call different related concrete factories from a single point of contact.
Client doesn't know about concrete classes & concrete factories. Client is aware only with abstract factory & abstract products (Interfaces).
Problems Solved: New concrete factories with related theme can be added without updating client.
Sample Code:
public abstract
class AbstractFactory
{
///
<summary>
///
Get Connection Factory
///
</summary>
///
<param name="connectionType">
///
1- Sql Connection
///
2- Oledb Connection
///
</param>
///
<returns></returns>
public abstract Connection GetConnectionObject(int connectionType)
{
return (new ConnectionFactory()).GetConnectionObject(connectionType);
}
///
<summary>
///
Get Command Factory
///
</summary>
///
<param name="commandType">
///
1- Sql Command
///
2- Oledb Command
///
</param>
///
<returns></returns>
public abstract Command GetCommandObject(int commandType)
{
{
return (new CommandFactory()).GetCommandObject(commandType);
}
}public class ConnectionFactory : AbstractFactory
{
public Override Connection
GetConnectionObject(int connectionType)
{
Connection
objConnection = null;
if (connectionType ==
1)
objConnection = new
SqlConnection();
else if (connectionType == 2)
objConnection = new
OledbConnection();
return objConnection;
}
public Override Command GetCommandObject(int CommandType)
public Override Command GetCommandObject(int CommandType)
{
return null;
}
return null;
}
}
public class
CommandFactory : AbstractFactory
{
public Override Command
GetCommandObject(int CommandType)
{
Command objCommand =null;
if (CommandType == 1)
objCommand = new SqlCommand();
else if (CommandType == 2)
objCommand = new OledbCommand();
return objCommand;
}
public Override Connection GetConnectionObject(int connectionType)
{
return null;
}
return null;
}
}
public interface
Connection
{
string GetName();
}
public interface
Command
{
string GetName();
}
public class
SqlConnection : Connection
{
public SqlConnection()
{
}
public string GetName()
{
return "Sql Connection";
}
}
public class
OledbConnection : Connection
{
public OledbConnection()
{
}
public string GetName()
{
return "Oledb Connection";
}
}
public class
SqlCommand : Command
{
public SqlCommand()
{
}
public string GetName()
{
return "Sql Command";
}
}
public class
OledbCommand : Command
{
public OledbCommand()
{
}
public string GetName()
{
return "Oledb Command";
}
}
Client Code
Console.WriteLine("Enter 1 for Sql connetion, 2 for oledb
connection");
int connectionType = Convert.ToInt32(Console.ReadLine().ToString());//Enter 1 or 2
Connection objConn =
AbstractFactory.GetConnectionObject(connectionType);
Console.WriteLine("Returned concrete connection object is of type
" + objConn.GetName());
Console.WriteLine("Enter value for getting command concrete
object");
Console.WriteLine("Enter 1 for Sql command, 2 for oledb command");
int commandType = Convert.ToInt32(Console.ReadLine().ToString());
//Enter 1 or 2
Command objCommand =
AbstractFactory.GetCommandObject(commandType);
Console.WriteLine("Returned concrete command object is of type "
+ objCommand.GetName());
Console.WriteLine("Restart for rewind...");
Console.ReadLine();
----------------------------------------------------
Example 2
Example 2
using System;
namespace RefactoringGuru.DesignPatterns.AbstractFactory.Conceptual
{
public interface IAbstractFactory
{
IAbstractProductA CreateProductA();
IAbstractProductB CreateProductB();
}
class ConcreteFactory1 : IAbstractFactory
{
public IAbstractProductA CreateProductA()
{
return new ConcreteProductA1();
}
public IAbstractProductB CreateProductB()
{
return new ConcreteProductB1();
}
}
// Each Concrete Factory has a corresponding product variant.
class ConcreteFactory2 : IAbstractFactory
{
public IAbstractProductA CreateProductA()
{
return new ConcreteProductA2();
}
public IAbstractProductB CreateProductB()
{
return new ConcreteProductB2();
}
}
public interface IAbstractProductA
{
string UsefulFunctionA();
}
// Concrete Products are created by corresponding Concrete Factories.
class ConcreteProductA1 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "The result of the product A1.";
}
}
class ConcreteProductA2 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "The result of the product A2.";
}
}
public interface IAbstractProductB
{
string UsefulFunctionB();
string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}
// Concrete Products are created by corresponding Concrete Factories.
class ConcreteProductB1 : IAbstractProductB
{
public string UsefulFunctionB()
{
return "The result of the product B1.";
}
public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();
return $"The result of the B1 collaborating with the ({result})";
}
}
class ConcreteProductB2 : IAbstractProductB
{
public string UsefulFunctionB()
{
return "The result of the product B2.";
}
public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();
return $"The result of the B2 collaborating with the ({result})";
}
}
class Client
{
public void Main()
{
// The client code can work with any concrete factory class.
Console.WriteLine("Client: Testing client code with the first factory type...");
ClientMethod(new ConcreteFactory1());
Console.WriteLine();
Console.WriteLine("Client: Testing the same client code with the second factory type...");
ClientMethod(new ConcreteFactory2());
}
public void ClientMethod(IAbstractFactory factory)
{
var productA = factory.CreateProductA();
var productB = factory.CreateProductB();
Console.WriteLine(productB.UsefulFunctionB());
Console.WriteLine(productB.AnotherUsefulFunctionB(productA));
}
}
class Program
{
static void Main(string[] args)
{
new Client().Main();
}
}
}
No comments:
Post a Comment