8. 인스턴스 변수는 2개 이하로 유지하라

소트웍스 앤솔로지Object Calisthenics 내용을 TypeScript로 적용해봤습니다.

실제로 지키기 제일 어려운 규칙이지만, 높은 응집도와 더 나은 캡슐화를 위해서 이 규칙은 필수다. 규칙 3: 모든 원시값과 문자열을 포장하라과 같은 맥락으로 이어지는 규칙이다. 왜 인스턴스 변수는 2개 이하로 유지해야할까?

class Car {
  constructor(
    private ownerFirstName: string,
    private ownerLastName: string,
    private ownerAge: number,
    private position: number
  ) {}
}

Car이 인스턴스 변수로 ownerFirstName, ownerLastName, ownerAge, position을 가지고 있다. 이중에서 Car와 직접적으로 연관되어 있는 필드는 position 정도 뿐이니, 나머지는 Owner 클래스로 분리해보자.

class Car {
  constructor(private owner: Owner, private position: number) {}
}

class Owner {
  constructor(
    private firstName: string,
    private lastName: string,
    private age: number
  ) {}
}

CarOwner가 각각 자신에게 필요한 인스턴스 변수들을 가지게 되었다. 그런데 Owner를 살펴보면, firstNamelastName은 공통적으로 이름에 관련되어있으니, 이를 다시 한 번 분리해줄 수 있다.

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: 모든 원시값과 문자열을 포장하라를 생각하며 의미를 가지는 모든 원시값과 문자열을 포장해보자.

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) {}
}

처음 큰 덩어리부터 세부적인 요소까지 의미있는 객체로 만들어줌으로써 (비록 조금 길어졌어도) 응집도를 높이고, 더 나은 수준의 캡슐화를 통해 명시적이고 깨끗한 코드를 만들어보았다.

Last updated