Sunday, May 30, 2010

Abstract Factory Pattern

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



1. It relies on object composition, object creation is in methods exposed in the factory interface.

2. Example from .NET

a. DbProviderFactory is an abstract factory.
b. It is implemented by SqlClientFactory, OdbcFactory
c. SqlClientFactory returns SqlCommand, OdbcFactory returns OdbcCommand
 namespace System.Data.Common { 
public abstract class DbProviderFactory {
protected DbProviderFactory();
public virtual bool CanCreateDataSourceEnumerator { get; }
public virtual DbCommand CreateCommand();
public virtual DbCommandBuilder CreateCommandBuilder();
public virtual DbConnection CreateConnection();
public virtual DbConnectionStringBuilder CreateConnectionStringBuilder();
public virtual DbDataAdapter CreateDataAdapter();
public virtual DbDataSourceEnumerator CreateDataSourceEnumerator();
public virtual DbParameter CreateParameter();
public virtual CodeAccessPermission CreatePermission(PermissionState state);
}
}

Factory Method Pattern

All factory patterns encapsulate object creation. The Factory Method Pattern encapsulates object creation by letting subclasses decide what objects to create.

Definition
The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.

Simple

1. You have a base class with an abstract method.
2. The abstract method is a factory method which returns different products.
3. The child classes implements the factory method and returns different products.
4. The base classes uses the products without knowledge of how they were created.

Simple Factory

1. The simple Factory Method is not a design pattern but more of a programming idiom.

2.

a. The client of factory uses factory to create instances of concrete classes.
b. The create() method is often declared statically.



3. Example

 public interface IPizza 
{
decimal Price { get; }
}
public class HamAndMushroomPizza : IPizza
{
decimal IPizza.Price
{
get
{
return 8.5m;
}
}
}
public class DeluxePizza : IPizza
{
decimal IPizza.Price
{
get
{
return 10.5m;
}
}
}
public class HawaiianPizza : IPizza
{
decimal IPizza.Price
{
get
{
return 11.5m;
}
}
}
public class PizzaFactory
{
public enum PizzaType
{
HamMushroom,
Deluxe,
Hawaiian
}
public static IPizza CreatePizza(PizzaType pizzaType)
{
IPizza ret = null;
switch (pizzaType)
{
case PizzaType.HamMushroom:
ret = new HamAndMushroomPizza();
break;
case PizzaType.Deluxe:
ret = new DeluxePizza();
break;
case PizzaType.Hawaiian:
ret = new HawaiianPizza();
break;
default:
throw new ArgumentException("The pizza type " + pizzaType + " is not recognized.");
}
return ret;
}
}


Drawbacks

1. Number of implementation classes is hardwired into the factory method. Therefore, even though there is an interface for the implementation objects, it's impossible for the factory method to return an implementation class that it does not know about. This limits extensibility, especially in the case of a public API and application frameworks, where the ability to dynamically introduce new implementation classes is not only desired, but often expected to achieve a certain degree of flexibility.

2. Even if the ability to dynamically introduce new implementations existed, the client application would still need to know which class to ask for. This eliminates some of the flexibility that the factory class was supposed to provide.

Saturday, May 29, 2010

Dependency Injection

Dependency Injection (DI), which allows you to inject objects into a class, rather than relying on the class to create the object itself.

When a component creates a private instance of another class, it internalizes the initialization logic within the component. This initialization logic is rarely reusable outside of the creating component, and therefore must be duplicated for any other class that requires an instance of the created class.

1. Factory

The use of a factory class is one common way to implement DI

1. It is not reusable across other applications.
2. Frequently all of the available creation options are hardcoded into the factory implementation, making the factory itself non-extensible.
3. Also, most of the time the class calling the factories' creation methods must know which subclass of the factory to create.
4. All dependencies for an object that is created using a factory are known to the factory at compile time. At run time there is no way to insert or alter the manner in which objects are created, or which dependencies are populated.
5. Since factories are custom to each individual implementation, there can be a significant level of cross-cutting infrastructure that is held captive inside a particular factory.
6. Factories rely on well-defined interfaces to achieve polymorphism. In order for a factory implementation to be able to dynamically create different concrete subclass instances, there must be a common base class or shared interface implemented by all classes that the factory will create. Interfaces decouple the construction of the object from the specific implementation of the interface. The dilemma that arises now is how you can accomplish this decoupling without being forced to create an interface for everything.

2. Containers

DI containers provide generic factory classes that instantiate instances of classes. These instances are then configured by the container, allowing construction logic to be reused on a broader level.

They provide

1. Not only factories for creating objects.
2. Also, dependency resolution.

For more details, please refer to MSDN article.

MSDN article