Frontend/함수형 코딩 스터디

[함수형코딩] chapter 4 , 5 정리본

<zinny/> 2023. 6. 11. 20:58
728x90

chapter 4 액션에서 계산 빼내기 

 

함수형 프로그래머는 

  1. 테스트하기 쉽게 만들고, 
  2. 재사용하기 쉽게 만들어야 합니다
    • 전역변수 제거
    • DOM 업데이트와 비즈니스 규칙을 분리
    • 함수에서 결괏값을 리턴
    • 등등등..

 

액션과 계산, 데이터를 구분하는 방법

//전역 변수는 변경 가능하기 때문에 액션!
var shopping_cart = [] 
var shopping_cart_total = 0 

function add_item_to_cart(name, price){
	//전역 변수를 변경 하는 것 액션!
	shopping_cart.push({
    	name: name,
        price: price
    });
    
    calc_cart_total()
}


//무료 배송비 계산하기 (구매 합계가 20달러 이상이면 무료 배송)
function update_shopping_icon(){
	var buy_button = get_but_button_don();
    
    for(var i = 0; i < buy_butto.lenght; i++){
    	var button = buy_button[i];
        var item = button.item;
        
        if(item.price + shipping_cart_total >= 20)
        	//dom을 바꾸는 것은 액션!
        	button.show_free_shopping_icon();
        else
        	//dom을 바꾸는 것은 액션!
        	button.hide_free_shopping_icon();
    }
}


//세금 계산하기 (장바구니의 합계가 달라질때마다 세금을 다시 계산) 
function update_tax_dom(){
	//dom을 바꾸는 것은 액션!
	set_tex_dom(shopping_cart_total * 0.01);
}


//장바구니의 모든 제품의 갯수 더하고 반영하기
function calc_cart_total(){
	shopping_cart_total = 0;
    
    for(var i = 0; i < shoppping_cart.length; i++){
    	var item = shopping_cart[i];
        shopping_cart_total +=. item.price;
    }
    
    set_cart_total_dom()
    update_shopping_icons();
    update_tax_dom();
}

 

함수에는 입력과 출력이 있습니다

  • 입력 : 함수가 계산을 하기 위한 외부 정보 
  • 출력 : 함수 밖으로 나오는 정보가 어떤 동작

함수를 부르는 이유는 결과가 필요하지만 결과를 얻기 위해서는 입력이 필요합니다. 

  • 명시적 입력 : 인자 
  • 암묵적 입력 : 인자 외 다른 입력
  • 명시적 출력 : 리턴 값
  • 암묵적 출력 : 리턴 값 외 다른 출력

예시

let total = 0;

//amout = 명시적 입력
function add_to_total (amount){
	//전역 변수를 읽는 것 암묵적 입력 ,콘솔을 찍는 것 암묵적 출력
	console.log("old total : " + total );
    //전역 변수를 바꾸는것 암묵적 출력
    total += amount 
    //리턴 값은 명시적 출력
    return total
}

함수에 암묵적 입력과 출력을 없애면 계산이 되고, 암묵적 입력은 함수의 인자로 변경하고 암묵적 출력은 함수의 리턴 값으로 바꾸면 됩니다.

 

tip: 암묵적 입력과 출력은 부수 효과라고 부르며, 함수의 주요 기능이 아닙니다.

 

액션에서 계산을 빼내는 과정

  • 계산에 해당하는 코드를 분리
  • 입력값은 인자로 출력값은 리턴값으로 바꿈

서브루틴 추출하기를 통한 리팩터링

=> 동작을 유지하며 코드를 바꾸는 것 

function calc_cart_total(){
    calc_total()
    set_cart_total_dom()
    update_shopping_icons();
    update_tax_dom();
}

function calc_total(){
	shopping_cart_total = 0;
    
    for(var i = 0; i < shoppping_cart.length; i++){
    	var item = shopping_cart[i];
        shopping_cart_total +=. item.price;
    }
}

여전히 두개의 출력과 하나의 입력이 있고, 모든 입력과 출력은 암묵적이기 때문에 명시적 입출력으로 바꿔야 합니다!

 

암묵적 출력 두개를 명시적 출력으로 변경

function calc_cart_total(){
    shopping_cart_total = calc_total()
    set_cart_total_dom()
    update_shopping_icons();
    update_tax_dom();
}

