-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
143 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,143 @@ | ||
# 5장 - 더 좋은 액션 만들기 | ||
|
||
이번 장에서 살펴 볼 내용 | ||
|
||
- 암묵적 입력과 출력을 제거해서 재사용하기 좋은 코드를 만드는 방법 | ||
- 복잡하게 엉킨 코드를 풀어 더 좋은 구조를 만드는 법 | ||
|
||
```jsx | ||
// AS IS | ||
function gets_free_shipping(total, item_price) { | ||
return item_price + total >= 20; | ||
} | ||
|
||
function update_shipping_icons(){ | ||
... | ||
if(gets_free_shipping(shopping_cart_total, item_price)) | ||
... | ||
} | ||
``` | ||
|
||
```jsx | ||
// TO BE | ||
function gets_free_shipping(cart) { | ||
return calc_total(cart) >= 20; | ||
} | ||
|
||
function update_shipping_icons(){ | ||
... | ||
let new_cart = add_item(shopping_cart, item.name, item.price); | ||
if(gets_free_shipping(new_cart)) // 카피-온-라이트 | ||
... | ||
} | ||
``` | ||
|
||
### 여기서 생각해볼 점 | ||
|
||
위 코드에서 add_item() 함수를 부를 때 마다 cart 배열을 복사하는데, 비용이 너무 많이 들지 않는가? | ||
|
||
⇒ 배열을 바꾸는 것보다 복사하는 비용이 더 드는건 맞음. 근데 요즘은 GC가 효율적으로 잘 처리해줘서 비용 신경 안쓰긴 함. trade-off 따져봤을 때 이득이 더 많다고 생각 | ||
|
||
## **원칙 : 암묵적 입력과 출력은 적을수록 좋다** | ||
|
||
인자가 아닌 모든 입력은 암묵적 입력이고, 리턴값이 아닌 모든 출력은 암묵적 출력이다. | ||
|
||
어떤 함수에 암묵적 입력과 암묵적 출력이 있다면 다른 컴포넌트와 강하게 연결된 컴포넌트라고 할 수 있다. | ||
|
||
다른 곳에서 사용할 수 없기 때문에 모듈이 아니다. | ||
|
||
또 아무때나 실행할 수 없기 때문에 테스트하기에도 어렵다. | ||
|
||
계산은 암묵적 입력과 출력이 없기 때문에 테스트 하기 쉽다. | ||
|
||
```jsx | ||
// AS IS | ||
function update_shipping_icons() { | ||
... | ||
let new_cart = add_item(shopping_cart, item.name, item.price); | ||
... | ||
} | ||
``` | ||
|
||
```jsx | ||
// TO BE | ||
function update_shipping_icons(cart) { | ||
... | ||
let new_cart = add_item(cart, item.name, item.price); | ||
... | ||
} | ||
|
||
``` | ||
|
||
코드에서 전역변수인 shopping_cart 를 사용하면서 암묵적 입력과 출력을 이용하고 있다. | ||
|
||
shopping_cart 라는 전역변수 대신 인자를 넣어주어 암묵적 입력을 제거한다. | ||
|
||
함수 시그니처가 달라졌기 때문에 호출하는 곳도 바꿔준다. | ||
|
||
```jsx | ||
// update_shipping_icons(); | ||
update_shipping_icons(shopping_cart); | ||
``` | ||
|
||
## **원칙 : 설계는 엉켜있는 코드를 푸는 것이다** | ||
|
||
함수를 사용하면 관심사를 자연스럽게 분리할 수 있다. | ||
|
||
함수는 인자로 넘기는 값과 그 값을 사용하는 방법을 분리한다. 또 가끔은 분리된 것을 합치고 싶을 수도 있다. | ||
|
||
하지만 분리한 것은 언제든 쉽게 조합할 수 있기 때문에 잘 분리하면 분리할 수록 좋다. 👍🏻 | ||
|
||
## **add_item()을 분리해 더 좋은 설계 만들기** | ||
|
||
아래 함수는 장바구니에 제품을 추가하는 간단한 일을 하는 함수다. 과연 간단할 일을 하고 있을까 살펴보자 | ||
|
||
```jsx | ||
function add_item(cart, name, price) { | ||
let new_cart = cart.slice(); | ||
new_cart.push({ | ||
name: name, | ||
price: price, | ||
}); | ||
return new_cart; | ||
} | ||
``` | ||
|
||
어떤 일을 하는지 나누어보면 아래와 같이 나눌 수 있다. | ||
|
||
### 1. item 객체를 만드는 함수 | ||
|
||
```jsx | ||
function make_cart_item(name, price) { | ||
return { | ||
name: name, | ||
price: price, | ||
}; | ||
} | ||
``` | ||
|
||
### 2. 배열을 복사해서 복사본 반환하는 함수 | ||
|
||
```jsx | ||
function add_item(cart, item) { | ||
let new_cart = cart.slice(); | ||
new_cart.push(item); | ||
return new_cart; | ||
} | ||
``` | ||
|
||
### 3. 함수 호출부 | ||
|
||
```jsx | ||
add_item(shopping_cart, make_cart_item("shoes", 3.45)) | ||
``` | ||
|
||
⇒ item 구조만 알고 있는 함수 (make_cart_item)와 cart 구조만 알고 있는 함수 (add_item)로 나눠서 수정 | ||
|
||
이렇게 분리하면 cart와 item을 독립적으로 확장 쌉가능 | ||
|
||
## **요약** | ||
|
||
- 암묵적 입력과 암묵적 출력은 인자와 리턴값으로 바꿔 없애주기 | ||
- 설계는 엉켜있는 것을 푸는 것, 풀려있는 것은 언제든 합칠 수 있음 | ||
- 엉켜있는 것을 풀어 각 함수가 하나의 일만 하도록 하면, 개념을 중심으로 쉽게 구성 가능 |