issues
search
wldnswldnswl
/
IknowJS
You Don't Know JS 스터디
1
stars
1
forks
source link
[쏙쏙] 18장
#207
Closed
Seulwoo
closed
3 months ago
Seulwoo
commented
6 months ago
18장. 반응형 아키텍처와 어니언 아키텍처
두 아키텍처 패턴은 독립적입니다
반응형과 어니언 패턴
서로 다른 단계에서 사용
반응형 아키텍처 : 순차적 액션 단계
어니언 아키텍처 : 서비스의 모든 단계
함께 사용할 수도 있고 따로 사용할 수도 있음#204
반응형 아키텍처
코드에 나타난 순차적 액션의 순서를 뒤집습니다
효과와 그 효과에 대한 원인을 분리해서 코드에 복잡하게 꼬인 부분을 풀 수 있다
어니언 아키텍처
웹 서비스나 온도 조절 장치 같은 현실 세계와 상호작용하기 위한 서비스 구조를 만든다
함수형 사고를 적용한다면 자연스럽게 쓸 수 있다
변경에 대한 원인과 효과가 강력하게 결합
장바구니에 관한 UI를 추가할 때마다 고쳐야하는 곳이 늘어난다 => 전통적인 n*m 문제
장바구니를 바꾸는 n가지 방법 * 장바구니를 표시하는 m 곳
한쪽에 뭔가를 추가하면 다른 쪽에 있는 것을 변경하거나 복제해야 함
반응형 아키텍처를 사용하여 해결 가능
n 액션과 m 액션이 결합된 것을 분리
반응형 아키텍처는 무엇인가요?
반응형 아키텍처 : 애플리케이션을 구조화하는 방법
핵심 원칙 : 이벤트에 대한 반응으로 일어날 일을 지정
웹 서비스와 UI에 잘 어울린다
웹 서비스는 웹 요청 응답에 일어날 일을 지정하고 UI는 버튼 클릭과 같은 이벤트 응답에 일어날 일을 지정 => 이벤트 핸들러
반응형 아키텍처의 절충점
반응형 아키텍처는 코드에 나타난 순차적 액션의 순서를 뒤집는다
X를 하고 Y를 하는 대신, X가 일어나면 언제나 Y를 한다
언제 어떻게 사용할지를 잘 판단
원인과 효과가 결합한 것을 분리합니다
어떤 경우에는 원인과 효과를 분리하면 코드가 읽기 어려워지지만 코드가 더 유연하고 하려는 것을 정확히 표현할 수 있음
여러 단계를 파이프라인으로 처리합니다
액션과 계산을 조합할 수 있음
타임라인이 유연해집니다
순서를 표현하는 방법을 뒤집으면 타임라인이 유연해집니다
유연성이 기대하지 않은 실행 순서로 이어진다면 좋지 않을 수도 있음
익숙해진다면 더 짧은 타임라인을 만들 수 있음
셀은 일급 상태입니다
ValueCell
스프레드시트에서 영향을 받은 이름
어떤 셀의 값이 바뀌면 그에 대한 반응으로 스프레드 시트 함수가 다시 계산함
function ValueCell (initialValue)
var currentValue = initialValue;
return {
val: function() { return currentValue; },
update : function(f) { var oldValue = currentValue; var newValue = f(oldValue); currentValue = newValue; }
};
하나의 값과 두 개의 동작
val : 값을 읽음
update : 현재 값을 바꿈
전역 변수 shoppingCart 를 ValueCell 로 바꿈
값을 변경하기 위해 직접 사용하지 않고 메서드를 호출
ValueCell 을 반응형으로 만들 수 있습니다
상태가 바뀔 때마다 무언가를 하도록 만들기 => 감시자 개념 추ㄹ가
ValueCell
var watchers = [];
update 함수 내부
if (oldValue != newValue) { forEach (watchers, function(watcher) { watcher(newValue); } }
addWatcher 함수 리턴
addWatcher : function(f) { watchers.push(f); }
감시자가 추가되어 장바구니가 바뀔 때 할 일을 지정할 수 있음
감시자의 다른 이름
감시자. 이벤트 핸들러. 옵저버. 콜백. 리스터
셀이 바뀔 때 배송 아이콘을 갱신할 수 있습니다
ValueCell에 update_shipping_icons 를 감시자로 등록
shopping_cart.addWatcher(update_shipping_icons);
장바구니가 바뀔 때 항상 배송 아이콘이 갱신됨
코드를 고치고 나서 알게 된 두 가지 사실
핸들러 함수가 더 작아짐 ( 원래 하던 것보다 더 적은 일을 함 )
아이콘을 직접 갱신하는 책임이 감시자로 넘어감
장바구니를 바꾸는 모든 핸들러에서 update_shipping_icons 를 부르지 않아도 됨 ( 추가,삭제,변경 )
add_item_to_cart 핸들러에서 DOM을 갱신하는 부분을 하나 없앰
FormulaCell은 파생된 값을 계산합니다
이미 있는 셀에서 파생한 셀을 만들어 다른 셀의 변화가 감지되면 값을 다시 계산
function FormulaCell (upstreamCell, f)
var myCell = ValueCell(f(upstreamCell.val());
upstreamCell.addWatcher(function(newUpstreamValue) {
myCell.update(function(currentValue) { return f(newUpstreamValue); });
return { val: myCell.val, addWatcher: myCell.addWatcher };
FormulaCell은 값을 직접 바꿀 수 없음. 감시하던 상위 셀 값이 바뀌면 FormulaCell 값이 바뀜
FormulaCell을 감시할 수 있기 대문에 FormulaCell 이 total이라면 total 값이 바뀔 때 실행할 액션을 추가할 수 있음
고친 코드
cart_total = FormulaCell(shipping_cart, calc_total);
cart_total.addWatcher(set_cart_total_dom);
cart_total.addWather(update_tax_dom);
함수형 프로그래밍과 변경 가능한 상태
변경 가능한 상태를 잘 관리해야 함
ValueCell의 update() 메서드를 사용하면 현재 값을 항상 올바르게 유지할 수 있음 ( 다른 타임라인에서 읽거나 쓰는 순서를 보장하지는 않지만 ??? )
항상 계산을 넘겨서 update 하기 때문
ValueCell을 일관되게 유지하기 위한 안내
올바른 값으로 초기화한다
update()에는 계산을 전달
계산은 올바른 값이 주어졌다면 올바른 값을 리턴해야 함
반응형 아키텍처가 시스템을 어떻게 바꿨나요
어떤 것이 바뀔 때 실행되는 핸들러를 만듬
반응형 아키텍처가 코드에 주는 3가지 영향
원인과 효과가 결합된 것을 분리한다
여러 단계를 파이프라인으로 처리한다
타임라인이 유연해진다
원인과 효과가 결합한 것을 분리합니다
현재 장바구니라는 조건
장바구니 상태는 언제나 바뀔 수 있고 장바구니 상태가 바뀔 대마다 아이콘을 갱신해야 한다는 뜻
일반적인 아키텍처
제품 추가 => 전역 변수에 장바구니 제품 추가 => 아이콘 업데이트
제품 삭제 => 전역 변수에 장바구니 제품 삭제 => 아이콘 업데이트
장바구니 비우기 => 전역 변수 장바구니 비우기 => 아이콘 업데이트
모든 UI 이벤트 핸들러에 같은 코드를 넣어야 함
반응형 아키텍처
제품 추가 => 전역 변수에 장바구니 제품 추가
제품 삭제 => 전역 변수에 장바구니 제품 삭제
장바구니 비우기 => 전역 변수 장바구니 비우기
전역 장바구니 변경 => 배송 아이콘 업데이트
원인과 효과가 결합한 것을 분리할 수 있음
어떤 이유로든 장바구니가 바뀔 때 배송 아이콘을 갱신
결합의 분리는 원인과 효과의 중심을 관리합니다
장바구니를 바꾸는 방법 5 / 장바구니가 바뀔 때 해야 할 액션 4
장바구니가 바뀔 때 해야 할 일이 추가 => 장바구니를 바꾸는 코드를 모두 고쳐야 함
장바구니를 바꾸는 방법을 추가 => 추가한 코드에 장바구니가 바뀔 때 할 일을 모두 추가해야 함
원인과 결과가 모두 연결되어 있기 때문에 관리해야 할 것이 20개
원인과 효과를 분리하여 해결
5 * 4 를 5 + 4로
여러 단계를 파이프라인으로 처리합니다
반응형 아키텍처도 간단한 액션과 계산을 조합해 복잡한 동작을 만들 수 있음
조합된 액션은 파이프라인과 같음
데이터가 각 파이프라인으로 들어가 각 단계에서 처리됨 ???
파이프라인은 반응형 프레임워크를 사용해 구현하기도 함
Promise 액션과 계산을 조합
타임라인이 유연해집니다
일반적인 긴 타임라인 => 짧은 타임라인 여러 개
공유하는 자원이 없으면 타임라인이 많아져도 문제가 없음
장바구니 ValueCell은 감시자를 호출할 때 현재 값을 넘겨주기 대문에 감시자 함수가 직접 장바구니 값을 읽지 않아도 됨 => 장바구니를 전역변수로 사용하지 않아도 됨
DOM을 갱신할 때도 FormulaCell을 직접 읽지 않아도 됨. 자신의 DOM만 갱신하면 됨
타임라인은 서로 다른 자원을 사용하기 때문에 안전함
또 다른 아키텍처 패턴
어니언 아키텍처 : 서비스 전체를 구성하는데 사용하기 때문에 바깥 세계와 상호작용 하는 부분을 다룬다
함수형 사고를 적용한다면 자연스럽게 쓸 수 있음
인터렉션 -> 도메인 -> 언어 계층 순서로 원 모양
어니언 아키텍처는 무엇인가요?
인터랙션 계층 : 바깥 세상에 영향을 주거나 받는 액션
도메인 계층 : 비즈니스 규칙을 정의하는 계산
언어 계층 : 언어 유틸리티와 라이브러리
규칙 세 가지
현실 세계와 상호작용은 인터랙션 계층에서 해야 함
계층에서 호출하는 방향은 중심 방향
계층은 외부에 어떤 계층이 잇는지 모름
다시보기 : 액션과 계산, 데이터, 계층형 설계
스킵
전통적인 계층형 아키텍처
전통적인 아키텍처로 웹 API를 만들 때 계층 개념을 사용하지만 어니언 아키텍처의 계층과는 다름
웹 인터페이스 계층 : 웹 요청을 도메인으로 바꾸고 도메인을 웹 응답으로 바꾼다
도메인 계층 : 애플리케이션 핵심 로직으로 도메인 개념에 DB 쿼리나 명령이 들어간다
데이터베이스 계층 : 시간에 따라 바뀌는 정보를 저장한다
함수형 아키텍처
전통형 아키텍처와 함수형 아키텍처 비교
데이터베이스 계층과 도메인 계층의 관계
함수형 아키텍처는 도메인 계층이 데이터베이스 계층에 의존하지 않음. 데이터베이스 동작은 값을 바꾸거나 데이터베이스에 접근하기 때문에 액션임
액션과 계산을 구분하는 선. 라이브러리나 언어 기능과 계산을 구분하는 선을 그려 함수형 아키텍처를 표현할 수 있음
데이터베이스는 변경 가능하고 접근하는 것을 모두 액션으로 만듬 => 데이터베이스를 도메인과 분리하는 것이 중요
웹 핸들러 -> 데이터베이스 //// 도메인동작 1... 2
도메인동작 1. 2 -> 라이브러리 -> 잦바스크립트
변경과 재사용이 쉬워야 합니다
어니언 아키텍처 는 인터랙션 계층을 바꾸기 쉬움 ( 가장 위에 있어서 )
도메인이 데이터베이스나 웹 요청에 의존하지 않기 때문에 인터랙션 계층에 속하는 데이터베이스나 서비스 프로토콜은 쉽게 바꿀 수 있음
전형적인 아키텍처에서 도메인 규칙은 데이터베이스를 부르지만 어니언 아키텍처는 같은 일을 다른 방식으로 처리
전형적인 아키텍처
계층은 순서대로 쌓여있음
웹 요청은 핸들러가 처리
핸들러는 데이터베이스에 접속하고 클라이언트에 응답하기 위해 가장 높은 웹 계층으로 결과를 리턴
도메인 규칙이 데이터베이스에서 합계를 가져와 처리. 데이터베이스에 접근하기 때문에 계산이 아님
어니언 아키텍처
웹 서버와 핸들러, 데이터베이스는 인터랙션 계층에 속함
cart_total은 제품 가격을 가지고 장바구니 합계를 만드는 계산
장바구니가 어디에서 왔는지 모르지만 핸들러가 데이터베이스에서 장바구니를 가져와 도메인에 전달하는 역할을 함
계층 구조가 다르지만 같은 일을 할 수 있음
인터랙션 계층에서 값을 가져오고 도메인 계층에서 값을 합산
도메인 규칙은 도메인 용어를 사용합니다
프로그램의 핵심 로직을 도메인 규칙 / 비즈니스 규칙이라고 함
어떤 데이터베이스를 사용할지 결정하는 코드
새 데이터베이스에 제품 이미지가 있다면 사용하고 없다면 이전 데이터베이스에서 가져옴
데이터베이스를 읽는 액션이 두 개 있음
var image = newImageDB.getImage('123'); if (image == undefined) image = oldImage.getImage('123');
이 코드는 비즈니스에 중요한 부분이라고 해도 도메인 규칙이 아니다
이유 ) 도메인 규칙에는 제품, 이미지, 가격, 할인과 같은 용어를 사용함. 데이터베이스는 도메인을 나타내는 용어가 아님 !!
가독성을 따져봐야 합니다
가독성을 결정하는 요소
사용하는 언어
레거시 코드와 스타일
사용하는 라이브러리
개발자들의 습관
어니언 아키텍처는 가장 이상적인 모습
설계자의 역할은 현실 세계의 문제와 이상적인 다이어그램 사이를 균형있게 유지하는 것
코드의 가독성
개발 속도
시스템 성능
18장. 반응형 아키텍처와 어니언 아키텍처
두 아키텍처 패턴은 독립적입니다
변경에 대한 원인과 효과가 강력하게 결합
반응형 아키텍처는 무엇인가요?
반응형 아키텍처의 절충점
셀은 일급 상태입니다
ValueCell 을 반응형으로 만들 수 있습니다
셀이 바뀔 때 배송 아이콘을 갱신할 수 있습니다
FormulaCell은 파생된 값을 계산합니다
함수형 프로그래밍과 변경 가능한 상태
반응형 아키텍처가 시스템을 어떻게 바꿨나요
원인과 효과가 결합한 것을 분리합니다
결합의 분리는 원인과 효과의 중심을 관리합니다
여러 단계를 파이프라인으로 처리합니다
타임라인이 유연해집니다
타임라인은 서로 다른 자원을 사용하기 때문에 안전함
또 다른 아키텍처 패턴
어니언 아키텍처는 무엇인가요?
다시보기 : 액션과 계산, 데이터, 계층형 설계
전통적인 계층형 아키텍처
함수형 아키텍처
변경과 재사용이 쉬워야 합니다
도메인 규칙은 도메인 용어를 사용합니다
가독성을 따져봐야 합니다