-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs/#10: 5장 유사한 코드 융합하기 (앞부분만!) * docs: chapter 05 * docs/#10: 5장 마무리 * Docs: 5장:타입코드처리하기 --------- Co-authored-by: uuuuujin <[email protected]> Co-authored-by: shinequasar <[email protected]>
- Loading branch information
1 parent
878fc12
commit d21df18
Showing
3 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
--- | ||
title: "5. Fuse Similar Code Together" | ||
categories: | ||
- boring-km | ||
--- | ||
[You can also read in Notion](https://www.notion.so/5-Fuse-Similar-Code-Together-b742feaccf9640e89676ae87ce3fc049?pvs=4) | ||
|
||
## 5.1 유사한 클래스 통합하기 | ||
|
||
- 반복작업을 자꾸 시켜서 손목이 아프다 | ||
- 비슷한 성격을 가진 두 객체의 동작이 거의 다르지 않다면, 하나로 만들되 `if/else` 를 사용하지 말고 만들자 | ||
- 책에서는 처음엔 enum으로 바꿨다가 interface로 바꿨는데 이러한 패턴을 **“클래스로 타입 코드 대체”** 라고 한다. | ||
- 사실 뭐 이름이 중요한가 싶다. 일일이 외우기 보단 손가락으로 익히는 게 맞는거 같다. | ||
|
||
https://github.com/FiveLinesofCodeStudy/2D-Puzzle-Compose/commit/e9b2b43b5f101de142aaf656edcc2e6365af320e | ||
|
||
## 5.2 단순한 조건 통합하기 | ||
|
||
- if 문 갯수 줄이는 것은 정말 좋은 방법인 것 같다. | ||
|
||
### 절차 | ||
|
||
1. 본문이 실제로 동일한지 확인한다. | ||
2. 첫 번째 if 문의 닫는 괄호와 else if 문의 여는 괄호 사이의 코드를 선택하고 삭제한 후 `||`을 삽입한다. if 뒤에 여는 괄호를 삽입하고 `{` 앞에 닫는 괄호를 삽입한다. 동작을 변경하지 않도록 항상 표현식을 괄호로 묶는다. | ||
|
||
## 5.3 복잡한 조건 통합하기 | ||
|
||
- 코드 동작에 대한 명확한 이해가 받쳐줘야 가능하다. | ||
- SRP (단일 책임 원칙)에 따른 메서드를 만드는 걸 목적으로 리팩토링 해보자 | ||
|
||
https://github.com/FiveLinesofCodeStudy/2D-Puzzle-Compose/commit/d3b75296b6a5a47b4d6e0d9df24a23c8d1a6ebe3 | ||
|
||
## 5.4 클래스 간의 코드 통합 | ||
|
||
- 컴포지션을 사용하는 대표적인 디자인 패턴이다. | ||
- https://stackify.com/oop-concepts-composition/ | ||
|
||
https://github.com/FiveLinesofCodeStudy/2D-Puzzle-Compose/commit/e21106afe6097d2147ba3bbdb1eee3ac6d55149b | ||
|
||
## 5.5 유사 함수 통합하기 | ||
|
||
https://github.com/FiveLinesofCodeStudy/2D-Puzzle-Compose/commit/2718970221007d9a7985b81a9347aefa1aceef96 | ||
|
||
## 5.6 유사한 코드 통합하기 | ||
|
||
https://github.com/FiveLinesofCodeStudy/2D-Puzzle-Compose/commit/79ec4d0a596471b21db40184f46edfbc553c983d | ||
|
||
- 전략 패턴 동일하게 사용 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
--- | ||
title: "5장 유사한 코드 융합하기" | ||
categories: | ||
- shinequasar | ||
--- | ||
# 5장 유사한 코드 융합하기 | ||
|
||
### 실습 중인 레포 | ||
https://github.com/FiveLinesofCodeStudy/five-lines-soyeon.git | ||
|
||
## 5-1 유사한 클래스 통합하기 | ||
|
||
- || 로 묶인 상태를 하나의 함수로 묶으니 가독성이 좋아졌다. 변수명으로 바로 유추 가능 | ||
- 앞에서 다양한 메서드들을 쪼개고, 클래스들도 많이 만들어 놨어서 왜 이렇게 나누지 의문이 좀 있었는데(중복된 기능들을 반복해서 사용하는 모습이 의문스러웠었음) 5장을 위해서 이렇게 했구나 싶음. | ||
- 유사한 메서드나 기능을 if 불리언으로 합치고, 그걸 다시 .is~~~() 형태로 클래스에 내재화 해서 한 클래스에 모은 후 비슷한 클래스를 삭제해 합치는 과정이 나와서 마음이 편해졌다. | ||
- 이 과정에서 생성자를 활용하여 초기 상태를 정하는 것도 잘 활용해볼 수 있을 것 같다. | ||
|
||
## 5-1-1 리팩토링 패턴 : 유사 클래스 통합 | ||
|
||
- 트래픽 예제로 다시한번 복습 | ||
|
||
## 5-2 단순한 조건 통합하기, 리팩토링 패턴 : if문 결합 | ||
|
||
- 당연하게 써오던 같은 본문은 합친다~! 를 다시한번 강조 | ||
- 5-1에서 언급한 ‘|| 로 묶인 상태를 하나의 함수로 묶기’ 같은 방법은 코드를 연구하지 않아도 리팩토링할 수 있는 패턴이라는 점이 공식같아서 새로운 시각을 가지게 되었다. | ||
|
||
## 5-3 복잡한 조건 통합하기 | ||
|
||
- 코드는 다르지만 논리적으로 같은 부분을 같은 코드로 바꾸고, 그 메서드 두 개를 합치는 방법 | ||
- 이 부분은 코드의 의미를 어느정도 파악한 후에 적용할 수 있는 기법인 듯하다. | ||
- 맡고있는 프로젝트에 대한 이해가 높아지면 적용해봐도 좋을 듯. | ||
|
||
### 5-3-1 조건을 위한 산술규칙 사용 | ||
|
||
- 코드를 덧셈법칙, 곱셈법칙처럼 수식의 모습으로 사고하는 방식이 인상깊었다. | ||
- 이 부분은 당장 적용해볼 수 있을 것 같아서 조건을 고려할 때 바로 도입해봐야겠다는 생각을 했다. | ||
``` | ||
//변경 전 | ||
if(map[y][x].isStony() && map[y][x].isAir()) || map[y][x].isBoxy() && map[y][x].isAir()) { | ||
... | ||
} | ||
//변경 후 | ||
if((map[y][x].isStony() || map[y][x].isBoxy()) && map[y][x].isAir()) { | ||
... | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
# 5장 - 유사한 코드 융합하기 | ||
|
||
## 5.1 유사한 클래스 통합하기 | ||
|
||
- 상수 메서드: 상수를 반환하는 메서드 | ||
- 경우에 따라 다른 값을 반환하는 상수 메서드를 공유한다면 두 클래스는 합칠 수 있음 | ||
|
||
- 클래스를 합치는 방법 | ||
1. 상수 메서드를 제외한 클래스의 모든 것을 동일하게 만든다. | ||
2. 클래스를 합친다. | ||
|
||
- 구체적인 절차 | ||
1. 모든 비기준 메서드를 동일하게 만듦 | ||
2. 기준 메서드에 대한 필드를 도입하고 생성자에서 상수를 할당하는 것으로 시작 | ||
3. 상수 대신 도입한 필드를 반환하도록 메서드 변경 | ||
4. 문제 없는지 확인 위해 컴파일 | ||
5. 각 클래스에 대해 한 번에 하나의 필드씩 다음 수행 | ||
- 필드의 기본값을 매개변수로 지정 | ||
- 컴파일러 오류 살펴보고 기본값 인자로 전달 | ||
6. 모든 클래스 동일하면 통합한 클래스 중 하나를 제외한 모두를 삭제하고, 삭제하지 않은 클래스로 바꾸어 모든 컴파일러 오류를 수정 | ||
|
||
<br> | ||
|
||
### Stone과 FallingStone 통합하는 방법 | ||
1. 두 개의 moveHorizontals를 동일하게 만듦 | ||
2. 상수메서드 isFallingStone만 다르므로 falling 필드를 새로 도입하고 생성자에서 그 값을 할당 | ||
3. isFallingStone을 변경해서 새로운 falling 필드를 반환 (상수 대신 필드 반환) | ||
4. 문제 없는지 컴파일 | ||
5. 각 클래스에 대해 falling의 기본값을 매개변수로 받도록 만들고 기본값을 인자로 전달 | ||
6. 통합 중인 클래스 중 하나를 제외한 모든 클래스를 삭정한 후, 컴파일 오류를 남아 있는 클래스로 바꿔서 수정 | ||
|
||
<br> | ||
📌 클래스를 결합할 때 기대하는 효과 | ||
|
||
- 잠재적으로 숨겨진 타입을 가리키는 코드를 찾을 수 있음 | ||
|
||
<br> | ||
|
||
> **class에서 consturctor** | ||
> <br> | ||
> - 클래스의 인스턴스 객체를 생성, 초기화하는 역할 | ||
> - 클래스 내부 혹은 다른 클래스에 상속한 경우, 해당 클래스 내부에서 사용하기 위한 객체를 정의 | ||
> - 생성자는 하나만 가질 수 있음 | ||
> - 매개변수 앞에 public, private 키워드 넣으면 자동으로 인스턴스 변수 만들고 인자 값 할당함 | ||
```typescript | ||
// 방법 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 루프의 가운데에 있는 것 | ||
|
||
<br> | ||
|
||
📌 명령에서 질의 분리 | ||
- 명령: 부작용이 있는 모든 것 | ||
- 질의: 순수한 것 | ||
- => void 메서드에서만 부수적인 동작 허용하기!! (부수적인 동작 하거나, 무언가 반환하거나 둘 중 하나만!) | ||
|
||
<br> | ||
|
||
## 5.4 클래스 간의 코드 통합 | ||
> **UML(Unified Modeling Language)** <br> | ||
> - 코드에 대한 속성 전달하기 위해 다양한 유형의 표준 다이어그램으로 구성 | ||
> - 시퀀스 다이어그램, **클래스 다이어그램**, 활동 다이어그램 | ||
> - 전략 패턴 -> 클래스 다이어그램 사용 | ||
> **클래스 다이어그램** | ||
> - 인터페이스와 클래스의 구조가 서로 어떤 관계가 있는지 보여줌 | ||
> - 주로 공개 메서드만 묘사함 | ||
> - 인터페이스는 위에 interface라고 표기 | ||
> ```typescript | ||
> class Cls { | ||
> private text: string = "Hello"; | ||
> public name: string; | ||
> private getText() { return this.text } | ||
> printText() { console.log(this.getText()) } | ||
> } | ||
> ``` | ||
> <img width="400" alt="이미지" src="https://github.com/FiveLinesofCodeStudy/docs/assets/75356503/88bca221-4275-4a4e-9a81-cc38e2b17c76" /> | ||
> | ||
> <br> | ||
> <br> | ||
> | ||
> ⭐️️**클래스와 인터페이스 간의 관계**⭐️️ | ||
> | ||
> <img width="400" alt="이미지" src="https://github.com/FiveLinesofCodeStudy/docs/assets/75356503/0b0c1960-d78b-44a4-902a-3b56544f628e" /> | ||
> | ||
> - X가 Y를 사용한다 (의존, 연관) | ||
> - 관계가 무엇인지 모르거나 신경 쓰지 않을 떄 사용 | ||
> - X는 Y다 | ||
> - X가 하나 또는 여러 개의 Y를 가진다 | ||
> - 대부분 **컴포지션**과 **구현** 사용 | ||
> **구현(implements)** | ||
> ```typescript | ||
> interface A { | ||
> m(): void; | ||
> } | ||
> class B implements A { | ||
> m() { console.log("Hello"); } | ||
> } | ||
> ``` | ||
> <img alt="이미지" width="300" src="https://github.com/FiveLinesofCodeStudy/docs/assets/75356503/d881fd35-4b76-4520-89f7-5ce65331a0f5"> | ||
> | ||
> - 인터페이스로 이미 알 수 있어서 클래스 B에도 m 메서드가 있음을 보여줄 필요 없음 | ||
> **구성(composed)** | ||
> ```typescript | ||
> class A { | ||
> private b: B; | ||
> } | ||
> class B {} | ||
> ``` | ||
> <img alt="이미지" width="400" src="https://github.com/FiveLinesofCodeStudy/docs/assets/75356503/0936ff62-2d09-43fb-873d-fc96aca334a9"> | ||
<br> | ||
### 전략 패턴 | ||
- 다른 클래스를 인스턴스화해서 변형(variance)을 도입하는 개념 | ||
- <img alt="이미지" width="400" src="https://github.com/FiveLinesofCodeStudy/docs/assets/75356503/47dabe11-0813-434c-87af-b6ed12213664"> | ||
- 클래스를 추가해서 변경이 가능하게 한다!! | ||
- 전략 패턴 도입 상황 | ||
- 1. 코드에 변형 도입하고 싶어서 리팩터링 수행하는 경우 | ||
- 2. 클래스 간의 동작 통합하려는 경우 | ||
- 구현체가 하나뿐인 인터페이스 만들지 말 것 | ||
- 가독성 도움 안 됨 | ||
<br> | ||
<br> | ||
> ⭐️ 이번주에 진행할 것 | ||
> 1. 3장 ~ 5장 복습하기 (코드 다시 쳐보기!!) | ||
> - 레포 새로 파기 | ||
> - 커밋 나눠하기 | ||
> - 파일 나누기 | ||
> - 웹스톰 단축키 익숙해지기 |