Law of Demeter
Law of Demeter(데메테르의 법칙) 는 " 최소 지식 원칙 (Principle of Least Knowledge)" 이라고도 불리며, 소프트웨어의 각 모듈이나 객체가 자신과 밀접하게 연관된 객체와만 상호작용해야 한다는 설계 지침이다. 이 원칙은 객체 간 불필요한 의존성과 결합도를 줄여 시스템의 유연성, 유지보수성, 테스트 용이성을 높인다. 대표적으로 “A.getB().getC().doSomething()” 과 같은 체이닝 호출을 지양하고, 중간 객체의 책임을 명확히 분리하는 방식으로 적용된다. 실무에서는 Facade, Service Layer, DTO, 의존성 주입 등 다양한 패턴과 기법으로 활용된다.
핵심 개념
Law of Demeter (디미터 법칙) 또는 Principle of Least Knowledge (최소 지식의 원칙) 는 객체지향 프로그래밍에서 객체 간의 상호작용을 제한하여 느슨한 결합 (Loose Coupling) 을 달성하는 설계 원칙이다.
핵심 철학:
- 객체는 자신의 직접적인 " 친구 " 들과만 대화해야 함
- " 낯선 사람 " 과는 대화하지 말아야 함
- 다른 객체의 내부 구조나 속성에 대해 최소한만 가정해야 함
핵심 규칙: 한 메서드는 다음 객체에만 메시지를 보낼 수 있다:
- 자기 자신 (this)
- 메서드 인자 (argument)
- 자신이 생성한 객체
- 자신의 인스턴스 변수
목적 및 필요성
- 결합도 감소: 컴포넌트 간 상호의존성 최소화
- 유지보수성 향상: 변경 시 영향 범위 제한
- 캡슐화 강화: 객체의 내부 구현 은닉
- 적응성 증대: 요구사항 변경에 대한 유연한 대응
- 정보 숨김: 불필요한 세부사항 노출 방지
주요 기능 및 역할
- 객체 간 직접적인 상호작용만 허용해 의존성 최소화
- 정보 은닉 (캡슐화) 강화
- 시스템의 안정성 및 유연성 향상
특징
- 느슨한 결합 (Loose Coupling) 지향
- 정보 은닉 (Information Hiding) 강조
- 유지보수성, 확장성, 테스트 용이성 향상
핵심 원칙 및 주요 원리
- " 친구의 친구와는 대화하지 않는다 (Only talk to your immediate friends)".
- 객체의 메서드는 다음과 같은 객체의 메서드만 호출해야 한다:
- 자기 자신의 메서드
- 메서드의 매개변수로 전달된 객체의 메서드
- 자기 자신의 필드로 선언된 객체의 메서드
- 메서드 내에서 생성된 객체의 메서드
- 객체 체이닝 (Chained Calls) 지양
flowchart TD A[Object A] -->|has| B[Object B] B -->|has| C[Object C] A -.->|"X (위반)"| C A -->|"O (준수)"| B
세 가지 핵심 권고사항:
- 각 단위는 다른 단위에 대해 제한된 지식만 가져야 함
- 각 단위는 친구들과만 대화해야 함
- 직접적인 친구들과만 대화해야 함
형식적 정의: 클래스 C 의 메서드 M 은 다음 유형의 객체 메서드만 호출할 수 있다:
- M 의 인수 객체들 (C 자신 포함)
- C 의 인스턴스 변수 클래스들
- M 에 의해 생성된 객체들
- 전역 변수 및 C 의 직접적인 구성 요소 객체들
캡슐화 메커니즘:
flowchart LR subgraph "Law of Demeter 준수" A1[Object A] -->|"명령/위임"| B1[Object B] B1 -->|"내부 처리"| C1[Object C] end subgraph "Law of Demeter 위반" A2[Object A] -->|"직접 접근"| B2[Object B] A2 -.->|"체이닝 접근"| C2[Object C] B2 --> C2 end
구현 기법
기법 | 정의/구성 | 목적 | 실제 예시 (시스템/시나리오) |
---|---|---|---|
위임 (Delegation) | 중간 객체에 기능 위임 | 결합도 감소 | Car 가 Engine 에 start() 위임 |
Facade 패턴 | 복잡한 내부 구조 감춤 | 단순화, 은닉 | Service Layer, API Facade |
DTO(Data Transfer Object) | 데이터 전달만 담당 | 정보 은닉, 결합도 감소 | API 응답 객체, DB 전송 객체 |
의존성 주입 (DI) | 외부에서 객체 주입 | 결합도 최소화 | Spring DI, 생성자 주입 등 |
위임자 메서드 (Delegate Methods)
정의: 내부 객체의 기능을 직접 노출하지 않고 래퍼 메서드를 통해 접근
구성: 공개 메서드 → 내부 객체의 비공개 메서드 호출
목적: 내부 구조 은닉과 인터페이스 안정성 확보
|
|
명령 패턴 (Command Pattern)
정의: 데이터를 요청하는 대신 수행할 행동을 명령
구성: 명령 객체 → 수신자 객체의 메서드 실행
목적: Tell Don’t Ask 원칙 구현
|
|
인터페이스 분리 (Interface Segregation)
정의: 넓은 인터페이스를 좁고 집중된 인터페이스로 분리
구성: 다중 특화 인터페이스 → 단일 책임 구현
목적: 불필요한 의존성 제거
의존성 주입 (Dependency Injection)
정의: 필요한 객체를 외부에서 주입받아 직접 참조
구성: 생성자/세터 주입 → 직접 의존성 확보
목적: 간접적 의존성 제거
장점과 단점
구분 | 항목 | 설명 |
---|---|---|
✅ 장점 | 유지보수성 향상 | 객체 간 느슨한 결합으로 변경 시 영향 범위 최소화 |
캡슐화 강화 | 내부 구현 세부사항 은닉으로 안정적인 인터페이스 제공 | |
테스트 용이성 | 모킹과 스텁 생성이 쉬워져 단위 테스트 작성 용이 | |
재사용성 증대 | 독립적인 컴포넌트로 다른 컨텍스트에서 재사용 가능 | |
병렬 개발 가능 | 인터페이스만 정의되면 독립적으로 개발 진행 가능 | |
⚠ 단점 | 래퍼 메서드 증가 | 위임을 위한 추가 메서드들로 인한 코드량 증가 |
성능 오버헤드 | 추가적인 메서드 호출로 인한 시간/공간 비용 발생 | |
과도한 추상화 위험 | 지나친 래퍼로 인해 실제 로직 파악이 어려워질 수 있음 | |
넓은 인터페이스 위험 | 잘못 적용 시 클래스가 과도하게 많은 메서드를 노출할 수 있음 |
도전 과제
도전 과제 | 설명 | 해결책 |
---|---|---|
성능 vs 설계 품질의 균형 | 래퍼 메서드나 위임 객체가 많아질수록 호출 비용 증가 가능성 있음 | 핫스팟 분석 후 선택적 적용, JIT/컴파일러 최적화 활용 |
과도한 래퍼 메서드 | 모든 접근을 위임할 경우 코드 양 증가 및 유지보수 복잡성 초래 | 핵심 도메인 로직 중심으로 적용, 실용적 접근 지향 |
기존 코드베이스 적용 | 레거시 시스템에 일괄 적용 어려움, 영향 범위 넓음 | 단계적 리팩토링, Bounded Context 단위로 분리 적용 |
일관되지 않은 팀 해석과 구현 | 개발자마다 LoD 해석 및 구현 방식 상이 | 코딩 가이드라인 정립, 코드 리뷰 문화 정착 |
과도한 캡슐화와 설계 복잡도 증가 | 지나친 위임으로 설계가 오히려 난해해지는 경우 | 위임 수준 조절, 퍼사드 (Facade) 패턴이나 도메인 전용 메서드 사용 |
자동화 한계 | 위임 메서드 수동 작성 시 생산성 저하 | IDE 템플릿/생성 도구, Lombok, CodeGen 등 자동화 도구 활용 |
분류에 따른 종류 및 유형
분류 기준 | 항목 | 설명 |
---|---|---|
적용 범위 | 메서드 레벨 | 한 메서드 내에서의 객체 접근을 최소화 (직접 소유 객체만 접근) |
클래스 레벨 | 클래스 간 상호작용에서 중간 객체 체인을 제한하는 설계 | |
패키지/모듈 레벨 | 패키지/모듈 간 의존성을 최소화하고 중재 계층을 둔 구조 | |
엄격성 수준 | Classic LoD | 모든 객체 접근을 일점 (one-dot) 규칙에 따라 제한하는 전통적인 접근 방식 |
Pragmatic LoD | 실용성을 고려해 일부 예외를 허용하며 핵심 도메인에 집중하는 접근 방식 | |
Contextual LoD | 레거시 시스템, 서드파티 API 등 컨텍스트에 따라 제한적으로 적용하는 방식 | |
구현 방식 | 위임 기반 | 객체 접근을 직접 하지 않고 위임 메서드 (Facade/Service 등) 를 통해 우회 접근 |
인터페이스 기반 | 구체 구현이 아닌 추상화 계층 (인터페이스, 추상 클래스) 을 통한 결합도 완화 | |
의존성 주입 (DI) 기반 | DI 컨테이너를 활용해 간접적으로 의존성 주입, 테스트 용이성과 결합도 개선 | |
사용 사례 유형 | Fluent LoD | 빌더 패턴, DSL 등 메서드 체이닝 구조에서 LoD 원칙을 흐름 유지와 조화롭게 적용 |
실무 적용 예시
적용 영역 | 적용 방법/예시 | 효과 |
---|---|---|
도메인 모델 | 중첩 객체 직접 접근 금지, 위임 활용 | 결합도 감소, 유지보수성 향상 |
서비스 레이어 | Facade 패턴 적용 | 내부 구조 은닉, 단순화 |
API 설계 | DTO 활용, 체이닝 호출 금지 | 정보 은닉, 확장성 강화 |
의존성 관리 | DI 로 객체 주입 | 결합도 최소화, 테스트 용이 |
활용 사례
사례 1: 전자상거래 주문 처리 시스템
시나리오: 온라인 쇼핑몰에서 주문 처리 과정에 Law of Demeter 적용
시스템 구성:
graph TB subgraph "Order Processing System" OC[Order Controller] OS[Order Service] O[Order] C[Customer] P[Payment] I[Inventory] S[Shipping] end OC -->|"processOrder(orderData)"| OS OS -->|"createOrder()"| O OS -->|"validatePayment()"| P OS -->|"checkInventory()"| I OS -->|"arrangeShipping()"| S O -->|"calculateTotal()"| O O -->|"validateCustomer()"| C
Law of Demeter 위반 사례:
|
|
Law of Demeter 준수 개선안:
|
|
시스템 구성 다이어그램:
sequenceDiagram participant Controller participant OrderService participant Order participant Customer participant Payment participant Inventory Controller->>OrderService: processOrder(data) OrderService->>Order: createOrder() Order->>Customer: validateForOrder() Customer-->>Order: validation result Order->>Payment: processPayment() Payment-->>Order: payment result Order->>Inventory: reserveItems() Inventory-->>Order: reservation result Order-->>OrderService: order summary OrderService-->>Controller: process result
Workflow:
- 주문 접수: Controller 가 OrderService 에 주문 처리 요청
- 주문 생성: OrderService 가 Order 객체 생성 및 초기화
- 고객 검증: Order 가 Customer 에게 주문 자격 검증 위임
- 결제 처리: Order 가 Payment 에게 결제 처리 위임
- 재고 확인: Order 가 Inventory 에게 재고 확보 위임
- 배송 준비: Order 가 Shipping 에게 배송 준비 위임
- 결과 반환: 각 단계의 결과를 Controller 에 전달
각 컴포넌트의 역할:
- Order: 주문 프로세스 전체 조율 및 상태 관리
- Customer: 고객 정보 관리 및 자격 검증
- Payment: 결제 수단 관리 및 결제 처리
- Inventory: 재고 관리 및 예약 처리
- Shipping: 배송지 관리 및 배송 일정 수립
사례 2: 전자상거래 시스템에서의 Law of Demeter 적용
시나리오: 전자상거래 플랫폼에서 주문 처리 (Checkout) 를 담당하는 OrderService
클래스가 Customer
, Cart
, Payment
, Shipping
등의 도메인 객체와 상호작용함.
문제 발생 전:
|
|
➡ Law of Demeter 위반 (너무 많은 체이닝)
리팩토링 후:
|
|
시스템 구성:
classDiagram class OrderService { +checkout() } class Customer { +describeCartItems() } class Cart { +getItems() } class Item { +getProduct() } class Product { +getName() } OrderService --> Customer : uses Customer --> Cart : owns Cart --> Item : contains Item --> Product : references
Workflow 다이어그램:
sequenceDiagram participant OrderService participant Customer participant Cart participant Item participant Product OrderService->>Customer: describeCartItems() Customer->>Cart: getItems() Cart->>Item: 각 아이템 반환 Item->>Product: getProduct() Product-->>Item: 이름 반환
담당 역할:
클래스 | 역할 설명 |
---|---|
OrderService | 주문 처리 및 흐름 제어 |
Customer | 고객 정보 및 행위 책임 주체 |
Cart | 장바구니 항목 관리 |
Item | 개별 상품 항목 |
Product | 상품 정보 보유 객체 |
실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점
구분 | 고려사항 | 설명 | 권장사항 |
---|---|---|---|
설계 원칙 | 객체 간 책임 분리 | 각 객체는 자신의 책임만 수행 | 단일 책임 원칙 (SRP) 및 명확한 도메인 경계 설정 |
위임 구조 | 위임 메서드의 적절한 사용 | 불필요한 래퍼 메서드로 인한 복잡도 증가 방지 | 핵심 로직 위주로 적용, 자동화 도구 활용 |
패턴 활용 | 설계 단순화 패턴 적용 | 구조를 단순화하기 위한 패턴의 활용 | Facade, Service Layer, Adapter 패턴 적절히 활용 |
테스트 전략 | Mock/Stub 구조의 유지 관리 | 위임 구조가 복잡해질 경우 테스트 설계가 어려워짐 | 인터페이스 기반 설계 및 테스트용 추상화 적용 |
구현 실용성 | 과도한 캡슐화 및 분리의 부작용 방지 | 지나치게 분리하면 가독성/유지보수성 저하 | 실용적 캡슐화와 책임 위임의 균형 유지 |
성능 측면 | 메서드 호출 오버헤드 | 위임 호출이 누적되면 성능 저하 요인 | 프로파일링 및 핫스팟 분석을 통한 선별적 최적화 |
유지보수 | 변경에 대한 영향도 고려 | 위임 구조는 구조 변경 시 영향도가 넓어질 수 있음 | 인터페이스 변경 시 버전 관리, 점진적 리팩토링 적용 |
팀 협업/문화 | 일관된 LoD 적용 기준 | 개발자마다 LoD 해석이 달라질 수 있음 | 코딩 컨벤션, 코드 리뷰 기준에 LoD 포함 |
최적화하기 위한 고려사항 및 주의할 점
구분 | 고려사항 | 설명 | 권장사항 |
---|---|---|---|
메모리 사용량 | 객체 수 증가 | 위임 및 계층 분리로 인해 객체가 많이 생성될 수 있음 | 객체 풀링 (Object Pooling), 경량 객체 패턴 적용 |
메서드 호출 수 | 호출 체인 과다 | 메서드 체인이 깊어질수록 성능 저하 우려 | 필요 시 직접 접근 허용, 호출 최소화 |
위임 오버헤드 | 과도한 위임 구조 | 불필요한 래퍼 메서드 증가 → CPU 자원 낭비 | 정적 분석 도구 활용, 위임 최소화 |
실행 시간 최적화 | 핫패스 성능 저하 우려 | 위임 로직이 자주 실행되는 경로에 존재할 경우 성능 저하 가능 | 프로파일링으로 핫패스 식별, 선택적 최적화 |
캐싱 전략 | 반복 연산 결과 재사용 필요성 | 위임 호출 결과가 동일할 경우 불필요한 재계산 | 메모이제이션 (Memoization) 적용 |
컴파일러 최적화 | JIT 인라이닝 최적화 유도 가능성 | 메서드 분리가 적절하면 컴파일러 인라이닝 가능 | 프로파일 기반 최적화 (PGO: Profile-Guided Optimization) 적용 |
네트워크 통신 | 원격 객체 접근에 따른 비용 증가 | 마이크로서비스 또는 원격 객체 간 호출 시 오버헤드 발생 | 비동기 호출, 배치 처리 적용 |
데이터베이스 접근 | 위임 구조로 인해 N+1 문제 발생 가능 | 객체 그래프 탐색 시 반복 쿼리 발생 | 지연 로딩 (Lazy Loading), 배치 로딩 (Batch Fetching) 전략 |
자동화 도구 활용 | 생산성 및 일관성 향상 | 위임 메서드 반복 작성의 생산성 저하 | IDE 플러그인, 코드 생성기 도입 |
리팩토링 전략 | 복잡도 감소와 성능 균형 필요 | 위임으로 인한 계층 구조가 오히려 복잡성을 증가시킬 수 있음 | 주기적 리팩토링 및 계층 간소화 |
주제와 관련하여 주목할 내용
분류 | 항목 | 설명 |
---|---|---|
설계 원칙 | 최소 지식 원칙 (Least Knowledge) | 객체는 자신과 직접 관련된 객체와만 상호작용해야 한다는 원칙 |
느슨한 결합 (Loose Coupling) | 결합도를 낮추고 모듈 간 독립성 향상을 통해 유지보수성 확보 | |
정보 은닉 (Encapsulation) | 객체 내부 상태나 구현을 외부에 노출하지 않도록 보호 | |
Tell, Don’t Ask | 데이터를 요청하지 말고 필요한 작업을 요청하라는 메시지 중심 접근법 | |
단일 책임 원칙 (SRP) | 객체가 하나의 책임만 가지도록 하여 자연스럽게 LoD 준수 | |
의존성 역전 원칙 (DIP) | 고수준 모듈이 저수준 구현이 아닌 추상에 의존하도록 설계 | |
디자인 패턴 | Delegation Pattern | 책임을 다른 객체에 위임하는 방식 |
Facade Pattern | 복잡한 내부 구조를 단순화하여 외부에 단일 인터페이스 제공 | |
Mediator Pattern | 객체 간 상호작용을 중앙 집중화하여 직접 결합 제거 | |
Command Pattern | 요청을 객체로 캡슐화하고 위임을 통해 실행 | |
아키텍처 패턴 | Layered Architecture | 각 계층이 하위 계층에만 의존하는 구조 |
Hexagonal Architecture | 포트/어댑터 구조로 외부 의존성 분리 | |
Clean Architecture | 핵심 도메인을 외부 요소로부터 격리하여 LoD 원칙을 체계적으로 구현 | |
프로그래밍 기법 | 위임 메서드 | 중간 객체로의 책임 전가를 통해 직접 접근 방지 |
인터페이스 분리 (ISP) | 필요한 기능만 제공하여 불필요한 의존성 제거 | |
의존성 주입 (DI) | 직접 생성 대신 외부에서 주입하여 결합도 낮춤 | |
리팩토링 전략 | 중간자 제거 (Remove Middleman) | 불필요한 중간 객체를 제거하여 과도한 위임 방지 |
품질 메트릭스 | RFC (Response For Class) | 클래스가 노출하는 응답 수 측정으로 LoD 위반 여부 간접 판단 |
WMC (Weighted Methods per Class) | 클래스의 복잡도와 결합 정도를 측정 | |
Coupling Metrics | 모듈 간 결합도 수치화 | |
유틸리티/도구 | 리팩토링 도구 | IntelliJ, SonarQube 등에서 LoD 위반 코드 자동 분석 가능 |
보조 패러다임 | AOP (Aspect-Oriented Programming) | 횡단 관심사를 분리하여 직접 호출 없이도 기능 주입 가능 |
하위 주제로 분류한 추가 학습 내용
카테고리 | 주제 | 설명 |
---|---|---|
설계 원칙 | Principle of Least Knowledge | 객체는 필요한 최소한의 객체와만 상호작용해야 한다는 LoD 의 핵심 개념 |
캡슐화 (Encapsulation) | 내부 구현을 숨기고 명확한 인터페이스만 제공 | |
정보 은닉 (Information Hiding) | 불필요한 정보 노출을 제한함으로써 변경에 유연한 구조 유지 | |
결합도와 응집도 (Coupling & Cohesion) | 모듈 간 관계 최적화를 위한 이론적 기반 | |
Single Responsibility Principle | 객체가 한 가지 책임만 갖도록 하여 자연스럽게 LoD 준수 | |
디자인 패턴 | Delegation Pattern | 책임을 다른 객체에 위임함으로써 직접 접근 제거 |
Facade Pattern | 복잡한 내부 구현을 감추는 단순한 외부 인터페이스 제공 | |
Service Layer | 도메인 로직과 애플리케이션 로직 분리 | |
DTO (Data Transfer Object) | 데이터 전송용 단순 객체로, 의존성 명확화 | |
소프트웨어 아키텍처 | 마이크로서비스와 LoD | 독립적 서비스 간 통신 시 LoD 적용 고려사항 |
이벤트 기반 아키텍처 | 비동기 메시징을 활용한 느슨한 결합 구현 | |
DDD 와 경계 컨텍스트 | 객체 간 경계 명확화를 통해 LoD 실현 | |
리팩토링 | 체이닝 호출 제거 | 메서드 체이닝 등 직접 참조 패턴을 위임 방식으로 개선 |
레거시 코드 리팩토링 | 기존 시스템에 LoD 원칙을 점진적으로 적용하는 방법 | |
테스트 전략 | Mocking / Stubbing | LoD 구조에서의 단위 테스트 구성법 |
테스트 최적화 | 위임 구조에 적합한 테스트 케이스 분리 | |
성능 최적화 | 위임에 따른 오버헤드 최소화 | LoD 적용이 성능에 미치는 영향 고려 및 최적화 전략 |
도구 및 프레임워크 | Spring Framework 와 DI | 의존성 주입 기반으로 LoD 적용 |
.NET Core DI | .NET 환경에서의 DI 컨테이너 활용 | |
정적 분석 도구 (Static Analysis Tools) | IntelliJ, SonarQube 등을 통한 LoD 위반 코드 탐지 및 개선 지원 |
관련 분야와 추가 학습 내용
카테고리 | 주제 | 설명 |
---|---|---|
소프트웨어 아키텍처 | Clean Architecture | 핵심 도메인 보호를 위한 계층화된 설계 구조 |
Hexagonal Architecture | 포트와 어댑터로 외부 의존성을 격리하여 느슨한 결합 실현 | |
Architecture Decision Records | 아키텍처 설계 시 LoD 관련 고려사항을 기록하고 공유 | |
계층화 설계 | LoD 원칙을 각 계층 간 명확한 책임 분리로 구현 | |
객체지향 설계 원칙 | SOLID Principles | LoD 와 상호 보완적인 SRP, DIP 등의 설계 원칙 |
결합도/응집도 (Coupling/Cohesion) | LoD 가 결합도 감소, 응집도 증가에 기여 | |
함수형 프로그래밍 | 함수 합성 (Functional Composition) | 메서드 체이닝 없이도 복잡한 처리를 구성하는 안전한 방식 |
불변 객체 (Immutable Objects) | 상태 공유 없이 안전하게 객체 전달 가능 | |
모나드 패턴 (Monadic Design) | 부작용 없는 체이닝 구조로 LoD 보완 | |
디자인 패턴 | Mediator Pattern | 객체 간 직접 의존을 중재하여 결합도 감소 |
Delegation Pattern | 책임을 외부 객체에 위임하여 직접 접근 제한 | |
Facade Pattern | 복잡한 내부 구현을 감춘 단순한 인터페이스 제공 | |
분산 시스템 | Service Mesh Architecture | 마이크로서비스 간 통신을 인프라 수준에서 제어 |
API Gateway Pattern | 클라이언트와 마이크로서비스 사이 추상화 계층 구성 | |
Event Sourcing | 도메인 이벤트 기반으로 시스템 상태 추적 | |
성능 엔지니어링 | 메모리 관리 (Memory Management) | 위임 구조에서 불필요한 객체 생성을 방지 |
컴파일러 최적화 | 위임 메서드 호출이 성능에 미치는 영향과 인라이닝 최적화 활용 | |
프로파일링 & 모니터링 | 런타임 성능을 정량적으로 측정하고 병목을 분석 | |
코드 품질 관리 | 정적 분석 도구 | LoD 위반 여부를 자동 분석 (SonarQube, IntelliJ 등) |
프로그램 기법 | Law of Demeter for Functions | LoD 개념을 메서드/함수 레벨에서도 확장 적용 |
용어 정리
용어 | 설명 |
---|---|
Law of Demeter (데메테르의 법칙) | 객체는 직접적으로 연관된 객체와만 상호작용해야 한다는 객체지향 설계 원칙 |
Principle of Least Knowledge | Law of Demeter 의 다른 명칭으로, 객체 간 상호작용을 최소화해야 한다는 설계 원칙 |
Delegation (위임) | 특정 작업의 책임을 다른 객체에게 넘기는 설계 기법 |
Delegation Method (위임 메서드) | 다른 객체의 기능을 호출하는 중간 메서드로, 결합도를 낮추는 수단 |
Facade Pattern (퍼사드 패턴) | 복잡한 내부 시스템을 단순한 인터페이스로 감추는 디자인 패턴 |
DTO (Data Transfer Object) | 계층 간 데이터 전달만을 담당하는 객체로, 부작용 없이 구조화된 데이터 교환 가능 |
Service Layer (서비스 레이어) | 비즈니스 로직을 캡슐화하여 프레젠테이션과 도메인 계층 간의 결합도를 낮추는 구조적 계층 |
Dependency Injection (의존성 주입) | 객체 생성 책임을 외부로 분리하여 결합도를 줄이는 구성 방식 |
Encapsulation (캡슐화) | 객체 내부 구현을 숨기고, 공개된 메서드를 통해서만 상태에 접근하도록 제한하는 원칙 |
Information Hiding (정보 은닉) | 모듈 또는 객체의 내부 세부사항을 외부에서 감추는 설계 원칙 |
Loose Coupling (느슨한 결합) | 컴포넌트 간 의존도를 낮춤으로써 변경 시 영향 범위를 최소화하는 구조 |
Coupling (결합도) | 모듈 간의 의존성 강도를 나타내는 소프트웨어 설계 메트릭 |
Cohesion (응집도) | 모듈 내부 구성 요소들이 얼마나 관련 있는 기능을 수행하는지를 나타내는 메트릭 |
Method Chaining (메서드 체이닝) | 연속적인 메서드 호출로 로직을 구성하는 방식으로, LoD 위반 가능성이 높은 패턴 |
Tell Don’t Ask | 객체에게 필요한 데이터를 꺼내 처리하기보다, 작업을 직접 요청하여 캡슐화를 강화하는 설계 원칙 |
Refactoring (리팩토링) | 외부 동작은 그대로 두고, 코드 구조를 더 나은 형태로 재정비하는 기법 |
RFC (Response For Class) | 클래스가 응답할 수 있는 메서드 수를 나타내는 클래스 복잡도 메트릭 |
WMC (Weighted Methods per Class) | 클래스에 정의된 메서드들의 가중 합을 계산하여 복잡도를 나타내는 메트릭 |
참고 및 출처
공식 문서 및 백그라운드
실무 적용 및 자바 기반 예제
- Law of Demeter in Java - Baeldung
- Law of Demeter in Java – GeeksforGeeks
- The Law of Demeter by Example - Paweł Pluta
- The Law of Demeter by Example - Medium
설계 원칙 설명 및 해설
- Demystifying the Law of Demeter - InfoWorld
- The Genius of the Law of Demeter - DZone
- Understanding the Law of Demeter - Test Double
- Law of Demeter - DevIQ
- Law of Demeter (Principle of Least Knowledge) - DEV Community
- Understanding the Law of Demeter and Design Approaches - LinkedIn
- The Law of Demeter Software Design Principle - Pinte.ro
기타 관련 설계 원칙/도구 참고
- Essential Software Design Principles - Design Gurus
- JetBrains - IntelliJ Structural Search
- SonarQube 공식 문서