인터페이스
- 단일 구현 인터페이스는 보통 따로 만들지 않는다. 가장 큰 이유는 비용인데, 구현체가 하나일 때의 인터페이스는 다른 구현체가 추가될 때 변경될 가능성이 높다.
캡슐화
-
변수를 특정 스코프 내에 두어 변경의 영향을 해당 영역으로 제한할 수 있다.
-
상수는 스코프 바깥에 두는 경우가 종종 있는데, 상수도 해당 변수의 영향 범위를 드러내기 위해 캡슐화하는 것이 좋을까?
-
캡슐화의 장점
- 변수나 함수의 영향 범위를 보다 쉽게 파악할 수 있기 때문에 보다 읽기에도 좋고 코드를 수정하기에도 좋음
- 흩어져 있는 도메인 로직을 모아서 잘못 사용할 수 있는 가능성을 줄여줌
- 요구사항이 바껴서 코드를 변경해야 할 때 보아야 할 곳이 보다 명확함
-
클로저 변수에 이미 중복이라고 응답받은 메일을 보관하고 API 호출을 절약하는 팁 괜찮은듯
- 근데 그 사이에 서버에서 탈퇴가 발생하면 어쩌지?
-
디미터의 법칙
- 객체는 최소한의 지식만을 가져야 한다는 원칙
- 이 법칙은 숨긴 정보가 외부로 노출되지 않는지 점검하는 방법을 제시
user.getName();user.getAddress().getCity().getName()-
getter가 줄줄이 이어진 모습이 기차와 닮아서 열차 전복, 기차 충돌(train wreck) 이라는 단어로 표현하기도 한다.
-
주의: 디미터 법칙은 하나의 . 을 강제하는 규칙이 아니다
- 객체 내부를 반환하는 것이 아니라, 객체 자신을 반환하여 기능을 연속적으로 수행하는 구조(예: Fluent Interface, 빌더 패턴)는 디미터의 법칙을 위반하지 않는 것으로 봅니다
-
-
책에 나온 위반 예시
userManager.getUsers().filter(...)
userManager에게getUsers()로 내부 컬렉션을 꺼낸 뒤, 그 컬렉션에 직접 접근해서 조작userManager의 내부 구조(users배열이 있다는 사실)를 외부에서 알고 의존하게 되는 구조
// userManager가 직접 책임지는 구조
const readAuthorizedUsers = userManager.getReadAuthorizedUsers();
// 혹은
const readAuthorizedUsers = userManager.filterUsers(
(user) => !user.writeAuthorization
);
추가로 user.writeAuthorization 도 주의
(user) => !user.writeAuthorization
이 부분도 user 객체의 내부 프로퍼티를 외부에서 직접 참조하고 있어서 엄격하게 적용하면 이것도 개선 대상
(user) => user.isReadOnly() // user 스스로 판단
결합도와 응집도
함수, 컴포넌트, 그리고 다른 어떤 형태의 코드 묶음이라도 모듈의 성질을 갖추고 있다면 모듈로 활용할 수 있습니다.
- 왜 이 챕터를 설명할 때 모듈을 먼저 언급했을까?
- 결합도와 응집도를 "측정 가능한 기준"으로 쓰려면, 먼저 "무엇을 단위로 측정할 것인가" 를 정의해야 함
- 함수든, 클래스든, 컴포넌트든 — "독립적으로 다룰 수 있는 코드 단위" 라는 개념을 모듈로 추상화하면, 결합도/응집도 논의를 특정 언어나 패러다임에 종속시키지 않고 범용적으로 전개할 수 있음
- 즉, 언어 독립적인 논의를 위한 공통 어휘 확보가 목적으로 보인다는 클로드의 답변
- 하지만 결합도와 응집도가 모듈에서만 지닐 수 있는 속성은 아닌 것 같아서 논리 전개가 와닿지 않았음
응집도를 높이는 데 참고하면 좋은 지침 중 하나는 진실의 원천을 하나만 두는 것입니다.