5. 한 줄에 점은 오직 하나만 사용하라
소트웍스 앤솔로지의 Object Calisthenics 내용을 TypeScript로 적용해봤습니다.
TypeScript에서는 어떤 객체 또는 배열 내 값에 접근할 때 점(.
) 또는 인덱스 접근자([]
)을 사용한다. 이번 규칙은 무수히 많은 .
또는 []
를 통해 객체나 배열 내부 깊게 들어가 속성값을 가져오는 것을 지양하라는 뜻이다. 규칙이 지켜지지 않은 예제를 살펴보자.
디미터의 법칙으로 일컬어지는 이 규칙은 너 자신 또는 1차 관계에 있는 친구에게만 이야기하라라고 비유한다.
cars[i].position
을 살펴보자. 규칙에서 말하듯 .
은 1개라서 문제가 없지 않냐 생각할 수 있지만 이 규칙의 의미는 그런 것이 아니다. cars
라는 배열 객체의 인덱스에 접근하기 위해 1차적으로 [i]
를 사용하고, 2차적으로 .position
을 사용해 그 인덱스에 있는 Car
객체의 값에 접근하고 있기 때문에 문제시 될 수 있는 부분이다. 이렇게 한 줄에 객체 내부 값을 가져오기 위해 체이닝을 하는 것은 극단적으로는 이런 코드를 만들 수 있다.
심지어 이와 유사한 코드가 소스 코드 여러 곳에 산재되어 있다면... 상상만 해도 끔찍하다. 이 무수히 많은 접근자들을 어떻게 더 쉽게 만들 수 있을까?
이런 느낌으로 바꾸면 어떨까? 훨씬 간결한 코드로 변한 것을 알 수 있다. 이렇게 한 줄에 점(.
)(그리고 []
)을 두 개 이상 찍지 말라는 규칙을 지키며 처음 코드를 리팩토링해보자.
단,
class
에서this
를 사용하는 경우와.map
,.reduce
,.forEach
등을 체이닝 하는 배열 함수에 있어서는 이 규칙을 적용하지 않아도 된다고 생각하자. 중첩된 객체의 내부 속성에 직접 접근하는 것을 지양하는 것이 이 규칙의 핵심이다.
다음 방법들을 적용해 이전의 코드보다 가독성이 좋고 잘 추상화된 코드를 만들어봤다.
public
했던 객체의 속성을private
으로 바꿔서 직접 속성에 접근하는 것을 예방하기 (owner
같은 경우set
을 할 수 없게get
만 열어주었다.직접 속성에 접근해 연산하는 대신 다른
Car
을 인자로 받는Car
의 메소드를 만들기Car[]
에 일급 콜렉션을 적용해Car
들을 관리하는 메소드를 모으기for
문을 배열 함수로 바꾸어 체이닝하기
이제 객체나 배열의 구조가 변경되더라도 속성에 직접 접근했었던 모든 부분을 고치지 않아도 되기 때문에 확장에 대해 열려있고, 수정에 대해 닫혀 있는 개방-폐쇄 원칙을 지킬 수 있다.
이렇게 한 줄에 여러 개의 .
과 []
를 두지 않으려 노력하는 것만으로도 코드의 품질을 많이 개선할 수 있다는 것을 알게 되었다.
Last updated