文章出處

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

這一行代碼就實現了,業務層和數據層耦合的問題。

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()