- 單一職責原則(Single Reponsibility Principle,SRP)
- 里氏替換原則(Liskov Substitution Principle,LSP)
- 依賴倒置原則(Dependence Inversion Principle,DIP)
- 接口隔離原則(Interface Segregation Principe,ISP)
- 迪米特法則(Law of Demeter,LOD)
- 開閉原則(Open Closed Principle,OCP)
迪米特法則(LOD)
Law of Demeter,簡稱:LOD。
一個對象應儘可能少的瞭解其它對象
問題由來:類與類之間的關係越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。
解決方案:儘量降低類與類之間的耦合。
迪米特法則又叫最少知道原則(Least Knowledge Principle,LKP),通俗的來講,就是一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類來說,無論邏輯多麼複雜,都儘量的將邏輯封裝在類的內部,對外除了提供的public方法,不對外泄漏任何信息。
簡單的定義:只與直接的朋友通信。
直接的朋友:每個對象都會與其他對象有耦合關係,只要兩個對象之間有耦合關係,我們就說這兩個對象之間是朋友關係。耦合的方式很多,依賴、關聯、組合、聚合等。
其中,我們稱出現成員變量、方法參數、方法返回值中的類爲直接的朋友,而出現在局部變量中的類則不是直接的朋友。也就是說,陌生的類最好不要作爲局部變量的形式出現在類的內部。
舉個例子
分別定義學校,班級,學生三個角色,School通過Command方法讓Class管理班級學生,Class通過Manage方法管理學生。
代碼如下:
學生類:包含兩個公共屬性、一個公有 Learn() 方法和兩個私有方法(Lesson()、Homework()),如下:
/// <summary>
/// 學生
/// </summary>
public class Student
{
public int Id { get; set; }
public string StudentName { get; set; }
public void Learn()
{
this.Lesson();
this.Homework();
}
/// <summary>
/// 聽課
/// 內部方法,儘量減少公開的方法和屬性
/// </summary>
private void Lesson()
{
Console.WriteLine(" {0} Lesson {1} ", this.GetType().Name, this.StudentName);
}
/// <summary>
/// 寫作業
/// </summary>
private void Homework()
{
Console.WriteLine(" {0} Homework {1} ", this.GetType().Name, this.StudentName);
}
}
班級類:只與直接的朋友 Student 通信,一個類只和一個朋友說話。
/// <summary>
/// 班級
/// </summary>
public class Class
{
public int Id { get; set; }
public string ClassName { get; set; }
public List<Student> StudentList { get; set; }
public void Manage()
{
foreach (Student s in this.StudentList)
{
s.Learn();
}
}
}
學校類:同理,一個類只和一個朋友說話,這裏只與班級Class通信。
/// <summary>
/// 學校
/// </summary>
public class School
{
public int Id { get; set; }
public string SchoolName { get; set; }
public List<Class> ClassList { get; set; }
public void Command()
{
Console.WriteLine("Command {0}", this.GetType().Name);
foreach (Class c in this.ClassList)
{
c.Manage();//班級自己管理學生 1
Console.WriteLine(" {0}Manage {1} ", c.GetType().Name, c.ClassName);
}
}
}
場景調用:
class Program
{
static void Main(string[] args)
{
try
{
School school = new School()
{
SchoolName = "愛新覺羅氏葬愛家族皇家學院",
ClassList = new List<Class>()
{
new Class()
{
ClassName = "學前班",
StudentList = new List<Student>()
{
new Student()
{
StudentName = "梵高"
}
}
}
}
}
school.Command();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.Read();
}
}