这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的简单工厂了吧

                                            这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的简单工厂了吧

        接上文(这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧)。
       上文有说到,我在BLL层是已经可以new出不同的实例,这样就可以做到数据库驱动层的一个切换了。因为其是用接口的实例,而后面是用一个具体实现。这样果断是可以做到数据库访问驱动层的一个切换的,非常简单的只需要我们在BLL层改动一点代码,new 出不同的实例出来就可以了。只是如果是这样的话,那么,我们要做到切换数据库访问驱动层的话,就得在BLL层改代码了。正如上文提到,如果有很多地方都要用到此实例的话,我们就都得到每个BLL或者说是服务的地方去new,多且不说,万一哪个地方一不小心new错了也是不好的。所以,我们能不能做到不动BLL层就可以做到切换数据访问驱动层的呢。
      上文中在文章结尾也有说过园子里可能会有一篇叫“这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的简单工厂了吧”的文章。也有园友提出这样写不是很好,应该用简单工厂(笔者在此处对园友表示感谢)。那么,我就写了这篇名字叫做“ 这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的简单工厂了吧”的文章吧。我们开始再用简单工厂优化一下吧。
      个人认为其本质也就是写一个静态类。里面返回一个实例可以了。返回实例要一个抽象的,在写方法的时候。下面return的时候就要返回一个具体的了。
      我们新建一个类库项目。在其中,我们写一个静态方法,用此静态方法得到实例。而在BLL层调用一个这个方法,也就可以了。其代码如下。
 1  using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using Anmutu.OA.AdoNetDAL;
 7 using Anmutu.OA.DAL;
 8 
 9 namespace Anmutu.OA.DalFactory
10 {
11   public class DalSimpleFactory
12     {
13       public static IDAL.IUserDal GetUserDal()
14       {
15           //return new UserAdoNetDal();//这样就是访问一个Ado.net的访问驱动层。
16           return new UserDal(); //这样就是创建一个EF的数据访问驱动层。
17       }
18     }
19 }
简单工厂(用户创建实例)
1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 using Anmutu.OA.Model;
 8 
 9 namespace Anmutu.OA.IDAL
10 {
11     /// <summary>12     /// 创建一个接口,约定其返回类型是User类,参数是一个user实体。
13     /// </summary>14       interface IUserDal
15       {
16           User AddUser(User user);
17       }
18 }
DAL接口层的约束(未做修改)
1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using Anmutu.OA.IDAL;
 7 using Anmutu.OA.Model;
 8 
 9 namespace Anmutu.OA.AdoNetDAL
10 {
11     public class UserAdoNetDal:IUserDal//此处实现接口里的方法。因为接口里的方法名字也就AddUser,这里就没有必要CTRL+SHIFT+...了。我用的是Resharper插件,也就不用点实现了。12     {
13         public User AddUser(User user)
14         {
15             //在此处写一此插入的一个SQL.会用到DBSQLHelper.using()...写就是一个insert操作。16             return null;
17         }
18     }
19 }
ADO.NET作为访问驱动层时的代码(未做修改)
1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using Anmutu.OA.IDAL;
 7 using Anmutu.OA.Model;
 8 
 9 namespace Anmutu.OA.DAL
10 {
11     public class UserEFDal:IUserDal//这里实现接口。
12     {
13         public User AddUser(User user)
14         {
15             //得到的EF上下文,DBFirst不用解释了吧。
16             AnmutuModelContainer db = new AnmutuModelContainer();
17             //加到DB里去。
18             db.UserSet.Add(user);
19             //保存
20             db.SaveChanges();
21             return user;
22         }
23     }
24 }
EF作为访问驱动层时的代码(未做修改)
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using Anmutu.OA.AdoNetDAL;
 7 using Anmutu.OA.DAL;//添加EF层的程序集。
 8 using Anmutu.OA.Model;
 9 
10 namespace Anmutu.OA.BLL
11 {
12     public class UserService
13     {
14         #region 用到简单工厂后的代码
15         private IDAL. IUserDal userDal = DalFactory.DalSimpleFactory.GetUserDal();
16         public User AddUser( User user)
17         {
18             return userDal.AddUser(user);
19         }
20         #endregion
21 
22         #region 实现接口后的代码
23 
24         // IDAL.IUserDal userDal = new UserAdoNetDal();//当要用到ADO.NET作为访问驱动时。
25         // IDAL.IUserDal userDal = new UserDal();//当要用到EF作为访问驱动时。
26         //public User AddUser(User user)
27         //{
28         //    return userDal.AddUser(user);
29         //}
30 
31         #endregion
32 
33         #region 用EF作为访问驱动层时的代码。
34 
35         //private DAL.UserEFDal _userEfDal = new UserEFDal();
36         //public User AddUser(User user)
37         //{
38         //    return _userEfDal.AddUser(user);
39         //}
40 
41         #endregion
42 
43         #region 用ADO.NET作为访问驱动层时的代码
44 
45         //private AdoNetDAL.UserAdoNetDal userAdoNetDal = new UserAdoNetDal();
46         //public User Add(User user)
47         //{
48         //  return  userAdoNetDal.AddUser(user);
49         //}
50 
51         #endregion
52     }
53 }
逻辑层的代码(注意区别)
      看一下新加的简单工厂的图:
                                 
 
 
      逻辑层中的图:
                              
       那么,我们这么写的好处,就很好的做到了职责单一原则。我简单工厂的职责就是我只负责创建我的实例。而逻辑层根本就不需要关心我的实例是如何来的。并且这样我们如果要重新发布网站的话。项目也不用重新生成,只需要把这个简单工厂的程序集重新生成,把这个简单工厂的程序集复制到我们部署的网站的bin目录的文件下,网站一重启,整个网站的代码是不需要重新编译的。如若要切换,只需要改“简单工厂”里的代码就可以了。
 
        攻城狮又说了,这样做的话确实是又进步了一些。从最开始的为了切换一个数据库的驱动层,几乎将整个项目的每个层的很多地方都要做改动到只需要到逻辑层里那个new实例的地方(new出一个不同的实例来就可以做到切换数据库驱动层了)。然后因着如果切换一个数据库访问驱动层还得到BLL层那个创建实例的地方去修改且还会有不同的服务要此实例,改动地方依旧很多还可能出点错。我们就想到不在BLL里创建实例,而到其他的地方创建实例。于是就用到了简单工厂,也就是用静态方法创建实例。就可以不用在BLL层修改代码了,只需要在简单工厂里修改其创建的实例,在BLL层调用其创建实例的方法就可以了。那么可不可以通过配置就切换这个数据访问驱动层呢。那样,不就更好么,只改下APP.CONFIG就切换数据库访问驱动层。
       李宁说过一句话,他说,一切皆有可能。所以,是的,也许以后园子并不会多一篇叫做“这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的抽象工厂了吧”的文章。
       笔者依旧写的是很简单的东西。欢迎拍砖指正,共同进步。

 

 

posted @ 2014-08-02 04:15  公子若不胖天下谁胖  阅读(1415)  评论(0编辑  收藏  举报