반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 시스템설계면접예시
- cypressBDD
- formik react-query submitting not working
- 디자인패턴
- file not found Error
- git squash
- 시스템설계면접
- s3이미지다운로드됨
- git commit 협업
- Git commit 합치기
- 가상면접으로대규모시스템
- gitsquash
- formik submitting not working
- 리팩터링2판테스트
- 시스템설계
- 리액트구글애널리틱스
- 가상면접3장
- FirebaseAnalytics
- react
- 가상면접2장
- 시스템설계방법
- cypress React
- 전략패턴
- 시스템설계면접팁
- 테스트코드책
- react-ga
- 헤드퍼스트전략패턴
- awss3
- 리팩토링2판4장
- git commit merge
Archives
- Today
- Total
mingg IT
[함수형 프로그래밍] 5장 더 좋은 액션 만들기 본문
1장 부터 읽었을때 가장 인상깊고 재밌었던 장이다.
함수 내 코드를 분리할때 어떤 기준으로 나눌지 애매한 경우가 많았는데 비즈니스 규칙, 계산, 액션 등으로 나누는 기준을 알려줌
수정 전 (4장 코드)
var shopping_cart = [];
var shopoing_cart_total = 0;
function add_item_to_cart(name, price) {
shopping_cart = add_item(shopping_cart, name, price);
calc_cart_total();
}
function calc_cart_total() {
shopping_cart_total = calc_total(shopping_cart);
set_cart_total_dom();
update_shipping_icons();
update_tax_dom();
}
function update_shipping_icons() {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
if (gets_free_shipping(shopping_cart_total, item.price)) button.show_free_shipping_icon();
else button.hide_free_shipping_icon();
}
}
function update_tax_dom() {
set_tax_dom(calc_tsx(shopoing_cart_total));
}
function add_item(cart, name, price) {
var new_cart = cart.slice();
new_cart.push({
name: name,
price: price,
});
return new_cart;
}
function calc_total(cart) {
var total = 0;
for (var i = 0; i < cart.length; i++) {
var item = cart[i];
total += item.price;
}
return total;
}
function gets_free_shipping(total, item_price) {
return item_price + total >= 20;
}
function calc_tax(amount) {
return amount * 0.1;
}
비즈니스 요구사항 변경됨
장바구니에 담긴 제품을 주문할 때 무료배송인지 판단함
var shopping_cart = [];
var shopoing_cart_total = 0;
function add_item_to_cart(name, price) {
shopping_cart = add_item(shopping_cart, name, price);
calc_cart_total();
}
function calc_cart_total() {
shopping_cart_total = calc_total(shopping_cart);
set_cart_total_dom();
update_shipping_icons();
update_tax_dom();
}
function update_shipping_icons() {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
// 수정된 부분
var new_cart = add_item(shopping_cart, item.name, item.price);
if (gets_free_shipping(new_cart)) button.show_free_shipping_icon();
else button.hide_free_shipping_icon();
}
}
function update_tax_dom() {
set_tax_dom(calc_tsx(shopoing_cart_total));
}
function add_item(cart, name, price) {
var new_cart = cart.slice();
new_cart.push({
name: name,
price: price,
});
return new_cart;
}
function calc_total(cart) {
var total = 0;
for (var i = 0; i < cart.length; i++) {
var item = cart[i];
total += item.price;
}
return total;
}
// 수정된 부분
function gets_free_shipping(cart) {
return calc_total(cart) >= 20;
}
function calc_tax(amount) {
return amount * 0.1;
}
함수형 프로그래밍 원칙
- 암묵적 입력과 출력은 적을수록 좋다
- 설계는 엉켜있는 코드를 푸는 것이다 (재사용, 유지보수, 테스트 하기 쉽도록)
암묵적 입력과 출력을 줄인 결과
// var shopping_cart = [];
// var shopoing_cart_total = 0;
// C: cart에 대한 동작
// I: item에 대한 동작
// B: 비즈니스 규칙
function add_item_to_cart(name, price) {
shopping_cart = add_item(shopping_cart, name, price);
// calc_cart_total(shopping_cart);
var total = calc_total(shopping_cart);
set_cart_total_dom();
update_shipping_icons(shopping_cart);
update_tax_dom(total);
}
function calc_cart_total(cart) {
var total = calc_total(cart);
set_cart_total_dom();
update_shipping_icons(cart);
update_tax_dom(total);
}
// c, i , b
function update_shipping_icons(cart) {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
var new_cart = add_item(cart, item.name, item.price);
if (gets_free_shipping(new_cart)) button.show_free_shipping_icon();
else button.hide_free_shipping_icon();
}
}
function update_tax_dom(total) {
set_tax_dom(calc_tsx(total));
}
// c, i
function add_item(cart, name, price) {
var new_cart = cart.slice();
new_cart.push({
name: name,
price: price,
});
return new_cart;
}
// c, i, b
function calc_total(cart) {
var total = 0;
for (var i = 0; i < cart.length; i++) {
var item = cart[i];
total += item.price;
}
return total;
}
// b
function gets_free_shipping(cart) {
return calc_total(cart) >= 20;
}
// b
function calc_tax(amount) {
return amount * 0.1;
}
- 전역변수를 제거하고
- calc_cart_total 함수가 하는일이 너무 많아서 calc_cart_total함수 내에 있는 add_item_to_cart 함수로 옮겨줌
- cart, item, 비즈니스 규칙에 관한 부분은 분리하기 시작해야함
add_item 함수 분리하여 좋은 설계 만들기
// c, i , b
function update_shipping_icons(cart) {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
var new_cart = add_item(cart, make_cart_item(item.name, item.price));
if (gets_free_shipping(new_cart)) button.show_free_shipping_icon();
else button.hide_free_shipping_icon();
}
}
// c
function add_item(cart, item) {
var new_cart = cart.slice();
new_cart.push(item);
return new_cart;
}
function make_cart_item(name, price) {
return {
name: name,
price: price,
};
}
- 기존 add_item은 cart, item 구조 모두를 알고있어야 했음
- make_cart_item에서 아이템에 대한 구조를 알도록 한뒤, add_item은 item의 구조를 알 필요없도록 분리함
add_item -> add_element_last 공통 유틸로 변경
// c, i , b
function update_shipping_icons(cart) {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
var new_cart = add_item(cart, make_cart_item(item.name, item.price));
if (gets_free_shipping(new_cart)) button.show_free_shipping_icon();
else button.hide_free_shipping_icon();
}
}
function add_item(cart, item) {
return add_element_last(cart, item);
}
function add_element_last(array, elem) {
var new_array = array.slice();
new_array.push(elem);
return new_array;
}
function make_cart_item(name, price) {
return {
name: name,
price: price,
};
}
- 이제부터 add_item 카피-온-라이트를 사용해 배열에 항목을 추가하는 함수가 되었기 때문에 은 공통 유틸로 관리함
중간 점검 코드
// var shopping_cart = [];
// var shopoing_cart_total = 0;
// C: cart에 대한 동작
// I: item에 대한 동작
// B: 비즈니스 규칙
// A: 배열 유틸
function add_item_to_cart(name, price) {
shopping_cart = add_item(shopping_cart, make_cart_item(name, price));
// calc_cart_total(shopping_cart);
var total = calc_total(shopping_cart);
set_cart_total_dom();
update_shipping_icons(shopping_cart);
update_tax_dom(total);
}
function calc_cart_total(cart) {
var total = calc_total(cart);
set_cart_total_dom();
update_shipping_icons(cart);
update_tax_dom(total);
}
// c, i , b
function update_shipping_icons(cart) {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
var new_cart = add_item(cart, make_cart_item(item.name, item.price));
if (gets_free_shipping(new_cart)) button.show_free_shipping_icon();
else button.hide_free_shipping_icon();
}
}
// A
function add_item(cart, item) {
return add_element_last(cart, item);
}
// A
function add_element_last(array, elem) {
var new_array = array.slice();
new_array.push(elem);
return new_array;
}
// I
function make_cart_item(name, price) {
return {
name: name,
price: price,
};
}
function update_tax_dom(total) {
set_tax_dom(calc_tsx(total));
}
// c, i, b
function calc_total(cart) {
var total = 0;
for (var i = 0; i < cart.length; i++) {
var item = cart[i];
total += item.price;
}
return total;
}
// b
function gets_free_shipping(cart) {
return calc_total(cart) >= 20;
}
// b
function calc_tax(amount) {
return amount * 0.1;
}
- 배열 유틸리티 관련된 A를 주석으로 추가함
update_shipping_icons 수정
// c, i , b
function update_shipping_icons(cart) {
var buttons = get_buy_buttons_dom();
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var item = button.item;
var new_cart = add_item(cart, make_cart_item(item.name, item.price));
var hasFreeShipping = gets_free_shipping_with_item(new_cart, item);
set_free_shipping_icon(hasFreeShipping);
}
}
function gets_free_shipping_with_item(cart, item) {
var new_cart = add_item(cart, item);
return gets_free_shipping(new_cart);
}
function set_free_shipping_icon(button, isShown) {
if (isShown) button.show_free_shipping_icon;
else button.hide_free_shipping_icon;
}
- 너무 많은 기능을 하는 update_shipping_icons를 수정
- 아이템으로 카트를 계산하는 부분, 버튼을 보여주는 부분을 각각 나눔
요점
- 일반적으로 암묵적 입력과 출력은 인자와 리턴값으로 바꿔 없에는 것이 좋다
- 설계는 엉켜있는 것을 푸는 것임. 풀려있는 것은 언제든지 다시 합칠 수 있음
- 엉켜있는 것을 풀어 각 함수가 하나의 일만 하도록 하면, 개념을 중심으로 쉽계 구성 할 수 있음
- 8장에 다시 설계에 대한 내용을 살펴볼 예정
- 장바구니기능에 버그가 숨어있다함..
'FrontEnd' 카테고리의 다른 글
[함수형 프로그래밍] 7장 신뢰할 수 없는 코드를 쓰면서 불변성 지키기 (0) | 2023.10.14 |
---|---|
[함수형 프로그래밍] 6장 변경 가능한 데이터 구조를 가진언어에서 불변성 유지하기 (0) | 2023.10.14 |
[함수형 프로그래밍] 4장 액션에서 계산 빼내기 (2) | 2023.10.09 |
[함수형 프로그래밍] 3장 액션과 계산, 데이터의 차이를 알기 (0) | 2023.09.23 |
[함수형 프로그래밍] 2장 현실에서의 함수형 사고 (0) | 2023.09.17 |
Comments