아래 코드를 보자, 동작(Action) 이 있는 코드다.
let total = 0;
let item = [
{name : '새우깡', price: 100},
{name : '고래밥', price: 200},
{name : '꼬북칩', price: 300},
{name : '하이트맥주', price: 400},
];
const getTotalAmount = () => {
for(let i = 0; i < 4; i++) {
total += item[i].price;
}
console.log(`total: ${total}`)
};
getTotalAmount();
getTotalAmount 는 total에 item 배열의 price 값을 모두 더하는 간단한 함수.
위 코드에서 getTotalAmount 의 특징은
1. 암묵적인 입/출력이 있다.
- 암묵적 입력 : item
- 암묵적 출력 : total
2. 실행 횟수와 시점에 영향을 받는다.
- getTotalAmount 를 두번 호출한다면 item 배열의 요소를 두번 순회, total 값은 2000 이 된다.
때문에, getTotalAmount 는 '동작' 이고, getTotalAmount 의 유지보수 및 테스트를 위해서는 코드 전체를 확인한 후,
item 과 total 의 값 변경에 신경쓰며 작업해야한다.
작은 프로젝트에서야 저렇게 하는게 빠르고, 신경쓸 부분도 적기 때문에 상관이 없지만,
프로젝트가 증가하고, 같이 일할 사람들이 생길수록 저런 부분은 복잡성을 증가시키고, 여러 개발자들이 같은 작업을 계속하게된다.
(암묵적 입/출력 분석 및 상태 변경 처리 등...)
위 코드에서 암묵적 입/출력을 명시적 입/출력으로만 변경하여도, 유지보수 시 작업의 복잡도를 줄일 수 있다.
//getTotalAmountCalc 의 계산버전
const getTotalAmountCalc = (itemList) => {
let result = 0;
for(let i = 0; i < 4; i++) {
result += itemList[i].price;
}
return result;
}
getTotalAmountCalc 함수가 갖는 특징
1. 명시적인 입/출력이 생김
- 입력: itemList
- 출력: result
2. 실행 횟수와 시점의 영향을 받지 않음
- 100 번을 실행해도 itemList 가 같으면 항상 같은 값이 출력됨
위 1,2 번의 특징으로 인해 갖는 장점
1. 코드 테스트 부하가 상대적으로 감소
- 입력값에만 영향을 받으므로, 개발자가 원하는 특정 상황에서 테스트 가능
2. 유지보수 시 공수 감소
- 문서에는 '입력' 과 '출력' 타입 및 동작만 기술하면, 이후 개발자는 입출력만 신경써서 개발하면 된다.
(정 못믿겠으면, 개발 전에 테스트용 입력값 갖고 테스트만 하면됨.)
위 1,2 번의 특징으로 인해 갖는 단점
1. 코드량 증가
- 함수 첫부분 선언코드, 마지막의 return 코드
2. 메모리 추가사용
- 함수 안의 지역변수 선언, 지금은 작은 사이즈라 상관없지만, 크기가 자꾸 커지면???
단점이 없지는 않지만, 향후 정리할 '얕은 복사' 와 '방어적 복사' 등을 사용하고,
요즘 GC 들은 많은 부분에서 최적화가 이루어지고 있기 때문에, 기가바이트 급의 대용량이 아니라면,
저 단점들은 '투자' 의 개념으로 생각하는게 좋지 않을까 한다.
결론
동작을 계산으로 바꾸는 첫번째 방법 - 입/출력을 명시적으로 선언하라
=> 비지역 변수 read 는 함수의 파라미터로, 비지역변수 write 는 함수의 리턴값으로 바꿀 것.
'프로그래밍 > 함수형 코딩' 카테고리의 다른 글
함수형 코딩 - 3. 동작을 계산으로 바꾸는 두번째 방법 (1) | 2022.09.12 |
---|---|
함수형 코딩(Grokking Simplicity) - 1. 개념 (0) | 2022.09.12 |