# 8.6 문장 슬라이드하기 (Slide Statements)

리팩터링 전

```javascript
const pricingPlan = retrievePricingPlan();
const order = retreiveOrder();
let charge;
const chargePerUnit = pricingPlan.unit;
```

리팩터링 후

```javascript
const pricingPlan = retrievePricingPlan();
const chargePerUnit = pricingPlan.unit;
const order = retreiveOrder();
let charge;
```

## 🧷 배경

관련된 코드들이 가까이 모여 있다면 이해하기 더 쉽다. 문장 슬라이드하기 리팩터링으로 이런 코드들을 한데 모아둔다. 저자는 변수를 처음 사용할 때 선언하는 스타일을 선호한다.

## 🧷 절차

1\. 코드 조각(문장들)을 이동할 목표 위치를 찾는다. 코드 조각의 원래 위치와 목표 위치 사이의 코드들을 보면서 조각을 모으고 나면 동작이 달라지는 코드가 있는지 살핀다.  아래의 간섭이 있다면 리팩터링을 포기한다.\
\- 코드 조각에서 참조하는 요소를 선언하는 문장 앞으로는 이동할 수 없다.\
\- 코드 조각을 참조하는 요소의 뒤로는 이동할 수 없다.\
\- 코드 조각에서 참조하는 요소를 수정하는 문장을 건너뛰어 이동할 수 없다.\
\- 코드 조각이 수정하는 요소를 참조하는 요소를 건너뛰어 이동할 수 없다.

2\. 코드 조각을 원래 위치에서 잘라내어 목표 위치에 붙여 넣는다.

3\. 테스트 한다.

## 🧷 예시

코드 조각을 슬라이드 할 때는 무엇을 슬라이드 할지와 슬라이드 할 수 있는지 여부를 확인해야 한다.

### 📍 코드 순서가 바뀌면 겉보기 동작이 달라지는가?

지역 변수만을 수정하는 상대적으로 쉬운 예

```javascript
const pricingPlan = retrievePricingPlan();
const order = retreiveOrder();
const baseCharge = pricingPlan.base;
let charge;
const chargePerUnit = pricingPlan.unit;
const units = order.unitsl
let discount;
charge = baseCharge + units + chargePerUnit;
let discountableUnits = Math.max(units - pricingPlan.discountThreshold, 0);
discount = discountableUnits * pricingPlan.discountFactor;
if (order.isRepeat) discount += 20;
charge = charge - discount;
chargeOrder(charge);
```

몇 가지 순서를 옮겨 보자.

```javascript
const pricingPlan = retrievePricingPlan();
const baseCharge = pricingPlan.base;
let charge;
const chargePerUnit = pricingPlan.unit;

// 사용할 때 처음 선언 (부수효과X, 변수 참조X)
const order = retreiveOrder();
const units = order.unitsl


let discountableUnits = Math.max(units - pricingPlan.discountThreshold, 0);

// 사용할 때 처음 선언 (부수효과X, 변수 참조X)
let discount;
discount = discountableUnits * pricingPlan.discountFactor;

// 변수를 수정하는 일이 없다.
charge = baseCharge + units + chargePerUnit;

if (order.isRepeat) discount += 20;
charge = charge - discount;
chargeOrder(charge);
```

<details>

<summary>부수효과가 없는 것은 어떻게 알까?</summary>

명령-질의 분리 원칙을 지켜 코딩하면 값을 반환하는 함수는 모두 부수효과가 없음이 확실하다.

* 메서드는 명령만을 실행하거나, 어떠한 질의에 대한 반환하거나 둘 중 하나의 동작만을 수행해야함

</details>

## 🧷 예시: 조건문이 있을 때의 슬라이드

```javascript
let reuslt;
if (availableResources.length === 0) {
  result = createResource();
  allocatedResources.push(result);
} else {
  result = availableResources.pop();
  allocatedResources.push(result);
}
return result;
```

중복된 문장들을 조건문 밖으로 슬라이드 하자.

```javascript
let reuslt;
if (availableResources.length === 0) {
  result = createResource();
} else {
  result = availableResources.pop();
}
allocatedResources.push(result);
return result;
```
