高層模塊不應該依賴底層模塊,兩都都應該依賴抽象
一個三層的Demo
/// <summary>
/// 人員實體類
/// </summary>
class Person
{
public int ID { get; set; }
public string Name { get; set; }
public bool Sex { get; set; }
}
/// <summary>
/// 表示層
/// </summary>
class UI
{
public void Main()
{
ShowPerson();
}
public static void ShowPerson()
{
Console.WriteLine("輸入要查詢的人員ID");
var id = int.Parse(Console.ReadLine());
var bll = new BLL();
var person = bll.FindPerson(id);
Console.WriteLine($"ID:{person.ID},Name:{person.Name},Sex:{(person.Sex ? "男" : "女")}");
}
}
/// <summary>
/// 業務邏輯層
/// </summary>
class BLL
{
public Person FindPerson(int id)
{
var dal = new DAL();
return dal.QueryPersonByID(id);
}
}
/// <summary>
/// 數據訪問層
/// </summary>
class DAL
{
public Person QueryPersonByID(int id)
{
return new Person { ID = id, Name = "張三丰收", Sex = true };
}
}
高層模塊指的是調用方:
UI類ShowPerson方法中bll.FindPerson
BLL類FindPerson方法中dal.QueryPersonByID
底層模塊指的是實現模塊:
BLL類FindPerson()方法
DAL類QueryPersonByID()方法
這是直接用法,爲了降低耦合,響應需求變化,要把這種強依賴切降低,遵照“依賴倒置”,增加抽象層,用抽像層隔離高層和底層模塊,本代碼段中用一個ObjectHub來集中管理實例化過程,如下代碼:
#region 實體類
/// <summary>
/// 人員實體類
/// </summary>
class Person
{
public int ID { get; set; }
public string Name { get; set; }
public bool Sex { get; set; }
}
#endregion
#region 對象倉庫
/// <summary>
/// 對象倉庫
/// </summary>
class ObjectHub
{
public static Dictionary<string, object> Container { get; private set; }
static ObjectHub()
{
//通過這裏來解耦
Container = new Dictionary<string, object>
{
{ nameof(IDAL), new DAL() },
{ nameof(IBLL),new BLL() }
};
}
}
#endregion
#region 表示
/// <summary>
/// 表示層
/// </summary>
class UI
{
static void Main(string[] args)
{
var ui = new UI();
ui.ShowPerson();
}
public void ShowPerson()
{
//依賴業務邏輯層接口
var bll = ObjectHub.Container[nameof(IBLL)] as IBLL;
Console.WriteLine("輸入要查詢的人員ID");
var id = int.Parse(Console.ReadLine());
var person = bll.FindPerson(id);
Console.WriteLine($"ID:{person.ID},Name:{person.Name},Sex:{(person.Sex ? "男" : "女")}");
}
}
#endregion
#region 業務邏輯
/// <summary>
/// 業務邏輯層接口
/// </summary>
interface IBLL
{
Person FindPerson(int id);
}
/// <summary>
/// 業務邏輯層
/// </summary>
class BLL : IBLL
{
public Person FindPerson(int id)
{
//依賴業務邏輯層接口
var dal = ObjectHub.Container[nameof(IDAL)] as IDAL;
return dal.QueryPersonByID(id);
}
}
#endregion
#region 數據訪問
/// <summary>
/// 數據訪問層接口
/// </summary>
interface IDAL
{
Person QueryPersonByID(int id);
}
/// <summary>
/// 數據訪問層
/// </summary>
class DAL : IDAL
{
public Person QueryPersonByID(int id)
{
return new Person { ID = id, Name = "張三丰收", Sex = true };
}
}
#endregion
原來是高層模塊依賴底層模塊,現在依賴倒置,怎麼倒置了呢?個人理解:高層和底層之間出現了一個抽像,高層依賴抽象,按理抽象依賴底層,但這裏恰恰是底層和也依賴抽象,打破了一個依賴鏈,形成一個倒置。