Geeks With Blogs
AzamSharp Some day I will know everything. I hope that day never comes.

I decided to look into the design patterns so I can write good code. These days I am learning the Factory Pattern. The first important rule is "Program to an interface and not the implementation". What does it mean?

We all write code like this:

 Student student = new Student(); 

This is an example of programming to the implementation. This is because Student is a concreate class and when we type new then we are actually making an object of the concreate class. This way we are exposing the concreate class which will make it harder to be changed in the future. 

A better way is to use the abstract class or an interface like the one shown below: 

public abstract class User

{

public abstract void Save();

}

And now every concreate class inherits from the User abstract class.

 public class Student : User
    {     

        
public override void Save()
        {
            Console.WriteLine("Save Student"); 
        }    
     
    }

And so does the Teacher:

 class Teacher : User
    {
        
public override void Save()
        {
            Console.WriteLine("Save Teacher"); 
        }      
    }

Now, you can access the Student as well as Teacher in the following way:

 User user = new Student(); // Student is created 

 
User user = new Teacher(); // Teacher is created

This is little better but still we are using new to create the concreate classes. What we need is some mechanism that will create these users for us. For this reason let's look into Simple Factory which will be responsible for creating the users.

Here is our factory defined which is responsible for creating Users.

public class UserFactory
    {

        
public User CreateUser(string type)
        {
            
if (type.Equals("Student"))
                
return new Student();
            
else if (type.Equals("Teacher"))
                
return new Teacher();
            
else if (type.Equals("Admin"))
                
return new Admin();
            
else return null
        }

    }

And we can use the factory with the following code:

UserFactory factory = new UserFactory();
User user = factory.CreateUser("Student"); 
// Student is created
User2 user2 = factory.CreateUser("Teacher"); // Teacher is created 

All is good but in the UserFactory we have If-Else checks which makes the functionality of the Factory dependent on the checks and everytime a new user is added we need to add a new if-else. We can remove all the if-else by using the Activator class funtionality. Check out the new UserFactory below: 

 public class UserFactory
    {
        
public User CreateUser(Type type)
        {
            
return (User)Activator.CreateInstance(type);
        }
    }

Now, the above factory does not depends on the if-else checks but it creates and returns the instance of the object created and return the interface/abstract class.

And Here is how you can use the new factory. 

 static void Main(string[] args)
        {
            UserFactory factory = 
new UserFactory();
            User user = factory.CreateUser(
typeof(Student));
            user.Save();

            user = factory.CreateUser(
typeof(Teacher));
            user.Save();             
        }

Abstract Factory:

If your factory creates different types of products then you can also make the abstract factory. The abstract factory will have some abstract methods which will be implemented in the concreate factories.

Take a look at the abstract factory below:

 public abstract class UserFactory
    {
        
public abstract User CreateUser();
    }

And here are the StudentFactory and TeacherFactory:

 class StudentFactory : UserFactory
    {
        
public override User CreateUser()
        {
            
return new Student(); 
        }
    }
    
     
class TeacherFactory : UserFactory
    {
        
public override User CreateUser()
        {
            
return new Teacher(); 
        }
    }

And in the main program you can use it like this:

 static void Main(string[] args)
        {
            UserFactory factory = 
new StudentFactory();                        
            User user = factory.CreateUser(); 
// Student is created
            
user.Save();

            factory = 
new TeacherFactory();
            User user = factory.CreateUser(); 
// Teacher is created
            
user.Save(); 
        }

If you think this can be much improved then please let me know. Maybe a factory using Generics!!

powered by IMHO 1.3

Posted on Sunday, March 5, 2006 11:32 AM | Back to top


Comments on this post: Making Factories!

# re: Making Factories!
Requesting Gravatar...
I use the factory all the time, but for places where the generated type needs to be created via reflection, or via some encapsulated logic path.

In your example, I don't much see the value. In the place where you used "new", you had the specific type name.

When you used typeof, you had the specific type name. The factory didnt give you anything, except for code bloat to maintain.


In my mind whatever flaws

User user = new Student()

has

User user = = factory.CreateUser(typeof(Student));

also has.

The abstract factory doesnt add anything either (in this case)

As I said before, if you have a bunch of logic that creates multiple object trees, or are grabbing types out of reflection from config or databases, then the factory makes sense. I dont see if for this (obviously trivial) example
Left by Jason Coyne on Mar 07, 2006 7:13 AM

Your comment:
 (will show your gravatar)


Copyright © Mohammad Azam | Powered by: GeeksWithBlogs.net