文章出處
文章列表
前面,復習了簡單三層。可以看出三層的缺點,業務層和數據訪問層耦合在一起了,如果后面我需要在上面擴展的話,就不方便了,比如,現在我只是支持微軟的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(); } } }
這一行代碼就實現了,業務層和數據層耦合的問題。
文章列表
全站熱搜