Labels

Monday, November 15, 2010

Factory - Creational

1.1     Introduction


  • Factory patterns abstract the object instantiation process. They hide how objects are created and help make the overall system independent of how its objects are created and composed.
  • All OO languages have an idiom (new operator) for object creation. Factory patterns allow us to write methods that create new objects without explicitly using the new operator. This allows us to write methods that can instantiate different objects and that can be extended to instantiate other newly-developed objects, all without  modifying the method's code.

  • There are two factory patters viz. Factory and Abstract Factory Method

·         Factory Approach - Focuses on the use of inheritance to decide the object to be instantiated.
·         Abstract Factory Approach - Focuses on the delegation of the instantiation to another object

2      Factory Method Design Pattern:

2.1     Introduction

The Factory Method pattern is a creational pattern. Like other creational patterns, it deals with the problem of creating objects without specifying the actual class of objects that will be created. The Factory Method is intended to define an interface for clients to use to create an object, but lets subclasses decide which class to instantiate. Factory Methods let a class defer instantiation to subclasses.
               

2.2     Intent

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

2.3     Applicability

Use the Factory Method pattern in any of the following situations:

·         A class can't anticipate the class of objects it must create.
·         A class wants its subclasses to specify the objects it creates.

2.4     Structure


2.1     Participants


Product
Defines the interface for the type of objects the factory method creates
ConcreteProduct
Implements the Product interface
Creator
Declares the Factory Method, which returns an object of type Product
ConcreteCreator
Overrides the factory method to return an instance of a ConcreteProduct



2.2     Collaborations

Creator relies on its subclasses to implement the factory method so that it
returns an instance of the appropriate ConcreteProduct

2.3     Intent

So what exactly does it mean when we say that "the Factory Method Pattern lets subclasses decide which class to instantiate?"

·         It means that Creator class is written without knowing what actual ConcreteProduct class will be instantiated.
·         The ConcreteProduct class which is instantiated, is determined solely by which ConcreteCreator subclass is instantiated and used by the application.
·         It does not mean that somehow the subclass decides at runtime which ConreteProduct class to create.

2.4     Actual Implmentation









class MainApp
  {
    static void Main()
    {
     
      Creator[] creators = new Creator[2];
      creators[0] = new ConcreteCreatorA();
      creators[1] = new ConcreteCreatorB();

      foreach(Creator creator in creators)
      {
        Product product = creator.FactoryMethod();
        Console.WriteLine("Created {0}", product.GetType().Name);
      }
    }
  }


2.5     Few more Implmentation




2.6     Pros

·         Shields clients from concrete classes. i.e Code is made more flexible and reusable by the elimination of instantiation of application-specific classes.
·         If a framework uses the Factory Method pattern, it enables third-party developers to plug-in new Products.
·         Code deals only with the interface of the Product class and can work with any ConcreteProduct class that supports this interface
·         The Creator create method can be coded to return a default Product.

2.7     Consequences

·         Clients might have to subclass the Creator class just to instantiate a particular ConcreteProduct. i.e Coding a new Product means writing two classes - one for the Creator and one for the concrete Creator.
·         Static - inheritance based

2.8     Examples in C#

  1. System.Collections.Ienumerable

The Iterator interface traverses a collection of objects. The interface aims to create a way to access the elements in a collection without exposing the internal structure of the collection. One way to implement this interface would be to have every collection class return an iterator object supporting a specific interface for iterating over collections of that particular type only. However, using this approach, one usually ends up exposing the internal structure of the collection being traversed. The FCL uses a better approach: it uses a factory method to return a polymorphic instance of the appropriate iterator class. All iterators returned by this factory method support a common interface for enumerating over all collection classes without exposing the internal structure of the collection being traversed. This has the added benefit of allowing changes to be made to the collection without requiring a change in the client code.

By specifying a GetEnumerator factory method in the IEnumerable interface and by having all collection classes implement this interface, the framework exposes one interface for obtaining an enumerator for a collection. ArrayList is one such class that implements the IEnumerable interface. ArrayList.GetEnumerator returns an IEnumerator object capable of enumerating over the elements in the ArrayList. Figure 1 shows the class hierarchy where the Iterator interface uses the Factory Method pattern.


Since an iterator must have knowledge of the internal structure of the class over which it iterates, it is best to let every class provide its own iterator. IEnumerable classes provide their own iterators using GetEnumerator. In Figure 1, IEnumerable (the Creator) defines the interface by which an IEnumerator (the Product) is returned to the client. A ConcreteCreator (ArrayList) can then be called to return a ConcreteProduct (ArrayListEnumeratorSimple, a private inner class of ArrayList), which is an IEnumerator object capable of iterating over an ArrayList. Clients are required to refer to the returned object by the interface IEnumerator.

  1. The System.Security.Cryptography Classes

The .NET Framework contains a rich and extensible collection of cryptography classes that you can use within your own programs, right out of the box. Cryptography classes are part of the System.Security.Cryptography namespace. These classes use the Factory Method pattern to decouple the choice of algorithms used from their specific implementations.

