Let us learn Factory Pattern

Niladri.Biswas
Posted by in Design Pattern & Practices category on for Beginner level | Points: 250 | Views : 8026 red flag
Rating: 5 out of 5  
 1 vote(s)

In this article we will learn about Factory Pattern and it's implementation


 Download source code for Let us learn Factory Pattern

Introduction

Factory pattern comes under the category of Creational Pattern that promises the best way to create objects.The essence of the Factory Pattern is to "Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."(Quoted from Gang Of Four)

If we need the creation of many different types of objects when all derived from a common base type, Factory Pattern is the choice. Factory pattern does this by the help of Factory Method.It defines a method for creation of objects to sub classes.This means that a base class(abstract class) or interface is defined and subclasses which implement the interface / abstract class , are left to object instantiation. However, client code doesn't create an object against this interface. At run time, the Factory Method accepts a desired object as a parameter and returns a base class pointer to a new instance of that object.This pattern works best when a well-designed interface is used for the base class, so there is no need to cast the returned object.

Objective

In this article we will look into as how Factory Method is useful in object creation.This article will use invocation of workflow services after creation of their instances deferred till run time by the help of factory method.The concrete classes are the windows services here.

Case Study

This happens to be a real time scenario which we encounter some times back. I will extract the needed portion from the scenario that will fit for our learning purpose.

Once we had to interact with the Workflows from the Windows Services and the invocation of the Workflows (instance creation of the Workflow classes) were kept hidden from the client i.e. Windows Services. In this example, we will look into as how we factory pattern can help us in accomplishing so.

Step 1: Create the Workflow Project

First of all, let us create a "Sequential Workflow Console Application" project, and then add two Sequential workflows namely FirstSequentialWorkflow and SecondSequentialWorkflow.

Add a Code Activity component in the FirstSequentialWorkflow (FirstSequentialWorkflow.cs) and in the Execute Code event write the below code

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

{

Console.WriteLine("This workflow was invoked by {0}", WorkFlowInvokedBy);

Console.ReadKey();

}

Follow the same step for SecondSequentialWorkflow(SecondSequentialWorkflow.cs)

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

{

Console.WriteLine("This workflow was invoked by {0}", WorkFlowInvokedBy);

Console.ReadKey();

}

We will pass the WorkFlowInvokedBy property value from the client application and that will be displayed at runtime.

Now compile the project and it will build successfully

Step 2: Create the Workflow Factory Service Project

Now create a "Class Library" project and name it as WorkflowFactoryService.Let us first look into the UML class diagram

We can figure out that, the two Concrete classes viz ConcreteFirstWorkflow(ConcreteFirstWorkflow.cs) and ConcreteSecondWorkflow(ConcreteSecondWorkflow.cs) are implementing the IInstance interface's GetInstance() method.

IInstance.cs

public interface IInstance

{

Type GetInstance();

}

ConcreteFirstWorkflow.cs

public class ConcreteFirstWorkflow : IInstance

{

public Type GetInstance()

{

return typeof(ConcreteWorkFlows.FirstSequentialWorkflow);

}

}

ConcreteSecondWorkflow.cs

public class ConcreteSecondWorkflow : IInstance

{

public Type GetInstance()

{

return typeof(ConcreteWorkFlows.SecondSequentialWorkflow);

}

}

The WorkflowFactory (WorkflowFactory.cs) class's (it is the Factory class) GetObject method (it is the factory method) return the needed workflow class instance depending on the WorkflowType parameter passed to it.

WorkflowFactory.cs

public class WorkflowFactory

{

public IInstance GetObject(Constants.WorkflowType WorkflowType)

{

IInstance instance = null;

switch (WorkflowType)

{

case Constants.WorkflowType.FIRST_WORKFLOW:

instance = new ConcreteFirstWorkflow();

break;

case Constants.WorkflowType.SECOND_WORKFLOW:

instance = new ConcreteSecondWorkflow();

break;

}

return instance;

}

}

That's all about the Factory Method.Now we need to expose some service to the external client. For that purpose we have IFactoryService(IFactoryService.cs) interface

public interface IFactoryService

{

void Start();

void Stop();

Constants.WorkflowType WorkflowType { get; set; }

}

