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