-
Notifications
You must be signed in to change notification settings - Fork 0
The Law of Demeter(Don't Talk to Strangers)
본 내용은 이해를 위해 간단히 설명한 내용으로
원래 내용과 틀린점이 존재할 수 있습니다.
틀린점이 발견되면 담당자에게 문의남겨주세요.
디미터 혹은 디메테르라 불리는 이 법칙이란.
객체 지향 디자인 원칙중 하나로 "최소 지식 원칙"
결합도가 낮은 설계를 위한 원칙이다.
결합도가 높으면 하나를 수정하면 해당 사항과 관련된 모든곳에서 수정이 일어나야한다.
하지만 결합도가 낮으면 이를 방지할 수 있다.
이를 방지하는 방법중 디미터의 법칙은 메소드 내의 다른 객체/API 등의 호출에 관련된 원칙을 말한다.
디미터 법칙은 "클래스 C의 메서드 f는 다음과 같은 객체의 메서드만 호출해야 한다"고 주장한다.
- 클래스 C
- f가 생성한 객체
- f 인수로 넘어온 객체
- C 인스턴스 변수에 저장된 객체
쉽게 말해서 A가 B를 사용하고 B가 C를 사용할때 A가 C를 알필요가 없다.
간단하게 표현하자면 아래와 같다.
한 모듈이 내부 구현을 알아야하는 다른 모듈들을 최대한 적게 유지한다.
- 클래스 자기 자신의 메소드 또는 인스턴스 변수의 메소드 만 실행 가능하다.
- 메소드의 파라미터로 보내진 객체의 메소드만 실행 가능하다.
- 메소드 또는 인스턴스 변수가 직접 초기화한 객체일때 실행 가능하다.
- 호출을 위해서 메소드 또는 속성으로 같은 클래스 안에서 선언된 객체만 실행 가능하다.
- 싱글턴 같은 전역 객체일때만 실행 가능하다.
디미터 법칙을 못 지킨 형태❌
human.Stomach.IsEmpty()
디미터 법칙을 잘 지킨 형태✅
human.IsHungry()
위 human.Stomach.IsEmpty() 경우
human객체 안에 Stomach객체를 받아서 IsEmpty()를 호출하고 판별하여 반환하는 IsHungry()로 써야 추후 Stomach의 IsEmpty()를 수정하더라도 human까지 수정할 필요가 없어진다.
객체의 내부 구조를 숨기기 위해 사용하는 경우가 아닌경우는 해당 원칙을 따를 필요가 없다고한다. 자료 구조에서는 내부 구조를 노출하기 때문이다.
val myFile:File = mfile.getFile()
val myFilePaht:String = mfile.getFile().getFileAbsolutePath()
디미터 법칙은 경우에 따라서 판별해야한다. 또한 그 판별이 상황마다 다를 수 있으므로 이분법 적으로 생각하지 않아야한다.
기차 충돌 피하기(디미터 법칙 위반)
object.getChild().getContent().getItem().getTitle()
프로그램 순회 경로가 길수록 불안정하기 때문에 위의 방식은 피하도록 한다.
//myService는 인터페이스이고 싱글턴으로 instance를 호출하여 인스턴스로 생성된다.
myService.getInstance()
.requestToMyAPI(...)
/*
위의 경우는 myService는 인터페이스 이고 .getInstance로 인스턴스가 되어 myService가 다른 myService로 변환되고. 이를 둘러싼 캡슐은 유지된다.
그리고 해당 인스턴스의 메소드가 requestToMyAPI()이다.
*/
//또다른 자바8의 IntStream 예제
IntStream.of(1,20,3,40)
.filter(x -> x>10)
.distinct()
.count()
/*
위의 경우도 of,filter,distinct 메소드가 모두 IntStream이라는 클래스의 인스턴스를 반환하여 감싼 캡슐이 유지 된다.
*/