• 这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。


                                                           这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。

          假设现在有如下情况,某项目的框架结构用的是ADO.NET写的简单三层。且已经开始写了一部分了。现在因为时间比较紧急,经理认为用EF写速度会快一些,于是要求我们将访问驱动层改成用EF写的。

         那么,恩,好吧,我们得改了。先看一下原来DAL层和BLL层的代码。因仅演示而已,此处只写了一个大概思路的代码。另外此处笔者只打算写一个DAL层了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.Model;
     7 
     8 namespace Anmutu.OA.AdoNetDAL
     9 {
    10     public class UserAdoNetDal
    11     {
    12         public User AddUser(User user)
    13         {
    14             //在此处写一此插入的一个SQL.会用到DBSQLHelper.using()...写就是一个insert操作。你知道的,主要是那个思想。代码略过。
    15             return null;
    16         }
    17     }
    18 }
    访问驱动层的代码
     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.Model;
     8 
     9 namespace Anmutu.OA.BLL
    10 {
    11     public class UserService
    12     {
    13        //调用一下数据库访问层的方法,打个酱油。
    14         private AdoNetDAL.UserAdoNetDal userAdoNetDal = new UserAdoNetDal();
    15         public User Add(User user)
    16       {
    17           return  userAdoNetDal.AddUser(user);
    18        }
    19     }
    20 }
    逻辑层的代码

           还好还好,DB里有的相应的表的。我们DBFirst一下,拿到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.Model;
     7 
     8 namespace Anmutu.OA.DAL
     9 {
    10     public class UserEFDal
    11     {
    12         public User AddUser(User user)
    13         {
    14             //得到的EF上下文,DBFirst不用解释了吧。
    15             AnmutuModelContainer db = new AnmutuModelContainer();
    16             //加到DB里去。
    17             db.UserSet.Add(user);
    18             //保存
    19             db.SaveChanges();
    20             return user;
    21         }
    22     }
    23 }
    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 用EF作为访问驱动层时的代码。
    15         private DAL.UserEFDal _userEfDal = new UserEFDal();
    16         public User AddUser(User user)
    17         {
    18             return _userEfDal.AddUser(user);
    19         }
    20         #endregion
    21         #region 用ADO.NET作为访问驱动层时的代码
    22         //private AdoNetDAL.UserAdoNetDal userAdoNetDal = new UserAdoNetDal();
    23         //public User Add(User user)
    24         //{
    25         //  return  userAdoNetDal.AddUser(user);
    26         //}
    27         #endregion
    28     }
    29 }
    修改后的逻辑层的代码(注意对比)

     

           这样貌似就算是修改好了。在这个小案例中。那么两个分析一下具体的情况。现在的情况是逻辑层的的代码,依赖与一个具体的实现,那么依赖者就必须跟着变化。就如同这里的实例名字不一样,那么下面具体用到此实例的时候就都得改了。如果这里调用数据库访问层的方法的名字不一样,同样也是需要改动的。目前这个小案例中,修改的地方还真就不算多。但是,正如你知道的,一个项目中不可能真的只有这么一个方法的。会有很多方法。那么,是的,你得修改很多的地方了。来图看一下,它可能是这样。 

                               

     

           程序猿甲说,这个好办,我们可以CTRL+F,然后选择将相应的需要改的全部替换也就好了。

           攻城狮乙说,这个方法,固然可以,可是如果哪个地方替换错了,就有那么一个地方名字一样,替换错误了,那岂不是很麻烦么?

           程序猿丙说,我们可以依旧CTRL+F,我们选择单个替换就好了呀,我们可以小心一点的。

           攻城狮丁说,这个方法,依旧且算可以,只是就算你很小心没有替换错,不是很耽误时间的么?时间可就是金钱啊。

           那么,思路是我们就可以不让其依赖与一个具体的实例。而是依赖与一个抽象的实例。比如让其依赖与一个接口。用接口解除其对具体数据库访问的耦合。通过让BLL层去依赖一个公共的变化很少的契约接口,依赖抽象,具体的实现在变化的时候,BLL层就不用变化了。这是对变化点的一个封装。有点绕口且有点‘WHERE IS 南 WHERE IS 北’(笔者用此句表示不太容易理解,如果没有了解过接口神马的) 的感觉。简单的说就是用一个抽象的实例,但是后面new出来的就是一个具体的了。

          那么,将修改的代码将会是这个样子:

     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         //IDAL.IUserDal userDal=new UserAdoNetDal();//当要用到ADO.NET作为访问驱动时。
    16         IDAL.IUserDal  userDal=new UserEFDal();//当要用到EF作为访问驱动时。
    17         public User AddUser(User user)
    18         {
    19             return userDal.AddUser(user);
    20         }
    21         #endregion
    22         #region 用EF作为访问驱动层时的代码。
    23         //private DAL.UserEFDal _userEfDal = new UserEFDal();
    24         //public User AddUser(User user)
    25         //{
    26         //    return _userEfDal.AddUser(user);
    27         //}
    28         #endregion
    29         #region 用ADO.NET作为访问驱动层时的代码
    30         //private AdoNetDAL.UserAdoNetDal userAdoNetDal = new UserAdoNetDal();
    31         //public User Add(User user)
    32         //{
    33         //  return  userAdoNetDal.AddUser(user);
    34         //}
    35         #endregion
    36     }
    37 }
    BLL层的代码(注意对比)

         如果要换访问驱动层的话,请看图:

                         

           是的,只需要在如图的位置new一个不同的就好了。且VS会给我们提示。

           这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的面向接口编程了吧。

     

     

           攻城狮戊说,可是我可能会有很多服务的地方都用到这个实例,那我都得改么?这样写很麻烦的感觉呢。

           李宁说过一句话,他说,一切皆有可能。所以,是的,也许以后园子时会多一篇叫做“这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的简单工厂了吧”的文章。

           笔者写的都是很简单的东西。欢迎指正,共同进步。

     

  • 相关阅读:
    laravel 使用构造器进行增删改查
    explan各项说明
    data函数参数
    php引用
    PHP开发api接口安全验证方法一
    redis主从配置
    php 实现同一个账号同时只能一个人登录
    MySQL慢查询1- 开启慢查询
    前端基础 & 初识HTML
    HTTP协议概述
  • 原文地址:https://www.cnblogs.com/anmutu/p/3869580.html
Copyright © 2020-2023  润新知