function calc_total(){
	//지역변수로 변경 
	var total = 0;
    
    for(var i = 0; i < shoppping_cart.length; i++){
    	var item = shopping_cart[i];
        total +=. item.price;
    }
    return total;
}

 

암묵적 입력을 함수인자로 바꾸기

function calc_cart_total(){
    shopping_cart_total = calc_total(shoppint_cart)
    set_cart_total_dom()
    update_shopping_icons();
    update_tax_dom();
}

//인자를 받아서 사용하는 방식으로 변경
function calc_total(cart){
	//지역변수로 변경 
	var total = 0;
    
    for(var i = 0; i < cart.length; i++){
    	var item = cart[i];
        total +=. item.price;
    }
    return total;
}

이제는 calc_total() 함수는 계산이 되었습니다! 모든 입력은 인자이고 모든 출력은 리턴 값 입니다!

 

계산 추출을 단계별로 알아보기 

  1. 계산 코드를 찾아 빼냅니다
  2. 새 함수에 암묵적 입력과 출력을 찾습니다. 
  3. 암묵적 입력은 인자로 암묵적 출력은 리턴값으로 변경합니다!

여기서 인자와 리턴값은 바뀌지 않는 불변값이라는게 중요합니다. 리턴값이 나중에 바뀐다면 암묵적 출력이 됩니다. 또한 인자로 받은 값이 바뀔수 있다면 암묵적 입력입니다. 

 

chapter4에서는 액션에서 계산을 빼내는 방법에 대해서 알게 되었고, 함수형 원칙을 사용하면 액션은 줄어들고 계산은 늘어나게 된다는 것을 배웠습니다 

chapter 5 더 좋은 액션 만들기

 

기존에 배운 것으로 액션에서 계산으로 리팩터링 하는 과정은 매우 기계적이여서 좋은 구조를 만들기 위해서는 사람의 손길이 필요합니다!

 

암묵적 입력과 출력은 적을수록 좋습니다. 

  • 암묵적 입력 : 인자가 아닌 모든 입력
  • 암묵적 출력 : 리턴값이 아닌 모든 출력
  • 암묵적 입력과 출력을 줄이면 테스트하기 쉽고 재사용하기 좋습니다

 

설계는 엉켜있는 코드를 푸는 것이다

  • 함수는 작으면 작을수록 재사용하기 쉽습니다. 
  • 작은 함수는 쉽게 이해 가능하고 유지보수 하기 쉽습니다. 
  • 작은 함수는 테스트 하기 좋습니다. 

 

카피-온-라이트 패턴 빼내기

배열을 복사해서 복사본을 가지고 작업을 하는 부분은 장바구니에 추가하는 작업뿐만 아니라 다양한 곳에서 사용 할 수있게 됩니다. 

장바구니와 제품에서만 쓸 수 있는 함수가 아니라 어떤 배열이나 항목에도 사용할 수 있도록 이름을 변경 함으로써 

재사용 가능한 utiity 함수가 되었습니다.

 

//기존
function add_item9cart, item){
	let new_cart = cart.slice();
    new_cart.push(item);
    return new_cart
}


//새로 작성
function add_element_last(arrary,  elem){
	let new_array = array.slice();
    new_array.push(elem);
    return new_array
}

 

104p연습문제 

function update_shopping_icon(){
	let buy_button = get_buy_button_don();
    
    for(let i = 0; i < buy_butto.lenght; i++){
    	let button = buy_button[i];
        let item = button.item;
        
        let isShow = has_free_shopping(item.price, shipping_cart_total);
        show_free_shoping_icon(button, isShow);
    }
}

function gets_free_shipping_with_item(cart, item){
	let new_cart = add_item(cart, item);
    return get_free_shopping_icon(new_cart);
}

function has_free_shopping(price, total_amount){
	if(prcie + total_amount >= 20) 
    	true
    else
    	false
}

function show_free_shoping_icon(button, isShow){
	if(isShow)
    	button.show_free_shopping_icon();
    else
    	button.hide_free_shopping_icon();
}

 

chapter5에서는 암묵적 입력과 출력을 제거해서 재사용하기 좋은 코드를 만들고 더 좋은 설계를 하는 법에 대해서 배웠습니다.

 

728x90