소트웍스 앤솔로지 의 Object Calisthenics 내용을 TypeScript로 적용해봤습니다.
실제로 지키기 제일 어려운 규칙이지만, 높은 응집도와 더 나은 캡슐화를 위해서 이 규칙은 필수다. 규칙 3: 모든 원시값과 문자열을 포장하라 과 같은 맥락으로 이어지는 규칙이다. 왜 인스턴스 변수는 2개 이하로 유지해야할까?
Copy class Car {
constructor (
private ownerFirstName : string ,
private ownerLastName : string ,
private ownerAge : number ,
private position : number
) {}
}
Car
이 인스턴스 변수로 ownerFirstName
, ownerLastName
, ownerAge
, position
을 가지고 있다. 이중에서 Car
와 직접적으로 연관되어 있는 필드는 position
정도 뿐이니, 나머지는 Owner
클래스로 분리해보자.
Copy class Car {
constructor ( private owner : Owner , private position : number ) {}
}
class Owner {
constructor (
private firstName : string ,
private lastName : string ,
private age : number
) {}
}
Car
과 Owner
가 각각 자신에게 필요한 인스턴스 변수들을 가지게 되었다. 그런데 Owner
를 살펴보면, firstName
과 lastName
은 공통적으로 이름에 관련되어있으니, 이를 다시 한 번 분리해줄 수 있다.
Copy class Car {
constructor ( private owner : Owner , private position : number ) {}
}
class Owner {
constructor ( private name : Name , private age : number ) {}
}
class Name {
constructor ( private firstName : string , private lastName : string ) {}
}
클래스가 어느정도 분리가 되었다. 확실히 처음에 비해 클래스가 잘게 나눠지면서 2개 이하의 인스턴스 변수를 적게 가지게 되었고, 각각이 독립적인 역할을 가지게 되었다는 것을 볼 수 있다. 이제 규칙 3: 모든 원시값과 문자열을 포장하라를 생각하며 의미를 가지는 모든 원시값과 문자열을 포장해보자.
Copy class Car {
constructor ( private owner : Owner , private position : Position ) {}
}
class Position {
constructor ( private value : number ) {}
}
class Owner {
constructor ( private name : Name , private age : Age ) {}
}
class Name {
constructor ( private firstName : FirstName , private lastName : LastName ) {}
}
class FirstName {
constructor ( private value : string ) {}
}
class LastName {
constructor ( private value : string ) {}
}
class Age {
constructor ( private value : number ) {}
}
처음 큰 덩어리부터 세부적인 요소까지 의미있는 객체로 만들어줌으로써 (비록 조금 길어졌어도) 응집도를 높이고, 더 나은 수준의 캡슐화를 통해 명시적이고 깨끗한 코드를 만들어보았다.