SgDotNet
Singapore Professional .NET User Group -For Cool Developers

Data Access Object

Latest post 08-25-2005 12:08 AM by Thanh. 2 replies.
  • 08-23-2005 2:31 AM

    Data Access Object

    On a boring Saturday evening, I was having a conversation with my Java friends whom I hadn't seen for a while. He kept on telling me how good the Java and J2EE world is, that I should get into the Java world and very soon will fall in love with it. I of course defend it vigorously with the greatness of C# and .NET, and he is the one who should switch to C# and .NET, not the other way around. Finally, we both decided to implement the DAO(Data Access Object) pattern in both languages just for the fun of it.

    Before diving into the code, what is Data Access Object? DAO manages the connection with the data source to obtain and store data. It provides an  abstract and encapsulated layer to the data source.

    The sample code provided below is just a skeleton demonstrating the DAO pattern. There is no logic at all to actually talk to any data storage mechanism. 

    DAO.cs
    using System;
    using DataFactory;
    using DAOInterface;
    using Model;

    namespace DAO
    {
      public class Client
      {
        public static void Main(string[] args)
        {
          DAOFactory Factory = SqlServerDAOFactory.getDAOFactory(DAOFactory.SQLSERVER);
          IDAO custDAO = Factory.getCustomerDAO();
          if(custDAO.insert())
            Console.WriteLine("Success");

          Factory = OracleDAOFactory.getDAOFactory(DAOFactory.ORACLE);
          custDAO = Factory.getCustomerDAO();
          if(custDAO.insert())
            Console.WriteLine("Success");         
        } 
      }
    }

    DAOFactory.cs
    using System;

    using DAOInterface;
    using SQLServer;
    using Oracle;

    namespace DataFactory
    {
      public abstract class DAOFactory
      {
        public const int SQLSERVER = 1;
        public const int ORACLE = 2;

        public abstract IDAO getCustomerDAO();
        public abstract IDAO getOrderDAO();

        public static DAOFactory getDAOFactory(int whichFactory)
        {
          switch (whichFactory)
          {
     case SQLSERVER:
       return new SqlServerDAOFactory();     
     case ORACLE:
       return new OracleDAOFactory();
     default:
       return null;
          }
        }
      } 

      public class SqlServerDAOFactory : DAOFactory
      {
        public override IDAO getCustomerDAO()
        {
          return new SqlServerCustomerDAO();
        }

        public override IDAO getOrderDAO()
        {
          return new SqlServerOrderDAO();
        }
      }

      public class OracleDAOFactory : DAOFactory
      {
        public override IDAO getCustomerDAO()
        {
          return new OracleCustomerDAO();
        }

        public override IDAO getOrderDAO()
        {
          return new OracleOrderDAO();
        }
      }

    DAOInterface.cs
    using Model;

    namespace DAOInterface
    {
      public interface IDAO
      {
        bool insert();
        bool delete();
        Customer find(int Id);
        bool update();     
      } 
    }

    Model.cs
    using System;

    namespace Model
    {
      [Serializable]
      public class Customer
      {
        private int _customernumber;
        public int CustomerNumber
        {
          get { return _customernumber; }
          set { _customernumber = value; }
        }

        private string _name;
        public string Name
        {
          get { return _name; }
          set { _name = value; }
        }   
      }   
    }

    SQLServer.cs
    using System;
    using DAOInterface;
    using Model;

    namespace SQLServer
    {
      public abstract class SqlServerLayer
      {
        public bool Connect()
        {
          Console.WriteLine("Code to connect to SQL SERVER");
          return true;
        }
      }
     
      public class SqlServerCustomerDAO : SqlServerLayer, IDAO
      {
        public SqlServerCustomerDAO() {}

        public bool insert()
        {  
          if (Connect())
          {
            Console.WriteLine("Code to insert a customer record into SQL SERVER database");
            return true;
          } 
          return false;     
        }

        public bool delete()
        {
          return true;
        }

        public Customer find(int CustNo)
        {
          return new Customer();
        }

        public bool update()
        {
          return true;
        }   
      } 

      public class SqlServerOrderDAO : SqlServerLayer, IDAO
      {
        public SqlServerOrderDAO() {}

        public bool insert()
        {
          if(Connect())
            return true;
           
          return false; 
        }

        public bool delete()
        {
          return true;
        }

        public Customer find(int OrderNo)
        {
          return new Customer();
        }

        public bool update()
        {
          return true;
        }   
      }

    Oracle.cs
    using System;
    using DAOInterface;
    using Model;

    namespace Oracle
    {
      public abstract class OracleLayer
      {
        public bool Connect()
        {
          Console.WriteLine("Code to connect to ORACLE");
          return true;
        }
      }
     
      public class OracleCustomerDAO : OracleLayer, IDAO
      {
        public OracleCustomerDAO() {}

        public bool insert()
        {
          if (Connect())
          {
            Console.WriteLine("Code to insert customer record into ORACLE database");
            return true;
          }      
          return false;     
        }

        public bool delete()
        {
          return true;
        }

        public Customer find(int CustNo)
        {
          return new Customer();
        }

        public bool update()
        {
          return true;
        }   
      } 

      public class OracleOrderDAO : OracleLayer, IDAO
      {
        public OracleOrderDAO() {}

        public bool insert()
        { 
          if(Connect())
            return true;
           
          return false; 
        }

        public bool delete()
        {
          return true;
        }

        public Customer find(int OrderNo)
        {  
          return new Customer();
        }

        public bool update()
        {
          return true;
        }   
      }
    }

    Run the build.bat batch file to compile everything. You can again use VS .NET 200* if you prefer. 

    Build.bat
    csc /t:library Model.cs
    csc /r:Model.dll /t:library DAOInterface.cs
    csc /r:DAOInterface.dll /r:Model.dll /t:library SQLServer.cs
    csc /r:DAOInterface.dll /r:Model.dll /t:library Oracle.cs
    csc /r:DAOInterface.dll /r:SQLServer.dll /r:Oracle.dll /t:library DAOFactory.cs
    csc /r:DAOFactory.dll /r:DAOInterface.dll /r:Model.dll DAO.cs

    I intentionally divide it into many DLLs to seperate its functionalities and also for easy reading. You can of course mix it anyway you like. If you read the code carefully, you will notice that the factory pattern is in used here.

    Even though the two implementations looks very much alike, I believe the C# code is much cleaner and finer.

    Hope it helps

  • 08-24-2005 5:45 PM In reply to

    Re: Data Access Object

    This was something that I actually wanted to write about.

    The melody of logic will always play out the truth. ~ Narumi Ayumu, Spiral

  • 08-25-2005 12:08 AM In reply to

    Re: Data Access Object

     icelava wrote:
    This was something that I actually wanted to write about.

    Oh yea, junp in and see if anything you can improve to make the code cleaner and better. The more I'm experimenting with different patterns, the more I discover that there are so many better ways or not so good ways to spit out code. btw, I reviewed my own code and changed the DAO to use the strategy pattern to replace the Factory pattern. Below is the new change:

    DAO.cs
    using System;
    // using DataFactory; // Factory pattern
    using DataStrategy;  // Strategy pattern here
    using DAOInterface;
    using Model;

    namespace DAO
    {
      public class Client
      {
        public static void Main(string[] args)
        {
          Context DataContext = new Context(new SqlServerDAOStrategy());
          IDAO custDAO = DataContext.Strategy.getCustomerDAO();
          if(custDAO.insert())
            Console.WriteLine("Success");
           
          DataContext.Strategy = new OracleDAOStrategy();
          custDAO = DataContext.Strategy.getCustomerDAO();
          if(custDAO.insert())
            Console.WriteLine("Success");     
        } 
      }
    }

    DAOStrategy.cs
    using System;
    using DAOInterface;
    using SQLServer;
    using Oracle;

    namespace DataStrategy
    {
      public abstract class DAOStrategy
      {
        public abstract IDAO getCustomerDAO();
        public abstract IDAO getOrderDAO();   
      }
     
      public class SqlServerDAOStrategy : DAOStrategy
      {
        public override IDAO getCustomerDAO()
        {
          return new SqlServerCustomerDAO();
        }

        public override IDAO getOrderDAO()
        {
          return new SqlServerOrderDAO();
        }
      }

      public class OracleDAOStrategy : DAOStrategy
      {
        public override IDAO getCustomerDAO()
        {
          return new OracleCustomerDAO();
        }

        public override IDAO getOrderDAO()
        {
          return new OracleOrderDAO();
        }
      }
      
      public class Context
      {
        private DAOStrategy _strategy;
        public DAOStrategy Strategy
        {
          get { return _strategy; }
          set { _strategy = value; } // didn't check for null object here
        }
       
        public Context(DAOStrategy Strategy)
        {
          this._strategy = Strategy;
        }
      }
    }

    Important point: The context class allows us to remove the switch clause  found in the factory pattern which makes it looks more cleaner. However, with the Strategy pattern, client has to directly instantiate the SQL Server and Oracle DAO which is not found in the Factory pattern.  

    Replace these 2 lines
    csc /r:DAOInterface.dll /r:SQLServer.dll /r:Oracle.dll /t:library DAOFactory.cs
    csc /r:DAOFactory.dll /r:DAOInterface.dll /r:Model.dll DAO.cs

    with these 2 lines below for compilation

    csc /r:DAOInterface.dll /r:SQLServer.dll /r:Oracle.dll /t:library DAOStrategy.cs
    csc /r:DAOStrategy.dll /r:DAOInterface.dll /r:Model.dll DAO.cs

    Hope it helps

Page 1 of 1 (3 items) | RSS
Copyright SgDotNet 2004-2008
Powered by Community Server (Commercial Edition), by Telligent Systems