2014-04-10 5 views
2

나는 누군가가 나를 demeter의 법칙을 설명하는 것을 도울 수 있기를 바라고있다. 만약 내가 추측하고있는 클래스가 집계 루트이고 그 안에 자식 클래스의 컬렉션이 있다면 집계 루트를 통해 액세스하여 그 자식 클래스의 속성을 업데이트하는 것은 불법입니까?Demeter confusion의 법칙

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 
} 

내가 먼저 회사의 클래스에 액세스가 같은과 데메테르의 법을 위반하는 것입니다 클라이언트가 있다고 할 수 있습니다.

Employee e = aCompany.Employees.Where(e => e.Id == 1).Single(); 
e.LastName = "MarriedName"; 

또는

이 항상 클라이언트

aCompany.UpdateEmployeeLastName(1, "Marriedname"); 

두 번째는 더 나은 것 같다에서 회사

public class Company 
{ 
    public UpdateEmployeeLastName(int employeeId, string newName) 
    { 
     Employee e = Employees.Where(e => e.Id == employeeId).Single(); 
     e.LastName = newName; 
    } 
} 

에 위임해야하지만, 클라이언트가 ID를 알고하는 데에 문제가 있나요 업데이트하려는 직원의

중첩 된 집계가 여러 개있는 경우 복잡해지기 시작한 것처럼 보입니다.

감사합니다.

답변

5

두 번째 옵션은 Demeter Law의 목표입니다.

Demeter의 법칙은 기본적으로 "오직 당신이 알고있는 것에 이야기하십시오."첫 번째 시나리오에있는 "클라이언트"가 실제로 직원들에 대해 전혀 알지 못한다고 말합니다. 그것은 Company에 대해 알고 있지만 내부에있는 Company의 복잡성에 대해서는 알지 못합니다.

Company으로 위임하면 클라이언트에서이 기능의 특정 인스턴스를 각각 변경하지 않고도 직원의 업데이트 방법을 유연하게 변경할 수 있습니다. 당신은 단지 Active 직원들이 이름을 가질 수 있다는 결정 어느 날 변경 한 경우, 당신은이에 옵션을 하나의 모든 인스턴스를 갱신해야합니다 : Company에 그것을 포장

Employee e = aCompany.Employees.Where(e => e.Id == 1 && e.IsActive).Single(); 
//              ^^^^ active flag 
e.LastName = "MarriedName"; 

향후 다루기이 훨씬 좋네요한다 (Demeter의 법칙을 따르려는 시도와 상관없이).

두 번째 버전은 더 좋지만 클라이언트가 업데이트하려는 직원의 ID를 알아야하는 데 문제가 있습니까?

두 사례 모두 직원의 ID를 알고 있으므로 어떤 의미인지 확실하지 않습니다. Aggregate를 통해 정보를 전달할 때 코드를 사용하여 ID를 인식하는 것은 매우 일반적입니다.

+0

감사합니다. 내 생각을 증명할 누군가가 필요하다고 생각해. :) – mageets