핵심 인사이트 (3줄 요약)
- 최소 지식의 원칙은 객체가 친구의 친구가 아니라 직접 아는 이웃과만 대화하도록 제한하는 설계 원칙이다.
a.getB().getC().do()같은 긴 체이닝은 내부 구조 의존과 높은 결합도의 대표 신호다.- 캡슐화와 위임을 강화하면 변경 전파 범위를 줄이고 테스트 가능한 객체 협력을 만들 수 있다.
Ⅰ. 개요 및 필요성
최소 지식의 원칙은 "Don't talk to strangers"라는 문장으로 자주 요약된다. 한 객체가 다른 객체의 내부 구조를 지나치게 많이 알수록 작은 구조 변경도 여러 모듈에 연쇄 수정으로 번지기 때문이다. 대규모 시스템일수록 이런 구조 노출은 장애 전파와 회귀 테스트 비용을 빠르게 키운다.
┌────────┐ getOrder() ┌────────┐ getUser() ┌────────┐ getAddr() ┌────────┐
│Client │──────────────▶│Order │───────────────▶│User │───────────────▶│Address │
└────────┘ └────────┘ └────────┘ └────────┘
\___________________________ 구조를 많이 알수록 변경 파급 확대 ___________________________/
따라서 이 원칙의 목적은 메서드 체이닝 자체를 금지하는 데 있지 않다. 핵심은 내부 데이터를 꺼내 와서 판단하게 만들지 말고, 책임을 가진 객체에게 일을 맡기도록 구조를 바꾸는 데 있다.
- 📢 섹션 요약 비유: 친구 서랍 속 지갑 속 카드까지 직접 꺼내 보면, 서랍 위치만 바뀌어도 다시 헤매게 됩니다.
Ⅱ. 아키텍처 및 핵심 원리
최소 지식의 원칙은 객체가 스스로 책임을 수행하도록 위임 경계를 세우는 방식으로 구현된다. 즉 묻고 꺼내 오는 구조보다, 메시지를 보내 일을 시키는 구조가 바람직하다.
┌────────┐ pay() ┌────────┐ delegate ┌──────────┐
│Client │──────────▶│Order │──────────────▶│PaymentSvc│
└────────┘ └────────┘ └──────────┘
│
└── 내부의 Customer·Address·Policy 접근은 Order 내부에 은닉
| 허용되는 대화 상대 | 의미 | 예시 |
|---|---|---|
| 자기 자신 | 객체 자신의 필드와 메서드 활용 | this.validate() |
| 직접 보유한 이웃 | 멤버 필드나 주입받은 의존성에 메시지 전달 | paymentService.pay() |
| 메서드 범위 내 객체 | 파라미터나 내부 생성 객체와 협력 | formatter.format(order) |
이 원칙은 Tell, Don't Ask와 사실상 같은 방향을 바라본다. 상태를 가져와 외부에서 조합하는 대신, 책임이 있는 객체가 자신의 데이터를 기반으로 행동하게 만들어야 느슨한 결합이 유지된다.
- 📢 섹션 요약 비유: 반장이 공책을 돌려보며 이름을 직접 적는 대신, 각자 자기 이름을 쓰게 하면 자리 배치가 바뀌어도 반장은 덜 헷갈립니다.
Ⅲ. 비교 및 연결
| 관점 | 디미터 위반 구조 | 디미터 준수 구조 | 연결 개념 |
|---|---|---|---|
| 호출 방식 | 긴 메서드 체이닝으로 내부 객체를 탐색 | 상위 객체에 메시지를 보내 위임 | Tell, Don't Ask |
| 캡슐화 | 내부 구조가 외부에 노출됨 | 내부 협력이 객체 안에 숨겨짐 | Information Hiding |
| 변경 영향 | 하위 객체 필드 변경이 호출부까지 전파 | 내부 구현만 수정하면 외부 계약은 유지 | Loose Coupling |
| 대표 패턴 | Train Wreck 안티패턴 | Facade, Delegation | 객체지향 책임 분배 |
최소 지식의 원칙은 캡슐화, 퍼사드, DIP와도 자연스럽게 연결된다. 외부에 보여 줄 표면을 단순하게 유지할수록 내부 변경 자유도는 커지고, 그만큼 테스트와 리팩터링이 쉬워진다.
- 📢 섹션 요약 비유: 가게 손님은 계산대만 알면 되고, 창고 선반 배치까지 알 필요는 없습니다.
Ⅳ. 실무 적용 및 기술사 판단
실무에서는 도메인 객체가 다른 객체의 상태를 꺼내 가공하는 서비스 코드, 화면 계층에서 엔티티 내부 구조를 깊게 탐색하는 템플릿 코드, 여러 계층을 한 번에 관통하는 체이닝 호출을 우선 점검해야 한다. 기술사 판단에서는 단순히 점(.) 개수보다도, 변경 시 어느 계층까지 영향이 번지는지를 보는 것이 중요하다.
다만 DTO, 직렬화 모델, 일부 Fluent API는 예외적으로 긴 체이닝을 허용할 수 있다. 이 경우에도 비즈니스 규칙이 실린 객체 협력에는 최소 지식의 원칙을 엄격히 적용해 책임 누수를 막아야 한다.
판단 체크리스트
-
getA().getB().getC()형태의 호출이 비즈니스 핵심 경로에 반복되지 않는가? -
상태 조회 후 외부에서 판단하는 대신, 책임 객체에 행동 메서드를 제공하고 있는가?
-
하위 객체 구조가 바뀌어도 상위 호출부 계약은 유지되는가?
-
엔티티, 서비스, 화면 계층 사이에 불필요한 내부 구조 노출이 없는가?
-
예외적으로 허용한 체이닝이 단순 DTO 탐색인지, 규칙 누수가 있는 설계인지 구분했는가?
-
📢 섹션 요약 비유: 택배를 보내려면 경비실에 맡기면 되지, 아파트 배관실과 전기실 위치까지 알 필요는 없습니다.
Ⅴ. 기대효과 및 결론
최소 지식의 원칙을 지키면 객체 간 계약이 단순해지고, 특정 내부 구조 변경이 외부 모듈에 미치는 충격이 줄어든다. 이는 곧 단위 테스트 단순화, 리팩터링 안전성 향상, 계층 간 책임 분리를 의미한다.
결론적으로 이 원칙은 "도트를 줄이는 요령"이 아니라 "책임을 안으로 모으는 설계 태도"다. 객체가 자기 일을 스스로 하게 만들수록 시스템은 더 느슨하게 연결되고 오래 버틴다.
- 📢 섹션 요약 비유: 집 열쇠를 맡길 때 현관문 열쇠만 주면 되지, 금고 비밀번호까지 다 알려 줄 필요는 없습니다.
📌 관련 개념 맵
- 캡슐화: 내부 구조를 감추고 외부에는 행동만 노출한다.
- Tell, Don't Ask: 데이터를 꺼내기보다 일을 시키는 방식으로 책임을 유지한다.
- Facade: 복잡한 내부 구조 앞에 단순한 진입점을 둔다.
- 느슨한 결합: 변경 전파 범위를 줄이는 핵심 품질 속성이다.
📈 관련 키워드 및 발전 흐름도
객체 내부 구조 노출 증가
│
▼
Train Wreck 코드와 변경 파급 확대
│
▼
최소 지식의 원칙·Tell, Don't Ask 적용
│
▼
위임과 캡슐화 강화
│
▼
느슨한 결합과 리팩터링 용이성 확보
👶 어린이를 위한 3줄 비유 설명
- 친구 가방 안에서 필통 안 연필까지 직접 찾으면 친구 물건 배치가 바뀔 때마다 다시 헤매요.
- 그냥 친구에게 "연필 빌려 줘"라고 말하면 친구가 알아서 꺼내 줘요.
- 최소 지식의 원칙은 남의 속을 뒤지지 말고 필요한 일만 부탁하라고 알려 줘요.