본문 바로가기

개발 공부

$, _name$ 네이밍 컨벤션

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>()