아키텍처에 대한 이야기가 나오면 위 단어들이 빠지지 않는다.
위 단어들이 무엇을 의미하고 왜 분리하여 알아야 하는지 알아본다.
비즈니스 로직은 말 그대로 비즈니스와 관계되어 있다.
'출금' 기능을 구현한다고 하면 다음 처럼 구현할 수 있을 것이다:
if (amount <= balance) { // 잔고가 충분하면
balance -= amount; // 잔고 감소
let sql = 'update...'; // 데이터베이스 잔고 업데이트 쿼리
query(sql, balance); // 쿼리 전송
} else {
alert('not enough balance.'); // 충분하지 않으면 사용자에게 알림
}
기능을 동작시키기 위한 모든 코드가 비지니스 로직이 된다.
그럼 일반 로직은 무엇인가?
위 예시 코드에는 나타나지 않은 DB에 연결하거나, Server를 실행 시키는 등
시스템이 동작하기 위한 코드들이다. 따라서 비즈니스와 별개로 반드시 필요한 코드다.
비즈니스 로직이 구현에 가깝다면 비즈니스 룰은 말 그대로 원칙이다.
위 예시 코드에서 '잔고가 충분하면', '잔고 감소', '사용자에게 알림'과 같이 자연어로 표현 가능하다.
클라이언트가 제시한 비즈니스 규칙을 개발자가 비즈니스 로직으로 구현할 수 있다.
비즈니스 로직이 비즈니스 룰을 설명 할 수도 있다.
아키텍처를 설계하면 유지보수의 문제에 직면하게 된다. 좋은 아키텍처는 좋은 유지보수성을 나타낸다.
어느날 클라이언트가 '잔고가 없어도 사용자에게 알리지 않게 해주세요.'라고 말했다 치자. 문제는
비즈니스 룰과 관련된 코드: '잔고가 충분하면', '잔고 감소', '사용자에게 알림'
그렇지 않은 코드: '데이터베이스 잔고 업데이트 쿼리', '쿼리 전송'
위 코드들이 서로 섞여 있어서 가독성이 그렇게 좋지 않다는 것이다. 따라서 어떤 코드를 변경해야 사용자에 대한 알림이 가지 않는지, 그리고 해당 코드는 몇 줄에 걸쳐 나타나는지 분석해야 한다. 쿼리 수정을 할 때도 이런 문제는 발생한다.
Clean Architecture는 비즈니스를 규칙을 명시적으로 작성하고 비즈니스 로직과 계층을 분리하고, 비즈니스 로직을 작게 만들도록 한다.
계층을 분리함으로써 의존성을 분리하여 테스트하기 쉽게 한다. 잘 분리된 코드는 분석하기도 쉽다.
Stub, Mock, Fake 등 테스트 도구들을 통칭하는 말.
결과가 정해진 기능(function).
항상 같은 결과만 나오게 한다거나, 특정 인자에는 특정 결과만 반환하도록 한다.
NodeJS에는 SinonJS가 그 역할을 한다.
오브젝트를 흉내내는 것.
의존하는 모듈이 사이드이펙트를 가지거나, 아직 구현이 안되어서 로직을 흉내내어 동작케하는 것.
예:
비슷한 단어: Throttle
debounce는 클라이언트에서는 사용자 입력의 노이즈를 제거하는 용어로 주로 사용된다. 보통 서버 요청할 때 버튼이 두 번 눌러져서 요청이 두 번 발생하는 동시 요청 문제가 흔하다. 서버에서 동시 호출에 대한 방어 로직을 구현하는 것과 별개로, 클라이언트에서도 debounce를 이용한 UI 문제를 해결해 볼 수 있다.
kotlin은 Flow의 operator로 debounce()
를 제공한다.
flow {
emit(1)
delay(90)
emit(2)
delay(90)
emit(3)
delay(1010)
emit(4)
delay(1010)
emit(5)
}.debounce(1000)
// 3, 4, 5
첫 번째 값을 가져오고, 새 값이 설정한 시간 이내로 발생한 거라면 제거한다.
ReactiveX에서도 debounce operator를 제공한다.
only emit an item from an Observable if a particular timespan has passed without it emitting another item
RX 구현체에선 debounce
, throttle
함께 많이 사용하는 것으로 보인다.
Language-Specific Information:
- RxClojure
- RxCpp
- RxGroovy debounce throttleWithTimeout
- RxJava 1․x debounce throttleWithTimeout
- RxJava 2․x debounce throttleWithTimeout
- RxJS debounce debounceWithSelector throttleWithTimeout
- RxKotlin debounce throttleWithTimeout
- RxNET Throttle
- RxPHP throttle
- RxPY debounce throttle_with_selector throttle_with_timeout
- Rxrb
- RxScala debounce throttleWithTimeout
- RxSwift debounce throttle