7-5. 클래스 추출하기
적용 시점
클래스가 너무 비대하게 커지는 경우
일부 데이터와 메서드를 따로 묶을 수 있는 경우
함께 변경되는 일이 많거나 서로 의존하는 데이터들이 많은 경우
작은 일부의 기능만을 위해 서브클래스를 만들거나, 확장해야 할 기능이 무엇이냐에 따라 서브클래스를 만드는 방식이 달라지는 경우
절차
클래스의 역할을 분리하는 방법을 정한다.
분리될 역할을 담당할 클래스를 새로 만든다.
원래 클래스의 생성자에서 새로운 클래스의 인스턴스를 생성하여 필드에 저장함
분리될 역할에 필요한 필드들을 새 클래스로 옮긴다. 하나씩 옮길 때마다 테스트한다.
메서드들도 새 클래스로 옮긴다. 이때 저수준 메서드, 즉 다른 메서드를 호출하기보다는 호출을 당하는 일이 많은 메서드로부터 옮긴다. 하나씩 옮길 때마다 테스트한다.
양쪽 클래스의 인터페이스를 살펴보면서 불필요한 메서드를 제거하고, 이름도 새로운 환경에 맞게 바꾼다.
새 클래스를 외부로 노출할지 정한다. 노출하려거든 새 클래스에 참조를 값으로 바꾸기를 적용할지 고민해본다.
예시
❌Before
class Production {
constructor({ rank, category, name, price }) {
this._rank = rank;
this._category = category;
this._name = name;
this._price = price;
}
get category() { return this._category; }
get rank() { return this._rank; }
get name() { ... }
get price() { ... }
}
⭕After
class CategoryRank() {
constructor({ rank, category }) {
this._rank = rank;
}
get rank() { ... }
get category() { ... }
}
class Production {
constructor({ rank, category, name, price }) {
this._categoryRank = new CategoryRank({ rank, category });
this._name = name;
this._price = price;
}
get rank() { this._categoryRank.rank(); }
get category() { this._categoryRank.category(); }
get name() { ... }
get price() { ... }
}
Last updated