SymmetricAlgorithm, AsymmetricAlgorithm, and HashAlgorithm are the three roots of the class-inheritance hierarchy in the cryptography framework. These are abstract classes from which specific implementations of various encryption algorithms are derived. Each of these classes supports a static factory method called Create, which creates a particular instance of the cryptography class based on the type of algorithm requested. For example, the following line will instantiate a SymmetricAlgorithm-derived class called DESCryptoServiceProvider, which is the default implementation of the Data Encryption Standard (DES) algorithm in the .NET Framework.


  // Return an instance of DESCryptoServiceProvider
  SymmetricAlgorithm s = SymmetricAlgorithm.Create("DES");

The mapping between the string arguments and the instantiated classes can be found here.

Like WebRequest.Create, SymmetricAlgorithm.Create is a parameterized factory method; it takes a parameter that identifies the type of object to create, and all objects created are of type SymmetricAlgorithm. The use of a parameterized factory method here is important because it provides opportunities for extending the cryptography framework. For example, by adding a mapping for the RC5 algorithm (which does not currently exist in the .NET Framework SDK) that returns an instance of, say, RC5CryptoServiceProvider, one can add an RC5 implementation to the existing framework, and instantiate it using the following line:


  // Return an instance of RC5CryptoServiceProvider
  SymmetricAlgorithm s = SymmetricAlgorithm.Create("RC5");

  1. ASP.NET HTTP Pipeline

Several instances of the Factory Method pattern can be found in the ASP.NET HTTP pipeline. The ASP.NET HTTP pipeline is a set of classes (in the System.Web namespace) that a web server uses to process an incoming HTTP request and return a response to the client. The pipeline takes care of session management, application pooling, caching, security, etc.

At every point in the pipeline, the objective is to advance the request processing by one step by either identifying the objects that can handle the incoming request, or by forwarding the request to objects capable of handling the request. Factory methods come into play when different types of objects need to be instantiated, based on the type of incoming request.

System.Web.HttpApplicationFactory

The entry point in the pipeline is the HttpRuntime object, which creates an instance of HttpContext for the particular request. HttpRuntime does not try to determine the type of HttpApplication object that will handle the request. Instead, it calls the static factory method HttpApplicationFactory.GetApplicationInstance, passing it the HttpContext instance just created. HttpApplicationFactory is an undocumented class that contains the logic required to determine the HttpApplication object capable of handling an incoming request. GetApplicationInstance uses the HttpContext instance to determine the virtual directory (i.e., application) that this request was sent to. If the virtual directory has been called before, then the HttpApplication object (or a derived ASP.Global_asax object, if Global.asax is defined) is returned from the pool of applications. Otherwise, a new HttpApplication object for that virtual directory is created and returned. Figure 4 shows the class diagram for instantiating an HttpApplication object capable of handling the request.



HttpApplicationFactory.GetApplicationInstance is a parameterized factory method. It takes a parameter that identifies the type of product to create, and all products created are of type HttpApplication.


System.Web.IHttpHandlerFactory

Moving farther along in the pipeline, the HttpApplication instance just created needs the object that can handle the type of resource requested. This object is called a handler. To look up the proper handler, the HttpApplication first determines the factory that can create the handler. It does that by looking up the <httphandlers> section of the machine.config file. If it's not found in machine.config, it looks up the application's web.config file, using the inherited configuration model. The <httpHandlers> section in these config files lists the handlers currently registered for the application. A part of this section is reproduced below.


  <httpHandlers>
    <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory" />
    <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory" />
    .....
  </httpHandlers>

This section shows the mapping between the type of resource requested and the class capable of creating a handler for that resource. If an .aspx page is requested, the System.Web.UI.PageHandlerFactory class will be called. Once this class has been located, HttpApplication invokes the IHttpHandlerFactory.GetHandler factory method on the IHttpHandlerFactory interface to retrieve a new instance of the handler class. All such factory classes must implement the IHttpHandlerFactory interface. These factory classes have no behavior except to dynamically manufacture new IHttpHandler objects using the GetHandler method. This method returns an IHttpHandler object, which in this example is the System.Web.UI.Page-derived class created from the .aspx file. For an .aspx file called SamplePage.aspx, the compiled class will be called ASP.SamplePage_aspx, as shown in Figure 5. This class serves as the endpoint for the request, and is responsible for populating the response buffer for that particular request.



IHttpHandlerFactory.GetHandler is a classic example of the Factory Method pattern, where IHttpHandlerFactory (the Creator) decides which IHttpHandlerFactory-derived object to create, PageHandlerFactory (the ConcreteCreator) creates ASP.SamplePage_aspx (the ConcreteProduct), which is returned as an IHttpHandler (the Product) object.

Hope this helps.

Thanks & Regards,
Arun Manglick

No comments:

Post a Comment