The Start() method will start the Workflow runtime engine.

The Stop() method will stop the Workflow runtime engine.

The client i.e. the Windows Services has to register to the WorkflowType property inorder to determine which Workflow service they are interested in

The implementing class for this interface (i.e. IFactoryService) is the FactoryService (FactoryService.cs).Below is a full impplementation for the same

public class FactoryService : IFactoryService

{

WorkflowRuntime workflowRuntime = null;

WorkflowInstance instance = null;

 

public FactoryService()

{

workflowRuntime = new WorkflowRuntime();

}

#region IFactoryService Members

public Constants.WorkflowType WorkflowType { get; set; }

 

public void Start()

{

ThreadPool.QueueUserWorkItem(new WaitCallback(ExecuteWorkflow));

}

 

public void Stop()

{

workflowRuntime.StopRuntime();

}

#endregion

#region Private Methods

 

private void ExecuteWorkflow(object state)

{

try

{

Dictionary dictParams = new Dictionary();

switch (WorkflowType)

{

case Constants.WorkflowType.FIRST_WORKFLOW:

dictParams.Add("WorkFlowInvokedBy", "First Window Service");

break;

case Constants.WorkflowType.SECOND_WORKFLOW:

dictParams.Add("WorkFlowInvokedBy", "Second Window Service");

break;

}

instance = workflowRuntime.CreateWorkflow(GetWorkflowInstance(), dictParams);

instance.Start();

}

catch (Exception ex)

{

throw ex;

}

}

 

private Type GetWorkflowInstance()

{

WorkflowFactory factory = new WorkflowFactory();

return factory.GetObject(WorkflowType).GetInstance();

}

#endregion

}

The presence of the QueueUserWorkItem with the Callback method ensures that the OnStart() method of the Windows Service will run as expected without consuming more execution time if many workflow instances are created also.If we need to pass any parameter to the workflow, the we need to do so via a

Dictionary<string, object> dictParams = new Dictionary<string, object>();

object.In the ExecuteWorkflow method,we are checking the WorkflowType and then adding the needed value to the dictionary object. Then we are creating the WorkFlow instance by using the GetWorkflowInstance() method that returns Type.This method, internaly calls the factory method to create the workflow instance being requested by the Windows Service applications.

Step 3: Create the Windows Service Project

Finally we will create two Windows Service project - one by the name FirstWindowService, the other by the name SecondWindowService.

The implementation of the Service1.cs in FirstWindowService is as under

public partial class Service1 : ServiceBase

{

IFactoryService iService;

public Service1()

{

InitializeComponent();

iService = new FactoryService();

}

protected override void OnStart(string[] args)

{

iService.WorkflowType = Constants.WorkflowType.FIRST_WORKFLOW;

iService.Start();

}

protected override void OnStop()

{

iService.Stop();

}

}

The implementation of the Service1.cs in SecondWindowService is as under

public partial class Service1 : ServiceBase

{

IFactoryService iService;

 

public Service1()

{

InitializeComponent();

iService = new FactoryService();

}

 

protected override void OnStart(string[] args)

{

iService.WorkflowType = Constants.WorkflowType.FIRST_WORKFLOW;

iService.Start();

}

 

protected override void OnStop()

{

iService.Stop();

}

}

As we can figure out that the invocation part is really straight forward with the difference being in registering the WorkflowType

As a last step, we have to create the project installers and then install the service. Finally run the service and enjoy how it behaves.

N.B.~Those who don't know how to create,install and run a windows service, here is an article about the same.

References

Factory Method

Conclusion

Factory pattern deals with how an object is created. A factory class will have a factory method that returns a new instance of a class based on the parameter being passed.Hope this article will be helpful whoa are interested in knowing and implementing Factory pattern.

Zipped file is attached herewith.Thanks for reading

Page copy protected against web site content infringement by Copyscape

About the Author

Niladri.Biswas
Full Name: Niladri Biswas
Member Level: Platinum
Member Status: Member
Member Since: 10/25/2010 11:04:24 AM
Country: India
Best Regards, Niladri Biswas
http://www.dotnetfunda.com
Technical Lead at HCL Technologies

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)