캡슐화 연습 1

이 글과 하위 글들은 [객체 지향 프로그래밍 입문]에 관한 내용입니다. 최범균님의 인프런의 강의를 보며 정리한 내용으로 문제가 될시 삭제하겠습니다.

tsconfig.json -> { "strictPropertyInitialization": false }

문제 1

캡슐화 해보자.

function authenticate(id: string, pw: string) {
  const mem: Member = findOne(id);
  if(mem == null) return AuthResult.NO_MATCH;

  if(mem.getVerificationEmailStatus() !== 2) {
    return AuthResult.NO_EMAIL_VERIFIED;
  }

  if(passwordEncoder.isPasswordValid(mem.getPassword(), pw, mem.getId())) {
    return AuthResult.SUCCESS;
  }

  return AuthResult.NO_MATCH;
}

문제 1 해답

문제 2

캡슐화 해보자.

class Movie {
  static REGULAR = 0;
  static NEW_RELEASE = 1;
  #priceCode: number;

  constructor(priceCode: number) {
    this.#priceCode = priceCode;
  }

  getPriceCode(): number {
    return this.#priceCode;
  }
}


class Rental {
  #movie: Movie;
  #daysRented: number;

  constructor(movie: Movie, daysRented: number) {
    this.#movie = movie;
    this.#daysRented = daysRented;
  }

  getFrequentRenterPoints(): number {
    if (
      this.#movie.getPriceCode() === Movie.NEW_RELEASE &&
      this.#daysRented > 1
    ) {
      return 2;
    } else {
      return 1;
    }
  }
}

문제 2 정답

처음엔 나도 isNewRelease만 생각했었는데, 아래처럼 해당 로직을 통째로 캡슐화 해버려도 된다.

class Movie {
  static REGULAR = 0;
  static NEW_RELEASE = 1;
  #priceCode: number;

  constructor(priceCode: number) {
    this.#priceCode = priceCode;
  }

  getFrequentRenterPoints(daysRented: number): number {
    if (this.#priceCode === Movie.NEW_RELEASE && daysRented > 1) {
      return 2;
    } else {
      return 1;
    }
  }
}

class Rental {
  #movie: Movie;
  #daysRented: number;

  constructor(movie: Movie, daysRented: number) {
    this.#movie = movie;
    this.#daysRented = daysRented;
  }

  getFrequentRenterPoints(): number {
    return this.#movie.getFrequentRenterPoints(this.#daysRented);
  }
}

문제 3

캡슐화 해보자.

class Timer {
  startTime: number;
  stopTime: number;
}

const t = new Timer();
t.startTime = new Date().getMilliseconds();

// ...

t.stopTime = new Date().getMilliseconds();

const elaspedTime = t.stopTime - t.startTime;

문제 3 정답

class Timer {
  startTime: number;
  stopTime: number;

  start(): void {
    this.startTime = new Date().getMilliseconds();
  }

  stop(): void {
    this.stopTime = new Date().getMilliseconds();
  }

  elaspedTime(unit: "MILLISECOND") {
    switch(unit) {
      case "MILLISECOND":
        return this.stopTime - this.startTime;
    }
  }
}

const t = new Timer();
t.start();

// ...

t.stop();

const elaspedTime = t.elaspedTime('MILLISECOND');

문제 4

캡슐화 해보자.

function verifyEmail(token: string) {
  const mem: Member = findByToken(token);
  if(mem === null) throw new BadTokenException();

  if(mem.getVerificationEmailStatus() === 2) {
    throw new AlreadyVerifiedException();
  } else {
    mem.setVerificationEmailStatus(2);
  }
  // 수정 사항 DB 반영
}

문제 4 정답

class Member {
  #verificationEmailStatus: number;

  verifyEmail(): void {
    if(this.isEmailVerified()) {
      throw new AlreadyVerifiedException();  
    } else {
      this.#verificationEmailStatus = 2;
    }
  }

  isEmailVerified() {
    return this.#verificationEmailStatus === 2;
  }
}

function verifyEmail(token: string) {
  const mem: Member = findByToken(token);
  if(mem === null) throw new BadTokenException();

  mem.verifyEmail();
  // 수정 사항 DB 반영
}

Last updated