TokenService는 왜 static이어야 했을까? 객체지향을 넘나드는 JS 설계 회고
2025. 5. 12. 23:49
728x90

JavaScript에서 class로 바꾸면서 static을 사용하는 이유

최근에 작성한 코드에서 기존 함수 기반 설계를 class 구조로 전환하면서 static 키워드를 사용하게 되었다. 이 과정에서 왜 static을 사용해야 했는지, 언제 static이 유용한지를 직접 느끼고 정리해본다.


1. 클래스 기반 구조로 전환한 이유

기존에는 다음과 같은 순수 함수 구조로 코드를 구성했었다.

function generateToken() { ... }
function verifyToken(token) { ... }

하지만 점점 기능이 늘어나면서

  • 함수가 서로 강하게 연관되고
  • 네임스페이스 충돌이 걱정되고
  • 유지보수와 테스트가 어려워지면서

관련 로직을 하나의 책임 단위(class)로 묶는 구조로 변경하였다.

class TokenService {
  static generate() { ... }
  static verify(token) { ... }
}

이제 TokenService.generate()로 명확한 맥락과 의도를 전달할 수 있다.


2. static을 사용한 이유

클래스를 만들었지만, 굳이 인스턴스를 생성하지 않아도 되는 기능들이 많았다. 

  • 토큰 발급, 검증, 암호화, 파싱 등은 상태(state)를 가지지 않음
  • 모든 메서드는 입력 → 출력만 있는 순수 로직

이런 경우 굳이 객체를 new로 만들지 않고, 클래스 자체에서 바로 사용할 수 있도록 static 키워드를 붙였다.

TokenService.generate();  // OK
const t = new TokenService();
t.generate();             // 비효율적, 불필요한 인스턴스

3. 언제 static을 써야 할까?

상황 static 사용 적합 여부

내부에 상태 없음  사용 권장
인스턴스 생성 의미 없음  사용 권장
헬퍼, 유틸리티 함수  static에 최적화
인스턴스 간 고유 동작 필요  일반 메서드로 분리
의존성 주입 등 DI 구조 필요  일반 메서드 권장

 

예: UserFactory.create() / HashUtil.compare() / TokenService.verify()

이처럼 기능적으로 객체에 귀속되지만, 상태가 없는 경우에는 static 메서드가 설계상 더 명확하고 테스트도 쉬워진다.


4. 장점과 한계

 장점

  • 인스턴스 없이 직접 사용 가능 (성능, 간결성)
  • 순수 함수와 잘 어울림
  • 테스트, mocking이 쉬움

 한계

  • 상속 시 override 어려움
  • 상태 관리, 의존성 관리에는 적합하지 않음

5. 나의 회고

  • 처음엔 class 내부 함수에 무조건 this를 써야 할 것 같았지만, 그럴 필요가 없다는 걸 알게 됐다
  • static은 객체로 만들지 않아야 더 명확해지는 책임을 표현할 수 있는 도구였다
  • 앞으로도 기능 단위로 묶되, 상태가 없다면 적극적으로 static을 고려할 예정

 요약

포인트 설명

class로 감싼 이유 관련 기능들을 모아 응집도 있는 구조로 만들기 위해
static으로 만든 이유 상태가 없고, 인스턴스를 만들 필요가 없기 때문
언제 쓰는가? 유틸성 메서드, 순수 함수, 팩토리 로직 등

 

객체지향은 객체를 만들지 않는 선택도 포함한다. static은 그 균형의 도구다.

728x90
반응형