저장을 습관화
TypeScript 연습 - 도서관 프로그램 만들기 본문
작업 환경: Windows 10, VSC
작업 목표: 도서관 관리 프로그램
주요 기능 - 권한:
도서 추가 기능 - 사서
도서 삭제 기능 - 사서
도서 대여 기능 - 유저
도서 반납 기능 - 유저
작업 기록
1. 환경 구축
$ npm init -y
$ tsc --init --rootDir ./src --outDir ./dist --esModuleInterop --module commonjs --strict true --allowJS true --checkJS true
--rootDir: 소스 파일이 들어가는 경로를 명시적으로 지정함
이번에는 ./src 디렉토리에 넣겠다고 하였음
-- outDir: 컴파일된 파일이 tsc로 되면 TS파일이 JS 파일로 나올것임
여기서는 ./dist 디렉토리에 들어가게끔 하였음
--esModuleInterop: require 구문을 사용해서 가져오던 CommonJS 방식의 모듈을 es모듈 방식의 import 구문으로 가져올 수 있게 함
package.json, tsconfig.json 파일 생성 확인
package.json 파일 내용 수정
{
...(생략)...
"scripts": {
"start": "tsc && node ./dist/index.js",
"build": "tsc --build",
"clean": "tsc --build --clean"
},
...(생략)...
}
2. /src/index.ts 파일 생성
// 역할 enum
enum Role {
LIBRARIAN, // 사서
MEMBER, // 멤버
}
// 유저 추상 클래스
abstract class User {
constructor(public name: string, public age: number) {}
abstract getRole(): Role;
}
// 멤버 클래스
class Member extends User {
constructor(name: string, age: number) {
super(name, age);
}
getRole(): Role {
return Role.MEMBER;
}
}
// 사서 클래스
class Librarian extends User {
constructor(name: string, age: number) {
super(name, age);
}
getRole(): Role {
return Role.LIBRARIAN;
}
}
// 책 클래스
class Book {
constructor(
public title: string,
public author: string,
public publishedDate: Date
) {}
}
// 책 관리 인터페이스, 도서 목록 조회, 추가, 삭제, 대여, 반납 기능
interface RentManager {
getBooks(): Book[]; // 도서관의 현재 도서 목록을 확인하는 함수
addBook(user: User, book: Book): void; // 사서가 도서관에 새로운 도서를 입고할 때 호출하는 함수
removeBook(user: User, book: Book): void; // 사서가 도서관에서 도서를 폐기할 때 호출하는 함수
rentBook(user: Member, book: Book): void; // 사용자가 책을 빌릴 때 호출하는 함수
returnBook(user: Member, book: Book): void; // 사용자가 책을 반납할 때 호출하는 함수
}
// 도서관 클래스 구현
class Library implements RentManager {
private books: Book[] = [];
// rentedBooks는 유저의 대여 이력을 관리해요!
private rentedBooks: Map<string, Book> = new Map<string, Book>();
getBooks(): Book[] {
// 깊은 복사를 하여 외부에서 books를 수정하는 것을 방지합니다.
return JSON.parse(JSON.stringify(this.books));
}
addBook(user: User, book: Book): void {
if (user.getRole() !== Role.LIBRARIAN) {
console.log("사서만 도서를 추가할 수 있습니다.");
return;
}
this.books.push(book);
}
removeBook(user: User, book: Book): void {
if (user.getRole() !== Role.LIBRARIAN) {
console.log("사서만 도서를 삭제할 수 있습니다.");
return;
}
const index = this.books.indexOf(book);
if (index !== -1) {
this.books.splice(index, 1);
}
}
rentBook(user: User, book: Book): void {
if (user.getRole() !== Role.MEMBER) {
console.log("유저만 도서를 대여할 수 있습니다.");
return;
}
if (this.rentedBooks.has(user.name)) {
console.log(
`${user.name}님은 이미 다른 책을 대여중이라 빌릴 수 없습니다.`
);
} else {
this.rentedBooks.set(user.name, book);
console.log(`${user.name}님이 [${book.title}] 책을 빌렸습니다.`);
}
}
returnBook(user: User, book: Book): void {
if (user.getRole() !== Role.MEMBER) {
console.log("유저만 도서를 반납할 수 있습니다.");
return;
}
if (this.rentedBooks.get(user.name) === book) {
this.rentedBooks.delete(user.name);
console.log(`${user.name}님이 [${book.title}] 책을 반납했어요!`);
} else {
console.log(`${user.name}님은 [${book.title}] 책을 빌린적이 없어요!`);
}
}
}
function main() {
const myLibrary = new Library();
const librarian = new Librarian("ctrs", 29);
const member1 = new Member("testCust", 30);
const member2 = new Member("booker", 28);
const book = new Book("TypeScript 문법 종합반", "강창민", new Date());
const book2 = new Book("금쪽이 훈육하기", "오은영", new Date());
const book3 = new Book("요식업은 이렇게!", "백종원", new Date());
myLibrary.addBook(librarian, book);
myLibrary.addBook(librarian, book2);
myLibrary.addBook(librarian, book3);
const books = myLibrary.getBooks();
console.log("대여할 수 있는 도서 목록:", books);
myLibrary.rentBook(member1, book);
myLibrary.rentBook(member2, book2);
myLibrary.returnBook(member1, book);
myLibrary.returnBook(member2, book2);
}
main();
3. 컴파일
$ npm run build
> 04.-class@1.0.0 build
> tsc --build
4. 실행
$ npm run start
> 04.-class@1.0.0 start
> tsc && node ./dist/index.js
대여할 수 있는 도서 목록: [
{
title: 'TypeScript 문법 종합반',
author: '강창민',
publishedDate: '2023-08-01T14:49:02.879Z'
},
{
title: '금쪽이 훈육하기',
author: '오은영',
publishedDate: '2023-08-01T14:49:02.879Z'
},
{
title: '요식업은 이렇게!',
author: '백종원',
publishedDate: '2023-08-01T14:49:02.879Z'
}
]
testCust님이 [TypeScript 문법 종합반] 책을 빌렸습니다.
booker님이 [금쪽이 훈육하기] 책을 빌렸습니다.
testCust님이 [TypeScript 문법 종합반] 책을 반납했어요!
booker님이 [금쪽이 훈육하기] 책을 반납했어요!
'공부 > TypeScript' 카테고리의 다른 글
TypeScript - class-transformer 데이터 타입 변환 (0) | 2023.09.12 |
---|---|
객체 지향 설계 원칙 - S.O.L.I.D (0) | 2023.08.01 |
객체 지향 프로그래밍 - 인터페이스 (0) | 2023.08.01 |
객체 지향 프로그래밍 - 추상 클래스 (0) | 2023.08.01 |
객체 지향 프로그래밍 - 상속 (0) | 2023.08.01 |