일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 고등애플
- 에릭 노이먼
- 쏙속 들어오는 함수형코딩
- 로버트 C마틴
- 유틸리티타입은 공식문서 자주 보자
- 출처 : 한입크기로 잘라먹는 타입스크립트
- 클린코드다시읽기
- 이웅모
- 나는 flux좋아...
- 자바스크립트 딥다이브
- 리엑트를 다루는 기술
- 출처는 코딩앙마
- 큰돌의 CS책
- 갈길이 멀구나
- 오종택개발자님
- https://product.kyobobook.co.kr/detail/S000001952246
- 쏙쏙 들어오는 함수형 코딩
- 출처 : 코딩애플
- 김영한쌤
- 에릭 노먼드
- 쏙쏙들어오는함수형코딩
- 출처는 코딩애플
- 쏙쏙 들어오는 함수형코딩
- 생코님Redux
- 출처 : https://www.boostcourse.org/
- 에릭노이먼
- 출처 : 코딩앙마
- 출처 : 자바스크립트 딥다이브
- 함수형 코딩
- 흥달쌤
- Today
- Total
흰둥씨의 개발장
[함수형 코딩#18] 반응형 구조 & 어니언 구조 본문
반응형 아키텍쳐
- 순차적 액션 단계에 사용
(여러 원인 + 여러가지 효과 있는 경우 사용하기 좋음 / 하나의 원인으로 a-b-c단계로 효과가 일어난다면 비추)
- "이벤트에 대해 일어날 일을 지정하는 것 (X가 일어나면 Y가 일어난다)"
- 원인과 효과를 분리해서 표기
- 파이프라인 사용(여러가지 함수를 조합해서 쓸수있음, 그래서 여러단계일때 유용)
- 타임라인이 유연해짐(순차적인 액션의 순서를 뒤집어서, 효과와 효과의 원인을 분리함)
//초기 값을 받아서 => 업데이트 할수있는 기능을 가진 함수 만들기
function ValueCell(initialValue){
let curr = initialValue;
return{
val: ()=>{
return curr;
},
update: (f)=>{
let oldValue = curr;
let newValue = f(oldValue); //콜백으로 받은 함수에 초기값넣어서
curr = newValue; //업데이트 된 값적용해서 교체함
}
};
}
//위 함수에 감시자 개념을 추가해보자
function ValueCell(initialValue){
let curr = initialValue;
let watchers = []; //감시자 목록
return {
val : ()=>{
return curr;
},
update: (f)=>{
let oldValue = curr;
let newValue = f(oldValue);
if(oldValue !== newValue){ //값이 바뀔때 모든 감시자 실행됨
curr = newValue;
forEach(watchers, (watcher)=>{
watcher(newValue);
});
}
},
addWatcher: (f)=>{ //새로운 감시자를 추가하는 메서드
watchers.push(f)
},
};
}
//ValueCell()을 일관되게 유지하기 위한 방법
//1. 올바른 값으로 초기화하기
//2. update()에는 계산을 전달해야한다(액션전달하지 않기)
//3. 계산은 in이 올바르면 out도 항상 올바르게 리턴해야한다.
//감시자 기능 들어간 ValueCell 사용해보기
//감시자는 상태가 바뀔 때마다 실행되는 기능
let shopingCart = ValueCell({}); //초기값으로 {}빈객체 할당
function addItemtoCart(name, price){
let item = make_cart_item(name, price);
shopingCart.update(()=>{ //update()메소드 호출해서 add_item실행
return add_item(cart, item);
});
let total = calc_total(shopingCart.val());//val()메소드로 초기값 할당
set_cart_total_dom(total);
update_tax_dom(total);
}
shopingCart.addWatcher(update_shipping_icons); //장바구니가 바뀔때마다 실행됨(update_shipping_icons를 감시함)
function update_shipping_icons(cart){
let buy_buttons = get_buy_buttons_dom();
for(let i = 0; i <buttons.length; i++){
let button = buttons[i];
let item = button.item;
let newCart = add_item(cart, item);
if(gets_free_shipping(newCart)){
button.show_free_shipping_icon();
} else {
button.hide_free_shipping_icon();
}
}
}
어떤 값이 바뀌면 따라서 파생된 값을 바꿔주는 기본형 FormulaCell()만들어보기
function FormulaCell(upstreamCell, f) {
let myCell = ValueCell(f(upstreamCell.val()));
upstreamCell.addWatcher((newUpstreamValue)=>{
myCell.update((curr)=>{
return f(newUpstreamValue);
});
});
return {
val: myCell.val,
addWatcher: myCell.addWatcher
}
}
함수평 프로그래밍뿐 아니라 소프트웨어는 "변경 가능한 상태"를 잘 관리해야한다.
(모든 데이터가 불변성을 유지할 수는 없기 때문에 , 상태 흐름을 잘 추적할 수 있도록 작업하기 ...어렵다...)
반응형 아키텍쳐가 바꾼 시스템의 결과
1. 원인과 효과가 결합된 것을 분리함
//일반 아키텍처 (3번의 원인으로 6개의 작업만들기 필요)
제품추가버튼클릭 제품삭제클릭 장바구니비우기클릭
| | |
v v v
전역장바구니에제품추가 전역장바구니에제품삭제 전역장바구니비우기
배송아이콘 업데이트 배송아이콘 업데이트 배송아이콘 업데이트
//반응형 아키텍쳐 (3개의 원인으로 4개의 작업만들기하면됨)
제품추가버튼클릭 제품삭제클릭 장바구니비우기클릭
| | |
v v v
전역장바구니에제품추가 전역장바구니에제품삭제 전역장바구니비우기
| | |
ㄴ -------------------------------------------> 전역 장바구니 변경
|
배송 아이콘 업데이트
2. 여러 단계를 파이프 라인으로 처리함(파이프라인 : 작은 액션과 계산을 조합한 하나의 액션)
3. 타임라인이 유연해짐 (원인과 결과가 명확해짐)
//일반적인 타임라인(원인과 효과가 불명확)
전역 장바구니에 제품 추가 -> 합계 DOM업데이트 -> 배송아이콘 업데이트 -> 세금 DOM업데이트
//분리된 타임라인 (원인으로 인한 결과가 명확)
합계DOM업데이트 (결과1)
/
전역장바구니에 제품추가(원인) - 배송아이콘업데이트 (결과2)
\
세금 DOM업데이트 (결과3)
어니언아키텍쳐
- 현실세계와 상호작용 하기 위한 서비스구조를 만드는 방법(3개의 계층으로 나눔)
- 인터랙션 계층 : 바깥세상에 영향을 주거나 받는 액션 (현실세계와 상호작용함)
- 도메인 계층 : 비즈니스 규칙을 정의하는 계산
- 언어 계층 : 언어유틸리티와 라이브러리
- 각각의 계층은 독립적이고, 계층에서 호출하는 방향은 중심방향임
계층형 아키텍쳐(전통적 아키텍처)와 함수형 아키텍처의 차이
전통적 아키텍처 | 함수형 아키텍처 |
웹인터페이스 계층 (웹서버, 웹요청을 도메인 동작으로 변환함) |
인터렉션계층 (웹서버 + 데이터베이스 + 웹핸들러) |
도메인 계층 (웹핸들러 + 데이터 베이스 기반으로 동작) |
도메인계층 (도메인 동작들) |
데이터 베이스계층 (시간에 따라 바뀌는 정보 저장) |
언어계층 (라이브러리, 자바스크립트...) |
ㄴ> 함수형 아키텍처의 인터렉션 계층 : 변경하기 쉬움 (데이터베이스나 서비스 프로토콜 쉽게 변경가능) => 액션 몰빵?
ㄴ> 함수형 아키텍처의 도메인 계층 : 전통적 아키텍처와 다르게 데이터 베이스와 웹요청에 의존하지 않음(소프트웨어 동작으로 구성됨)
=> 계산으로 바꾸기 쉬움(재사용쉬워짐, but 가독성좋다면 액션이 나은 경우도 있음)
ㄴ> 함수형 아키텍처의 언어계층 : 소프트웨어를 만들 수 있는 언어기능과 라이브러리로 구성
//인터렉션 계층에 해당하는 코드 예시
let image = newImageDB.getImage('123'); //데이터베이스를 옮겨오는 과정이라 인터렉션계층에 속함
if(image === undefined) {
image = oldImageDB.getImage('123');
}
function getWithRetries(url, retriesLeft, success, error) { //웹요청 실패시 여러번 재시도하는 로직(외부와 인터렉션)
if(retriesLeft <= 0) {
error('No more retries');
} else {
ajaxGet(url, success, function(e) {
getWithRetries(url, retriesLeft - 1, success, error);
})
}
}
내정리:
반응형 아키텍처는 재사용성을 높이는 액션, 계산들로 파이프라인 만들어서 한방에 처리 용이하고, 원인과 효과 분석에 탁월한듯 함
함수형 아키텍처는 인터렉션계층에서 데이터요청이나, 웹요청 등을 모두 처리한 후 , 도메인에서는 동작만 신경쓰면되고,
전통적 아키텍처는 도메인계층에서 데이터를 받아오고 반영시키는 동작과 로직에 필요한 동작을 함께 수행하는 것같음
'함수형 프로그래밍 > 쏙쏙 들어오는 함수형 코딩' 카테고리의 다른 글
[함수형 코딩#7] 얕은 복사 vs 깊은 복사 (0) | 2024.04.04 |
---|---|
[함수형 코딩#17] 타임라인 조율하기 (0) | 2023.07.14 |
[함수형 코딩#16] 타임라인 사이에 자원 공유하기 (0) | 2023.07.14 |
[함수형 코딩#15] 타임라인 격리/ JS thread (0) | 2023.07.13 |
[함수형 코딩#14] 중첩데이터에 함수형도구 사용 (0) | 2023.07.12 |