Skip to content

Commit

Permalink
4장장 (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
sangbooom authored May 22, 2024
1 parent d21f595 commit 7462453
Showing 1 changed file with 186 additions and 0 deletions.
186 changes: 186 additions & 0 deletions 챕터_4/상범.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# 4장 - 액션에서 계산 빼내기

이번 장에서 살펴 볼 내용

- 테스트하기 쉽고 재사용 하기 좋은 코드를 만들기 위해 리팩터링 하는 방법

```jsx
let shopping_cart = []; // 장바구니 제품과 금액 합계를 담고 있는 전역변수
let shopping_cart_total = 0; // 장바구니 금액 합계를 담고 있는 전역변수

function add_item_to_cart(name, price) {
shopping_cart.push({
name: name,
price: price,
});
calc_cart_total();
}

function calc_cart_total() {
shopping_cart_total = 0;
for(let i = 0; i < shopping_cart.length; i++) {
shopping_cart_total += item.price;
}
set_cart_total_dom(); // 금액 합계를 반영하기 위해 DOM 업데이트
}

```

## 테스트하기 쉽게 만들기

지금 코드는 동작은 하지만, 정확하게 동작하고 있는지 테스트 하기는 어려움.

- DOM 업데이트와 비즈니스 규칙은 분리 되어야 함
- 전역변수가 없어야 함

## 재사용하기 쉽게 만들기

결제팀과 배송팀이 지금 코드를 재사용 하려고 한다면 재사용 불가능함.

- 장바구니 정보를 전역변수에서 읽어오고 있는데, 결제팀 배송팀은 DB에서 장바구니 정보 읽어와야 됨
- 결과를 보여주기 위해 DOM을 직접 바꾸고 있지만, 결제팀은 영수증을 배송팀은 운송장을 출력해야 함

## 액션과 계산, 데이터를 구분하기

함수형 프로그래머는 **암묵적 입력****암묵적 출력**을 부수효과 라고 부른다.

명시적 입력

- 인자

암묵적 입력

- 인자 외 다른 입력 (전역 변수 읽기)

명시적 출력

- 리턴값

암묵적 출력

- 리턴값 외 다른 출력 (전역 변수 값 변경)

```jsx
var total = 0;

function add_to_total(amount) { // 인자는 명시적 입력
console.log(total); // 전역 변수를 읽는 것은 암묵적 입력
total += amount; // 전역 변수를 바꾸는 것은 암묵적 출력
return total; // 리턴값은 명시적 출력
}
```

⇒ 생각해보니 함수를 작성할 때 인자를 통해 넘겨받지 않고 바로 참조하는 경우가 많았고 (암묵적 입력?) 전역 변수를 바꾸는 행위도 (암묵적 출력)이 많았던 것 같다.

## 액션에서 계산 빼내기

```jsx
// AS IS
function calc_cart_total() {
shopping_cart_total = 0;
// 계산 코드 개선 필요함
for(let i = 0; i < shopping_cart.length; i++) {
let item = shopping_cart[i];
shopping_cart_total += item.price;
}
set_cart_total_dom();
update_shipping_icons();
update_tax_dom();
}
```

```jsx
// TO BE
function calc_cart_total() {
calc_total(); // 서브루틴 추출하기 => 함수안에 함수가 있을 경우 안에 있는 함수를 서브루틴 이라고 함
set_cart_total_dom();
update_shipping_icons();
update_tax_dom();
}

function calc_total() {
shopping_cart_total = 0; // 전역 변수값 바꾸기 => 암묵적 출력
for(let i = 0; i < shopping_cart.length; i++) { // 전역 변수값 읽기 => 암묵적 입력
let item = shopping_cart[i];
shopping_cart_total += item.price; // 전역 변수값 바꾸기 => 암묵적 출력
}
}
```

암묵적 입/출력이 남아있음, 아직 액션임

```jsx
// TO BE
function calc_cart_total() {
shopping_cart_total = calc_total(shopping_cart); // 전역 값을 인자로 전달
set_cart_total_dom();
update_shipping_icons();
update_tax_dom();
}

function calc_total(cart) { // 명시적 입력
let total = 0; // 지역변수 => 명시적 출력
for(let i = 0; i < cart.length; i++) { // 인자로 전달한 값 읽기 => 명시적 입력
let item = cart[i];
total += item.price;
}
retrun total; // 지역변수 리턴 => 명시적 출력
}
```

암묵적 입/출력 없앰.

액션에서 계산 빼기 완료

## 액션에서 또 다른 계산 빼내기 2

```jsx
// AS IS
function add_item__to_cart(name, price){
shopping_cart.push({
name,
price
});

calc_cart_total();
}
```

```jsx
// TO BE
function add_item_to_cart(name, price){
add_item(name, price);
calc_cart_total();
}

function add_item(name, price){
shopping_cart.push({
// 전역 변수 값 읽기 => 암묵적 입력
// push() 메서드로 전역 변수 값 변경 => 암묵적 출력
name,
price
})
}
```

```jsx
// TO BE
function add_item_to_cart(name, price){
add_item(shopping_cart, name, price);
calc_cart_total();
}

function add_item(cart, name, price){
const new_cart = cart.slice(); // 인자를 통해 전역 변수 값 읽기 => 명시적 입력
new_cart.push({ // 복사본을 변경
name,
price
})
return new_cart; // 복사본 리턴 => 명시적 출력 (카피-온-라이트)
}
```

여기서 핵심은 암묵적 입력은 인자로 암묵적 출력은 리턴값으로 바뀐다는 것이고,
인자와 리턴값은 바뀌지 않는 불변값이라는 것이 중요하다. 리턴값이 나중에 바뀐다면 그건 암묵적 출력이다.

또 인자로 받은 값이 바뀔 수 있다면 그건 암묵적 입력이다.

0 comments on commit 7462453

Please sign in to comment.