Skip to content

Commit

Permalink
Create 15-3.md (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
newminkyung authored Jun 29, 2024
1 parent cd6b6d3 commit b6e9fcf
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions new/15-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# 파이브 라인스 오브 코드
## 4. 타입 코드 처리하기
### 규칙: if 문에서 else 를 사용하지 말 것
- 프로그램에서 이해하지 못하는 타입인지를 검사하지 않는 한 if 문에서 else 를 사용하지 않는다.

- `if-else` 를 사용하면 코드에서 결정이 내려지는 지점을 고정하게 된다.

- 독립된 if 문은 검사로 간주하고, if-else 문은 의사 결정으로 간주한다.

``` js
// AS IS
function average(ar: number[]) {
if (size(ar) === 0) {
throw new Error("Cannot take average of empty array");
}
return sum(ar) / size(ar);
}

// TO BE
function average(ar: number[]) {
assertNotEmpty(ar);
return sum(ar) / size(ar);
}

function assertNotEmpty(ar: number[]) {
if (size(ar) === 0) {
throw new Error("Cannot take average of empty array");
}
}
```
#### 스멜
- 이른 바인딩: if-else 같은 의사결정 동작은 컴파일 시 처리되어 애플리케이션에 고정되면 재컴파일 없이는 수정할 수 없다.
- 늦은 바인딩: 코드가 실행되는 순간 동작이 결정됨

#### 의도
- if 는 흐름을 제어 -> 다음에 실행할 코드를 결정한다는 뜻

### 리펙터링: 클래스로 타입 코드 대체
- 열거형을 인터페이스로 변환하고 열거형의 값들을 클래스가 되도록 변환한다.
- 해당 리펙터링 패턴은 자체적으로 많은 가치를 가지지 않지만, 추후 개선을 가능하기 한다.

### 리펙터링: 클래스로 코드 이관하기
- 기능을 클래스로 옮기면서 클래스로 타입 코드 대체 패턴의 자연스러운 연장선
- 특정 값과 연결된 기능이 값에 해당하는 클래스로 이동하기 때문에 불변속성을 지역화

### 리펙터링: 메서드의 인라인화
- 프로그앰에서 더 이상 가독성에 도움이 되지 않는 메서드를 제거
- 단, 메서드를 인라인으,로 사용하는 것과는 다른 개념

- 메서드가 인라인화 하기 너무 복잡한가?
-> 낮은 수준의 연산에 의존하여 가독성에 도움이 되는 경우에는 인라인화하지 않는다.

### 리펙터링: 메서드 전문화
- 일반화하고 재사용하려는 본능적인 욕구가 있지만 그렇게 하면 책임이 흐려지고, 다양한 위치에서 코드를 호출할 수 있기 때문에 문제가 될 수 있음
- 전문화된 메서드는 더 적은 위치에서 호출되어 필요성이 없어지면 더 쉽게 제거 가능함

### 규칙: switch 를 사용하지 말것
- default 케이스가 없고 모든 case 에 반환값이 존재하는 경우에는 switch 를 사용하지 않는다.

#### switch 의 문제점

- 컴파일러 입장에서 새로 추가한값의 처리에 대한 누락을 알 수 없다.
- break 키워드 누락으로 인한 버그

#### 스멜
- switch 문은 값을 처리하는 방법에 초점, 클래스에 기능을 추가할때는 값이 상황을 처리하는 방법에 초점
- 컨텍스트에 초점을 맞춘다는 것은 불변속성을 전역화하는 것을 의미

#### 의도
- switch -> else if -> 클래스로 변환

- 인터페이스 대신 추상 클래스를 사용할 수 없을까?
- 사용할 수 있다. 코드의 중복을 피할 수 있다.
- 하지만 인터페이스를 사용하면 개발자가 능동적으로 무엇인가를 해야함. 즉, 누락으로 인한 오류를 방지할 수 있음

#### 규칙: 인터페이스에서만 상속받을 것
- 상속은 오직 인터페이스를 통해서만 받는다.

- 추상 클래스를 사용하는 것은 일부 메서드의 기본 구현을 제공하고, 다른 메서드를 추상화 하기 위함
- 중복을 줄이고 코드의 줄을 줄이고자 할 경우 편리
- 하지만 추상 클래스의 코드 공유는 커플링을 유발하고, 기본 구현으로 인해 재정의가 필요한 메서드 인지 컴파일러를 통해 확인이 어려움

#### 스멜
> 상속보다는 컴포지션이 더 좋다 <<GoF의 디자인 패턴>>
### 리팩터링: 삭제 후 컴파일하기
- 인터페이스에서 사용하지 않는 메서드를 제거하는 것
- 메서드를 삭제하고 컴파일러에서 허용하는지 확인하는 것

0 comments on commit b6e9fcf

Please sign in to comment.