User라는 추상 클래스를 정의해볼게요. User 클래스는 name, age라는 인자를 받고 getRole이라는 추상 함수를 포함합니다!
❎도전
abstract class User {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
abstract getRole(): string;
}
✅정답
abstract class User {
constructor(public name: string, public age: number) {}
abstract getRole(): Role;
}
💡고찰
Member라는 클래스를 정의해보겠습니다. Member는 User를 상속받아요!
❎도전
class Member extends User {
constructor(public name: string, public age: number) {
super(name, age);
}
getRole(): Role {
return Role.MEMBER;
}
}
✅정답
class Member extends User {
constructor(name: string, age: number) {
super(name, age);
}
getRole(): Role {
return Role.MEMBER;
}
}
💡고찰
Book이라는 클래스를 정의해보겠습니다. 도서관에는 당연히 책이 있어야겠죠?
책은 이름, 저자, 출판일로 구성이 됩니다
❎도전
class Book {
constructor(name: string, author: string, publicationDate: number) {}
}
✅정답
class Book {
constructor(
public title: string,
public author: string,
public publishedDate: Date
) {}
}
💡고찰
RentManager라는 인터페이스를 정의해볼게요. 이 친구는 도서관이 꼭 갖추어야 할 기능을 정의한 명세서입니다.
❎도전
interface RentManager {
add(): void;
delete(): void;
borrow(): void;
return(): void;
}
✅정답
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;
}
💡고찰
RentManager를 구현하는 Library 클래스를 만들어보겠습니다
getBooks 함수는 books를 깊은 복사해서 던져주세요.
외부에서 books를 수정하는 것을 방지하기 위함이에요.
❎도전
class Library implements RentManager {
private books: Book[] = []
getBooks(): Book[] {
return [];
}
}
✅정답
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, removeBook는 사서만 호출할 수 있게 해주세요.
removeBook(user: User, book: Book): void {
if (user.getRole() !== Role.LIBRARIAN) {
console.log('올바르지 않은 요청입니다.');
return;
}
}
✅정답
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는 유저만 호출 할 수 있게 해주세요.
rentBook에서는 다른 책을 대여한 유저는 책을 대여할 수 없어야 해요.
❎도전
rentBook(user: User, book: Book): void {
if (user.getRole() !== Role.MEMBER) {
console.log('올바르지 않은 요청입니다.');
return;
}
}
✅정답
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}] 책을 빌렸습니다.`);
}
}
💡고찰
name
을 키로, book
을 값으로 지정하여 map에 넣어줌.returnBook에서는 책을 빌린 사람들만 반납할 수 있게 해주세요.
❎도전
returnBook(user: User, book: Book): void {
if (user.getRole() !== Role.MEMBER) {
console.log('올바르지 않은 요청입니다.');
return;
}
}
✅정답
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}] 책을 빌린적이 없어요!`);
}
}
}
💡고찰