logo
Published on

디자인패턴으로 이해하는 타입스크립트 클래스

Authors
  • avatar
    Name
    Bora Choi
    Twitter

클래스

  • class 키워드로 클래스를 선언한 후 extends 키워드로 다른 클래스를 상속받을 수 있다.
  • 클래스는 구체 클래스와 추상 클래스로 분류된다. 추상 클래스는 추상 메서드추상 프로퍼티를 가질 수 있다. → 추상 클래스는 인스턴스화 할 수 없고 abstract 키워드를 앞에 추가한다
  • 메서드는 private,protected,public중 한 가지의 한정자를 가질 수 있고 기본값은 public이다. 메서드는 인스턴스 메서드와 정적 메서드 두가지로 구분된다.
  • 클래스는 인스턴스 프로퍼티도 가질 수 있으며 이 프로퍼티들은 private, protected, public중 한 가지 한정자를 갖는다. 생성자의 매개변수나 프로퍼티 초기자에도 이들 한정자를 사용할 수 있다.
  • 인스턴스 프로퍼티를 선언할 때 readonly를 추가할 수 있다.

상속

템플릿 메소드 패턴

템플릿 메소드 패턴(template method pattern)은 소프트웨어 공학에서 동작 상의 알고리즘의 프로그램 뼈대를 정의하는 행위 디자인 패턴이다.알고리즘의 구조를 변경하지 않고 알고리즘의 특정 단계들을 다시 정의할 수 있게 해준다.

abstract class 아라이용하기 {
  constructor() {
    this.회원가입하기()
    this.학번인증하기()
    this.후기작성하기()
  }

  private 회원가입하기() {
    console.log('회원가입완료😊')
  }

  public abstract 학번인증하기(): void

  private 후기작성하기() {
    console.log('후기작성📝')
  }
}

class 포탈연동인증 extends 아라이용하기 {
  constructor() {
    super()
  }
  학번인증하기() {
    console.log('포탈 연동으로 학생증인증🌐')
  }
}

class 학생증인증 extends 아라이용하기 {
  constructor() {
    super()
  }
  학번인증하기() {
    console.log('학생증으로 학번인증💳')
  }
}

new 학생증인증()
new 포탈연동인증()

타입스크립트 클래스 특징

  • 구조기반 타입을 지원한다.
  • 값과 타입을 모두 선언한다.
  • this를 반환 타입으로 사용할 수 있다

this를 반환 타입으로 사용

빌더 패턴

빌더 패턴이란 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다.

class 맥북M1프로구매하기 {
  private cpu: '8코어' | '10코어' = '8코어'
  private gpu: '14코어' | '16코어' | '24코어' | '32코어' = '14코어'
  private memory: '16GB' | '32GB' = '16GB'
  private ssd: '512GB' | '1TB' = '512GB'

  constructor() {
    console.log(
      `${this.cpu}CPU/${this.gpu}GPU 프로세서를 탑재하고, ${this.memory}메모리와 ${this.ssd}의 저장공간 옵션을 선택했습니다. `
    )
  }
  cpu선택(cpu: '8코어' | '10코어' = '8코어'): this {
    this.cpu = cpu
    return this
  }

  gpu선택(gpu: '14코어' | '16코어' | '24코어' | '32코어'): this {
    this.gpu = gpu
    return this
  }

  메모리선택(memory: '16GB' | '32GB'): this {
    this.memory = memory
    return this
  }

  저장공간선택(ssd: '512GB' | '1TB') {
    this.ssd = ssd
    return this
  }
}

const book = new 맥북M1프로구매하기()
  .cpu선택('8코어')
  .gpu선택('14코어')
  .메모리선택('32GB')
  .저장공간선택('1TB')

인터페이스

타입에 이름을 지어주는 수단. 인터페이스를 통해 클래스 구현 할 때가 많음.

인터페이스 vs 타입

  • 타입 별칭은 더 일반적. 타입 별칭은 타입 표현식을 포함한 모든 타입을 표현할 수 있다. (&, | 등 타입연산자도 가능)
  • 인터페이스를 상속할 때 타입스크립트는 상속받는 인터페이스의 타입에 상위 인터페이스를 할당할 수 있는지를 확인한다.
  • 이름과 범위가 같은 인터페이스가 여러개 있다면 이들은 자동으로 합쳐진다. 같은 조건에서 타입 별칭이 여러 개라면 컴파일 타임 에러가 난다.

구현

어댑터 패턴

어댑터 패턴(Adapter pattern)은 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴으로, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해준다.

interface Electronic110V {
  콘센트연결: () => void
}

interface Electronic220V {
  전원연결: () => void
}

class 드라이기 implements Electronic110V {
  콘센트연결() {
    console.log('드라이기 전원 켜짐')
  }
}

class 에어컨 implements Electronic220V {
  전원연결() {
    console.log('에어컨 전원 켜짐')
  }
}

const 한국에서이용하기 = (electronic220V: Electronic220V) => {
  electronic220V.전원연결()
}

한국에서이용하기(new 에어컨()) //"에어컨 전원 켜짐"
//한국에서이용하기(new 드라이기) //Argument of type 'HariDryer' is not assignable to parameter of type 'Electronic220V'. Property '전원연결' is missing in type 'HariDryer' but required in type 'Electronic220V'.

class 돼지코 implements Electronic220V {
  private electronic110V: Electronic110V
  constructor(electronic110V: Electronic110V) {
    this.electronic110V = electronic110V
  }

  전원연결() {
    this.electronic110V.콘센트연결()
  }
}

const 돼지코를연결한드라이기 = new 돼지코(new 드라이기())
한국에서이용하기(돼지코를연결한드라이기) //"드라이기 전원 켜짐"

인터페이스 구현 vs. 추상 클래스 상속

  • 인터페이스는 형태를 정의하는 수단. 컴파일 타임에만 존재
  • 오직 클래스만 정의. 런타임에 자바스크립트 코드 생성. 생성자와 기본 구현을 가질 수 있으며 프로퍼티와 메서드에 접근 한정자를 지정할 수 있다.