微信号:quweiCSharp

介绍:专注于CSharp编程,.Net社区,.Net跨平台.

升级版:由简单三层,升级到简单工厂模式

2017-03-25 10:21 灰太狼的梦想

前面,复习了简单三层。可以看出三层的缺点,业务层和数据访问层耦合在一起了,如果后面我需要在上面扩展的话,就不方便了,比如,现在我只是支持微软的SQL Server数据库,要是我后面想支持MySQL,Oracle数据库呢。。。?这该咋办?你可以说,这好办,重新把访问数据库的类和方法写一遍。。显然这不是好方法。不符合,软件设计的封装性--封装变化点原则。

下面看下业务层的代码吧:

using DAL;
using Entity;
using IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BLL
{    public class ClassBLL
   {      
      ClassDAL dal = new ClassDAL();
      /// <summary>
/// 获取Class列表        
/// </summary>
/// <returns></returns>
public List<ClassEntity> GetList()
       {            
        return dal.GetList();
       }
   }
}

可以看出,代码中标橙色的代码(数据访问类的实例化代码),和业务层耦合了。

我们可以做这样的一个改变:把数据访问层实例化的代码,进行一下封装。--封装变化点,这样在业务层里面实例化的数据层的时候,就可以调用我们封装的方法。

现在我们可以这样做,添加一个接口:

using Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IDAL
{    public interface IClassDAL
   {
       List<ClassEntity> GetList();
   }}

在接口里面定义数据访问层里面的方法:

然后,我们可以在数据层里面的类里面后面来实现这个接口:

using Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using IDAL;
namespace DAL
{    public class ClassDAL:IClassDAL
   {        
    /// <summary>
/// 获取班级列表数据        
/// </summary>
/// <returns></returns>
public List<ClassEntity> GetList()
       {            
       string sql = "SELECT * FROM dbo.MyClass;";

           DataTable table = SQLHelper.GetDataTable(sql, CommandType.Text);            
           //此处不能直接new一个对象
List<ClassEntity> classListModel = null;            //table不为空
if (table.Rows.Count > 0)
           {                
           //要在这里new ,创建对象
classListModel = new List<ClassEntity>();
               
               ClassEntity model = null;                foreach (DataRow row in table.Rows)
               {
                   model = new ClassEntity();                
                   //加载数据                    
                   LoadEntity(row, model);
                   classListModel.Add(model);
               }

           }            
           return classListModel;

           
       }        
       /// <summary>
/// 加载数据        
/// </summary>
/// <param name="row"></param>
/// <param name="model"></param>
public void LoadEntity(DataRow row, ClassEntity model)
       {            
       if (row["C_ID"] != null)
           {
               model.CID = Convert.ToInt32(row["C_ID"]);
           }            
           if (row["C_Name"] != null)
           {
               model.CName = row["C_Name"].ToString();
           }            
           if (row["C_Descr"] != null)
           {
               model.CDescription = row["C_Descr"].ToString();
           }
       }
   }
}

 

然后在业务层里面,实例化数据访问的类的时候,我们可以这样做:

using DAL;
using Entity;using IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BLL
{    public class ClassBLL
   {        
   //耦合度太高      
   // ClassDAL dal = new ClassDAL();        
   //这种还是有耦合,业务层和数据访问层耦合度太高      
   IClassDAL dal = new ClassDAL();


/// <summary>
/// 获取Class列表        
/// </summary>
/// <returns></returns>
public List<ClassEntity> GetList()
       {            
        return dal.GetList();
       }
   }
}

 

图中代码标橙色的部分就是新的实例化方法:

  IClassDAL dal = new ClassDAL();

可以看出这个方式,虽然较第一种直接实例化数据访问类的方式,进步了一点,但还是没能解决业务层和数据访问层耦合的问题!!!,怎么解决呢?

我们看出,主要在 new ClassDAL();这个部分,这个部分是变化的,所以基于封装变化点,我们还可以继续封装。

再新建一个工厂类:

using DAL;
using IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DALFactory
{    public class DALFactory
   {        
   public static IClassDAL GetClassInstance()
       {            
       return new ClassDAL();
       }
   }
}

工厂类的作用就是,解决对象创建的问题,这里,解决了数据访问层类的创建问题。

这样写之后,我们在业务层就好办了!

using DAL;
using Entity;
using IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BLL
{    public class ClassBLL
   {        
   //耦合度太高      
   // ClassDAL dal = new ClassDAL();        
   //这种还是有耦合,业务层和数据访问层耦合度太高      
   //IClassDAL dal = new ClassDAL();        
   //引入简单工厂模式
       IClassDAL dal = DALFactory.DALFactory.GetClassInstance();        
       /// <summary>
/// 获取Class列表        
/// </summary>
/// <returns></returns>
public List<ClassEntity> GetList()
       {            
        return dal.GetList();
       }
   }
}

这一行代码就实现了,业务层和数据层耦合的问题。



.NET开发,前端设计,信中搜索趣味CSharp或扫描二维码关注


 
趣味CSharp 更多文章 三层架构的之间的引用 在C#中,Json的序列化和反序列化的几种方式总结 MVC学习系列9--控制器接收从视图传递过来的参数 MVC学习系列7--下拉框的联动 MVC学习系列5--Layout布局页和RenderSection的使用
猜您喜欢 Android打包系列——多渠道打包及签名 Android 7.0来的真快,来看看又来了些什么出人意料的东西 十二星座系列之——狮子座,王冠你拿去 踹车轮 极客帮王峰:不要在别人成功的领域打仗,创业要靠对错误的否定去找正确的方向