C#——依赖接口编程与简单工厂

在开发一个项目的时候,有时候会碰到这样一个问题:就是项目开发到一半时,原先对数据库的访问走的是ADO.NET,中途项目经理突然要求改成使用EF实体模型去访问数据库......呃好吧!这样的话就需要去把原有的代码个修改,我们都知道在ADO.Net中,数据访问层DAL与业务逻辑层是耦合在一块的,当数据访问层的代码由原来的使用ADO.NET去访问数据库变为使用EF实体模型去访问数据库时,业务逻辑层BLL的代码也要去相应的改变(这是一件相当痛苦的事情)

 1        //private UserEFDAL userefDal = new UserEFDAL();//当项目使用EF去访问数据库时创建一个实例
 2 
 3         // private UserInfoDAL userDal = new UserInfoDAL();//当项目使用ADO去访问数据库时创建一个实例
 4        //但是以上的方法当数据库访问的方法改变时,BLL层都要做出相应的改变并且不能保证改变后nwe出的实例名称相同
 5        //那样就相当的悲剧了、、、、
 6 public User Add(User userInfo)
 7        {
 8            return userDal.EFAdd(userInfo);//当通过两种方法new出来的实例名称不同时,悲催了。。。。
 9 
10            //return userefDal.ADOAdd(userInfo);
11        }         

通过上面的简单的代码我们可以发现,当我们要切换数据库的访问方式时,需要不断的去改变new实例的名称,并且在EF中定义的添加的方法叫EFAdd,在ADO中定义的添加的方法叫ADOAdd,这样去修改代码的的工程非常的浩大(当你去改完时,估计你也被炒鱿鱼了),而我们又希望能够在当数据访问的方式不用的时候,BLL层的代码改变很少,或者不去改变BLL层的代码就能切换数据库访问的方式,我们希望在不同是数据访问方式不同时,内部的方法不变,我们规定在ADO或是EF中添加的方法为Add、修改的方法为Edit等。说到这,想必大家应该明白接下去要说的是什么了,没错,就是接口,在C#中什么是接口?所谓的接口其实就是一种规范,使得实现接口的类或结构在形式上保持一致,当一个类去继承该接口时,就必须实现该接口的所有成员,使用接口可以使程序更加清晰和条理化,这就是接口的好处。

所以,在上面的例子中,我们可以定义一个接口,让EFDAL和ADODAL去继承这个接口

//定义一个接口,当使用ADO.NET访问数据库或是时候EF实体模型访问时,都继承于这个接口
   public  interface IDALInterface
    {
     //这里还可以定义多个成员
       User Add(User userInfo);
    }


//EFDAL去继承IDALInterface这个接口
public class UserEFDAL : IDALInterface
  {
        DataModelContainer db = new DataModelContainer();
        public User Add(User userInfo)
        {

            db.User.AddObject(userInfo);
            db.SaveChanges();
            return userInfo;
        }
    }


public class UserInfoDAL : IDALInterface//ADO.NET访问数据库时继承IDALInterface接口
    {
        /// <summary>
        /// 实现IDALInterface接口
        /// </summary>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public User Add(User userInfo)
        {
           //这里执行Add操作并返回插入的实体
            return userInfo;
        }
    }
      //BLL层代码
       IDALInterface userDal = new UserEFDAL();
       //在这里因为EF的DAL与ADo的DAL都继承自IDALInterface
       //当访问数据库的方式改变后,只要改变相应的数据库访问实例。这样就减少的代码的改动量
public User Add(User userInfo)
       {
           return userDal.Add(userInfo);

           //return userefDal.Add(userInfo);
       }

通过上面的例子,我们可以看到,只要在BLL层改变new不同的的实例,而不需要去改变太多的BLL的代码,就可以在不同的数据访问的方式切换,当然还是需要在BLL层修改代码。我们还是需要去一个个的找 IDALInterface userDal = new UserEFDAL();,然后去修改,有没有一种方法可以做到不去修改BLL层的代码而就能改变不同的数据库访问方式,答案当然是有的。我们可以创建一个工厂,通过反射的方法去创建一个实例

/// <summary>
       /// 创建一个简单的工厂来获取相应的程序集,
       /// </summary>
       /// <returns></returns>
       public static IDALInterface GetDALStyle()
       {
           string assemblyName = ConfigurationManager.AppSettings["assemblyName"];//通过配置文件来配置数据库的访问的方式
           string typeName = ConfigurationManager.AppSettings["typeName"];

           //通过反射创建一个实例
           return Assembly.Load(assemblyName).CreateInstance(typeName) as IDALInterface;
       }

而相应的BLL的代码就改成

       IDALInterface userDal = DALSimpleFactory.GetDALStyle();//通过工厂去创建一个实例
       public User Add(User userInfo)
       {
           return userDal.Add(userInfo);

           //return userefDal.Add(userInfo);
       }

至此,我们就只需在配置文件中去修改相应的配置,就可以在不修改过多的代码下完成不同数据库访问方式的切换,大大减少的项目的开发的周期,通过工厂来得的实例,可以大大的减少BLL层与DAL层之间的耦合,也就是所谓的解耦。