1장 - 객체지향 디자인
- 변화를 주기 힘든 애플리케이션은 다루기 어렵다. 그런데 왜 수정이 어려운가?
- 하나의 객체가 다른 객체를 너무 많이 알고 있기 때문. 뭐 하나 수정하려 할 때 협업 객체와 그 협업 객체의 협업 객체를 수정하는 등
- 너무 많은 것을 알아버린 객체는 변화를 주기 어렵고, 재사용 및 테스팅이 어렵다.
- 그렇다고 개발자가 미래를 예측하라는 것이 아니라, ‘언젠가 무언가는 변한다’, ‘지금 무엇이 변경될지 알 수 없다’ 라는 사실을 받아들이는 것이다. 즉 변화하고 움직일 수 있는 여지를 남겨 놓아 변화의 비용을 최소화한다.
- 디자인 원칙들
- 디자인 패턴?: 패턴을 익히는 것은 좋지만 잘못 적용되면 오히려 혼란스러운 코드를 낳게 된다. 사용법을 완벽하게 익힐 필요가 있다. (이 책에서는 다루지 않는다.)
- 언제 디자인을 해야하는가?
- BUFD(Big Up Front Design, 커다란 것을 먼저 구상하는 디자인)은 그닥 맞는 방법이 아니다.
- 애자일하게. “코드를 손쉽게 수정하려면 코드를 어떻게 배치해야 하는가?” 에 관심을 가진다.
- 소프트웨어의 질을 측정하는 궁극적인 기준?: 주어진 시간 안에서 기능별 구현 비용 (실제로 계산하기 쉽진 않음)
- 이를 위해 디자인에 시간이 필요하고, 결국 돈이 드는 것이다. 이 때 두 가지 고려 사항이 있는데:
- 디자인에 투자한 시간으로 본전이라도 뽑으려면 디자인 이론을 이해하고 적절히 적용할 수 있어야 한다. 올바른 순간에 필요한 만큼 적용할 줄 알아야 한다는 것이다.
2장 - 단일 책임 원칙을 따르는 클래스 디자인하기
- “클래스는 단순해야 한다” 라는 말을 명심하기
- 지금 당장 해야 할 일을 할 줄 알고, 나중에도 쉽게 수정할 수 있는 클래스 모델링하기
- 수정하기 쉽다?
- 수정이 예상치 못한 부작용을 낳지 않는다.
- 요구사항이 조금 변했을 때 연관된 코드를 조금만 수정하면 된다.
- 현재 코드를 다시 사용하기 쉽다.
- 코드를 수정하는 가장 쉬운 방법은 이미 수정하기 쉬운 코드에 새로운 코드를 추가하는 것이다.
- 그렇다면 이런 특징이 있어야 한다.
- Transparent: 수정의 결과가 뚜렷하게 드러나야 한다.
- Reasonable: 수정 비용은 수정 결과를 통해 얻은 이득에 비례해야 한다.
- Useable: 예상치 못한 상황에서도 현재 코드를 사용할 수 있어야 한다.
- Exemplary: 코드 자체가 나중에 수정하는 사람에게 모범이 되어야 한다.
- 코드 예시 - Gear
// 단순한 Gear 클래스가
class Gear {
constructor(chainring, cog) {
this.chainring = chainring;
this.cog = cog;
}
get ratio() {
return this.chainring / this.cog;
}
}
// 기능이 추가되면서 복잡해지기 시작한다. Gear 는 정말로 타이어에 대해 알아야할까?
class Gear {
constructor(chainring, cog, rim, tire) {
this.chainring = chainring;
this.cog = cog;
this.rim = rim;
this.tire = tire;
}
get ratio() {
return this.chainring / this.cog;
}
get gearInches() {
const { ratio, rim, tire } = this;
return ratio * (rim + tire * 2);
}
}
- 한개 이상의 책임이 있는 클래스는 재사용이 어렵다. 이럴 때 원하는 행동만을 가져오도록 코드를 복붙하는 하는 방법이 있다.
- 하지만 중복 코드는 유지보수를 어렵게 하고 버그를 생성하거나, 하나의 문제를 다른 문제로 가리는 수준에 지나지 않는다.
- 하나의 클래스가 다른 클래스의 책임까지 짊어지고 있는지 어떻게 아나?
- 클래스를 인격이 있는 존재처럼 가정하고 질문을 던져보는 방법
- “Gear 씨, 당신의 기어 인치는 몇인가요?” (?) / “Gear 씨, 당신의 타이어 높이는 무엇인가요?” (X)
- 클래스의 책임을 한 문장으로 만들어 보는 것
- 클래스는 최대한 작으면서도 유용한 것만 행해야 한다는 것을 기억하자.
- 응집력: 클래스 안의 모든 것들이 하나의 핵심 목표와 연관되어 있다. -> 하나의 책임을 가지고 있다(단일 책임 원칙).