export class LoadingService {
private _blocked$ = new BehaviorSubject<boolean>(false);
blocked$ = this._blocked$.asObservable();
block() {
this._blocked$.next(true);
}
unblock() {
this._blocked$.next(false);
}
}
Angular나 React 프로젝트에서 RxJS를 사용할 때 위와 같은 코드 패턴을 많이 보셨을 겁니다.
특히 변수명에 $와 _가 붙어 있는 경우가 단순히 스타일 문제가 아니라 코드 가독성과 역할 명확화를 위한 관례입니다.
1. $의 의미: Observable임을 나타냄
blocked$처럼 변수명 끝에 $가 붙은 이유는 "이 변수는 Observable이다"라는 걸 직관적으로 알리기 위해서입니다.
예시
blocked$ = this._blocked$.asObservable();
- 이 blocked$는 BehaviorSubject<boolean>에서 .asObservable()을 통해 외부에 노출된 읽기 전용 Observable입니다.
- $가 붙어 있으므로 이 값을 직접 next() 하지 않고 .subscribe() 하거나 async pipe로 구독하는 용도로 사용해야 함을 암시합니다.
장점
- 직관적인 타입 파악: blocked$만 봐도 이 값이 Observable임을 알 수 있음
- 사용자의 오용 방지: 외부에서 .next()를 호출할 수 없도록 제한
2. _의 의미: 내부에서만 사용하는 프라이빗 변수
_blocked$와 같이 앞에 _가 붙은 변수는 일반적으로 클래스 내부에서만 사용되는 private 변수임을 나타냅니다.
예시
private _blocked$ = new BehaviorSubject<boolean>(false);
- _blocked$는 BehaviorSubject로 직접 next()를 호출할 수 있는 주체이며, 외부에 노출되지 않습니다.
- 이처럼 프라이빗하게 선언하고, public 인터페이스로는 blocked$를 노출하는 게 이상적입니다.
함께 쓰는 이유: 읽기 전용 옵저버블 구조 만들기
이 구조는 흔히 RxJS에서 상태를 캡슐화할 때 사용하는 패턴입니다.
// 내부에서는 subject로 제어
private _state$ = new BehaviorSubject<State>(initialState);
// 외부에서는 observable로 읽기만 가능
public readonly state$ = this._state$.asObservable();
- 이렇게 하면 외부에서는 state$를 subscribe 하거나 async pipe로 바인딩할 수만 있고, 불변성(Immutability)을 보장할 수 있습니다.
예시: 로딩 상태 처리
LoadingService는 컴포넌트 어디서든 로딩 상태를 제어하고 구독할 수 있게 합니다.
// 컴포넌트에서
this.loadingService.blocked$.subscribe(isBlocked => {
if (isBlocked) {
// Block UI
} else {
// Unblock UI
}
});
// HTTP 호출 시
this.loadingService.block();
this.http.get('/api/data').subscribe({
next: () => this.loadingService.unblock(),
error: () => this.loadingService.unblock()
});
표 정리
| 네이밍 | 의미 | 예시 |
| blocked$ | Observable임을 나타냄 | readonly state$: Observable |
| _blocked$ | 내부 Subject (값을 변경할 수 있음) | private _blocked$ = new BehaviorSubject<boolean>() |
'개발 공부' 카테고리의 다른 글
| MCP (Model Context Protocol) (3) (1) | 2025.06.17 |
|---|---|
| MCP (Model Context Protocol) (1) (11) | 2025.06.12 |
| Chrome DevTools (1) | 2025.05.25 |
| SCSS 중첩 선택자: .parent { .children {} } 와 & > .children {}의 차이 (0) | 2025.05.18 |
| 얕은 복사, 깊은 복사 (1) | 2025.05.10 |