5장 - 유사한 코드 융합하기
5.1 유사한 클래스 통합하기
- 상수 메서드: 상수를 반환하는 메서드
- 경우에 따라 다른 값을 반환하는 상수 메서드를 공유한다면 두 클래스는 합칠 수 있음
- 클래스를 합치는 방법
- 상수 메서드를 제외한 클래스의 모든 것을 동일하게 만든다.
- 클래스를 합친다.
- 구체적인 절차
- 모든 비기준 메서드를 동일하게 만듦
- 기준 메서드에 대한 필드를 도입하고 생성자에서 상수를 할당하는 것으로 시작
- 상수 대신 도입한 필드를 반환하도록 메서드 변경
- 문제 없는지 확인 위해 컴파일
- 각 클래스에 대해 한 번에 하나의 필드씩 다음 수행
- 필드의 기본값을 매개변수로 지정
- 컴파일러 오류 살펴보고 기본값 인자로 전달
- 모든 클래스 동일하면 통합한 클래스 중 하나를 제외한 모두를 삭제하고, 삭제하지 않은 클래스로 바꾸어 모든 컴파일러 오류를 수정
Stone과 FallingStone 통합하는 방법
- 두 개의 moveHorizontals를 동일하게 만듦
- 상수메서드 isFallingStone만 다르므로 falling 필드를 새로 도입하고 생성자에서 그 값을 할당
- isFallingStone을 변경해서 새로운 falling 필드를 반환 (상수 대신 필드 반환)
- 문제 없는지 컴파일
- 각 클래스에 대해 falling의 기본값을 매개변수로 받도록 만들고 기본값을 인자로 전달
- 통합 중인 클래스 중 하나를 제외한 모든 클래스를 삭정한 후, 컴파일 오류를 남아 있는 클래스로 바꿔서 수정
📌 클래스를 결합할 때 기대하는 효과
- 잠재적으로 숨겨진 타입을 가리키는 코드를 찾을 수 있음
class에서 consturctor
- 클래스의 인스턴스 객체를 생성, 초기화하는 역할
- 클래스 내부 혹은 다른 클래스에 상속한 경우, 해당 클래스 내부에서 사용하기 위한 객체를 정의
- 생성자는 하나만 가질 수 있음
- 매개변수 앞에 public, private 키워드 넣으면 자동으로 인스턴스 변수 만들고 인자 값 할당함
// 방법 1
class Stone implements Tile {
private falling: boolean
constructor(falling: boolean) {
this.falling = falling;
}
}
// 방법 2
class Stone implements Tile {
constructor(private falling: boolean) {}
}
5.3 복잡한 조건 통합하기
📌 조건을 위해 산술 규칙을 사용할 떄 순수 조건을 사용해야 함
- 조건은 항상 순수 조건(순수조건: 조건이 변수에 값 할당하거나 예외 발생시키거나 I/O와 상호작용하는 동작이 없는 것)
- if, while뒤에 오는 것과 for 루프의 가운데에 있는 것
📌 명령에서 질의 분리
- 명령: 부작용이 있는 모든 것
- 질의: 순수한 것
- => void 메서드에서만 부수적인 동작 허용하기!! (부수적인 동작 하거나, 무언가 반환하거나 둘 중 하나만!)
5.4 클래스 간의 코드 통합
UML(Unified Modeling Language)
- 코드에 대한 속성 전달하기 위해 다양한 유형의 표준 다이어그램으로 구성
- 시퀀스 다이어그램, 클래스 다이어그램, 활동 다이어그램
- 전략 패턴 -> 클래스 다이어그램 사용
클래스 다이어그램
- 인터페이스와 클래스의 구조가 서로 어떤 관계가 있는지 보여줌
- 주로 공개 메서드만 묘사함
- 인터페이스는 위에 interface라고 표기
class Cls { private text: string = "Hello"; public name: string; private getText() { return this.text } printText() { console.log(this.getText()) } }
⭐️️클래스와 인터페이스 간의 관계⭐️️
- X가 Y를 사용한다 (의존, 연관)
- 관계가 무엇인지 모르거나 신경 쓰지 않을 떄 사용
- X는 Y다
- X가 하나 또는 여러 개의 Y를 가진다
- 대부분 컴포지션과 구현 사용
구현(implements)
interface A { m(): void; } class B implements A { m() { console.log("Hello"); } }
- 인터페이스로 이미 알 수 있어서 클래스 B에도 m 메서드가 있음을 보여줄 필요 없음
구성(composed)
class A { private b: B; } class B {}
전략 패턴
- 다른 클래스를 인스턴스화해서 변형(variance)을 도입하는 개념
- 클래스를 추가해서 변경이 가능하게 한다!!
- 전략 패턴 도입 상황
-
- 코드에 변형 도입하고 싶어서 리팩터링 수행하는 경우
-
- 클래스 간의 동작 통합하려는 경우
-
- 구현체가 하나뿐인 인터페이스 만들지 말 것
- 가독성 도움 안 됨
⭐️ 이번주에 진행할 것
- 3장 ~ 5장 복습하기 (코드 다시 쳐보기!!)
- 레포 새로 파기
- 커밋 나눠하기
- 파일 나누기
- 웹스톰 단축키 익숙해지기