Nov 2, 2010

DRY (don’t repeat yourself) Principle in Context of Data Access Layer

Introduction

Today most objected oriented applications are based on some common architectural design. Today the major architectural pattern is evolved from the pillars of OOP. Besides the pillars of the OOP the basic objected oriented design principle plays a major role in designing the architect of a system. Here in this article I like to share information how DRY principle plays a major role in designing OOP based system.

The Principle

“Avoid duplicating code by abstracting out things that are common and placing those in a single location”.

Dry is simply about abstracting one requirement in one place. Once you put all duplicate code in one location you are capable for maintaining flexibility of your code. If we have a common operation among different types of modules or objects in our system, rather than typing again and again similar code we just generalize the code to make a single module. Then we try to make call (use) that module when ever needed.

Let us take a simple classic example, assume we want to calculate a permutation of number (nPr) using a procedural like in C. We were told to do the common functionality in one common function, the call that function on need base. In our case since permutation is i.e. nPr = n!/(n-r)! . The first step was, to find the factorial of n then divide to factorial of (n-r)

#include ….

Int factorial(int n)

{// ……factorial of a number

}

int main()

{ int p,n,r;

scanf(“%d%d”,&n,&r);

P = factorial(n)/factorial(n-r);

printf(“Permutation of %d P %d = %d”,n,r,p);

return 0;

}

Here instead of simply calculating factorial of n separately in the main function code and (n-r) in the main function, we separated the repeated code in common function factorial.

DRY principle also asserts like that, it separates the repeated value in common (single) place, then we simply tend to refer to that code. The main advantage behind this is

· Code maintainability you don’t have to change every module you just have one module to change

· Requirement is also defined in one location so that whenever there is modification to requirement you can simply spot them

Class Database

{

public readonly static string connectionString;

}

class Movie

{

private int Id { get; set; }

public string Title { get; set; }

public string Type { get; set; }

public double Rate { get; set; }

private string connstr;

public Movie(string title, string type, double rate)

{

this.Title = title;

this.Type = type;

this.Rate = rate;

}

public void Save()

{

string sql = "insert into movie(id,title,type,rate) values(" +

this.Id + ",'" + this.Title + "','" + this.Type + "'," + this.Rate + ")";

using (SqlConnection con = new SqlConnection(Database.connectionString))

{

con.Open();

SqlCommand cmd = new SqlCommand(sql,con);

// cmd.Connection = con;

cmd.ExecuteNonQuery();

}

}

public void Update()

{

string sql = "Update movie set(id,title,type,rate) values(" +

this.Id + ",'" + this.Title + "','" + this.Type + "'," + this.Rate + ")";

using (SqlConnection con = new SqlConnection(Database.connectionString))

{

con.Open();

SqlCommand cmd = new SqlCommand(sql,con);

// cmd.Connection = con;

cmd.ExecuteNonQuery();

}

-----}

}

Again Game and movie class also perform these operation in similar manner. The main problem with this design is code is duplicated on all class only with minor changes, this creates problem when any change occurs on the database such as changing from one vendor to other, the whole duplicated code needed to be traced and modified in each class.

This creates a great problem in code maintenance in large project where we have many classes, during migration of our system from one DB vendor to another. Besides the requirement for the application is also defined in different part of the application event thought they remain the same.

DRY Solution

Today one of the solutions employed for this type of problem is to create a generalization class which is the data access layer (DAL). Using the DAL we try to separate the database from the application classes and perform the operation using common class which is the DAL for the CRUD operation. This design is basically based on the DRY principle as a result every class, in our case Game, Video, Music don’t need to implement their CRUD operation they simply send their operation to the DAL class to perform the CRUD operation.

Here the DAL class holds the common database operation done using ADO.NET such as

· ExecuteReader

· ExecuteNonQuery

· Fill Dataset

· ExecuteScalar

Since each operation on the database involves the following one or more of the above ADO .NET methods, we tend to encapsulate these methods in the DAL class rather than repeating same code in every class as well as in a multiple methods.

A short snips for a typical operation may look like

public class DAL

{

public static string connectionstring = "";

public bool ExecuteNonQuery(string sql)

{

int affected;

using (SqlConnection con = new SqlConnection(connectionstring))

{

SqlCommand cmd = new SqlCommand( sql,con);

con.Open();

affected = cmd.ExecuteNonQuery();

}

if (affected > 0)

return true;

else

return false;

}

}

class Movie

{

…..

Private DAL dal;

Public Movie(string title, string type, double rate)

{

this.Title = title;

this.Type = type;

this.Rate = rate;

dal=new DAL();

}

public void Save()

{

// here at this point we build simply the sql queries for saving the movie object into

// database

String sql = “insert into Movie(title,type,rate) values(‘“+this.Title+”’,’”+this.Type+”’,”+this.Rate”)”;

dal.executeNonQuery(sql);

}

//for other operation like delete,update …etc the operation is loosely coupled like this

Public void Delete()

{ ///

/// sql delete operation

///

}

}

Here my point is to explain the DRY principle in context of building DAL class, at this point I simply show a rough small portion of the DAL class. It is assumed that for production environment the class may be build differently with addition of exception handling and other mechanism.

Conclusion

As the dry principle suggests us to remove the repeated code and put on a common place. In the example I try to show a simple program without repeating common code on our database operation.

Although I try to explain the DRY principle in context of the database application, DRY principle is one of the basic objected oriented principles applied in all aspects of OOP. Even when we look at other OOP principles such as SRP they try to avail the DRY principle. So the major function of DRY principle is like many OOP principle lower effort to code maintenance by encapsulating the requirement definition on a single place.




There was an error in this gadget