Sunday 23 October 2011

Factory Design Pattern C# Code example




Introduction:

It separates the object creational logic and reduces coupling between classes. Usually, when there are multiple classes inheriting from same base class, it is recommended to use a factory design pattern.

Noob implementation:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Factory
{
    public abstract class DbServer
    {
        //method need to be implemented by inherited classes
        public abstract string GetDbServerName();
    }
    public class MsSqlServerDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "MS Sql Server";
        }
    }
    public class OracleDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "Oracle Database Server";
        }
    }
    //factory class that will be used to create objects
    public static class DatabaseFactory
    {
        //return the required object
        public static DbServer GetDb(string DbName)
        {
            if (DbName == "Ms Sql Server")
            {
                return new MsSqlServerDb();
            }
            if (DbName == "Oracle Database Server")
            {
                return new OracleDb();
            }
            return new MsSqlServerDb();

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //get the ms sql server object
            DbServer dbServer = DatabaseFactory.GetDb("Ms Sql Server");
            //return ms sql server
            string dbName = dbServer.GetDbServerName();
            //print the name on output window
            Console.WriteLine("Server Name : " + dbName);
            //get the oracle database server object
            dbServer = DatabaseFactory.GetDb("Oracle Database Server");
            //return oracle server name
            dbName = dbServer.GetDbServerName();
            //print the name to output window
            Console.WriteLine("Server Name : " + dbName);
            Console.Read();
        }
    }
}




Noob implementation does not adhere to OPEN/CLOSE PRINCIPLE, which states that classes should be open for extension but modification, should not be allowed.

To overcome this issue, we can use “class registration approach," implementation as below.


Class Registration:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Factory
{
    public abstract class DbServer
    {
        //method need to be implemented by inherited classes
        public abstract string GetDbServerName();
        public abstract DbServer CreateDbServer();
    }
    public class MsSqlServerDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "MS Sql Server";
        }

        public override DbServer CreateDbServer()
        {
            return new MsSqlServerDb();
        }
        public static void RegisterDbServer(string dbName)
        {
            DatabaseFactory.RegisterDatabaseServer(dbName, new MsSqlServerDb());
        }
    }
    public class OracleDb : DbServer
    {
        //overridden method
        public override string GetDbServerName()
        {
            return "Oracle Database Server";
        }

        public override DbServer CreateDbServer()
        {
            return new OracleDb();
        }
        public static void RegisterDbServer(string dbName)
        {
            DatabaseFactory.RegisterDatabaseServer(dbName, new OracleDb());
        }
    }
    //factory class that will be used to create objects
    public static class DatabaseFactory
    {
        public static Dictionary<string, DbServer> dbDictionary = new Dictionary<string, DbServer>();
      
        public static void RegisterDatabaseServer(string dbName, DbServer dbServer)
        {
            dbDictionary.Add(dbName, dbServer);
        }

        public static DbServer GetDb(string DbName)
        {
            DbServer dbServer = new MsSqlServerDb();
            if (dbDictionary.ContainsKey(DbName))
            {
                dbServer = dbDictionary[DbName];
                return dbServer.CreateDbServer();
            }
            return dbServer.CreateDbServer();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //registeration
            MsSqlServerDb.RegisterDbServer("Ms Sql Server");
            OracleDb.RegisterDbServer("Oracle Database Server");

            //get the ms sql server object
            DbServer dbServer = DatabaseFactory.GetDb("Ms Sql Server");
            //return ms sql server
            string dbName = dbServer.GetDbServerName();
            //print the name on output window
            Console.WriteLine("Server Name : " + dbName);
            //get the oracle database server object
            dbServer = DatabaseFactory.GetDb("Oracle Database Server");
            //return oracle server name
            dbName = dbServer.GetDbServerName();
            //print the name to output window
            Console.WriteLine("Server Name : " + dbName);
            Console.Read();
        }
    }
}




No comments:

Post a Comment