mag*_*ets 2 c# aggregate law-of-demeter
我希望有人可以帮我解释一下demeter法则.如果我有一个我假设的类是聚合根,并且其中有一个子类集合,那么通过聚合根访问它们来更新这些子类的属性是不合法的吗?
例如
public class Company
{
// company has a number of employees
public List<Employee> Employees {get; set;}
}
public class Employee
{
// each employee has a lastname
public int Id {get; set;}
public string LastName {get; set;}
// other properties of employee
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个客户端正在访问公司类,首先它会违反demeter法则.
Employee e = aCompany.Employees.Where(e => e.Id == 1).Single();
e.LastName = "MarriedName";
Run Code Online (Sandbox Code Playgroud)
或者这应该总是委托给公司
public class Company
{
public UpdateEmployeeLastName(int employeeId, string newName)
{
Employee e = Employees.Where(e => e.Id == employeeId).Single();
e.LastName = newName;
}
}
Run Code Online (Sandbox Code Playgroud)
在客户端
aCompany.UpdateEmployeeLastName(1, "Marriedname");
Run Code Online (Sandbox Code Playgroud)
第二个似乎更好但是客户端必须知道它想要更新的员工的ID有什么问题吗?
这似乎可能会开始变得复杂,你有许多嵌套聚合.
谢谢
您的第二个选择是德米特法则的目标.
因为德米特定律基本上只是说"只谈你所知道的事情"......无论"客户"在第一个场景中是什么,实际上根本不了解员工.它知道Company...而不是Company内部的复杂性.
委派Company给您可以灵活地更改员工的更新方式,而无需从客户端更改此功能的每个特定实例.如果有一天您决定只有Active员工可以更改其名称,那么您必须将选项1的每个实例更新为:
Employee e = aCompany.Employees.Where(e => e.Id == 1 && e.IsActive).Single();
// ^^^^ active flag
e.LastName = "MarriedName";
Run Code Online (Sandbox Code Playgroud)
把它包装起来Company使得将来更好地处理(无论是否试图遵循得墨忒耳定律).
第二个似乎更好但是客户端必须知道它想要更新的员工的ID有什么问题吗?
你的两个例子都知道员工的ID ......所以我不确定你的意思.在通过Aggregate传递信息时,消耗代码以识别ID是很常见的.
| 归档时间: |
|
| 查看次数: |
388 次 |
| 最近记录: |