배워서 남 주자

디자인 패턴 - Flyweight 패턴

미래에서 온 개발자 2023. 10. 29. 12:18

Flyweight 패턴

  • 비슷한 객체를 대량으로 만들어야 할 때 메모리를 절약할 수 있게 해주는 유용한 패턴 
  • 동일한 객체 인스턴스를 여러 번 사용할 수 있도록 하는 패턴으로, 새 복사본을 생성하는 대신 flyweight factory 또는 캐시에서 실제 객체를 공유한다. 이렇게 하면 객체를 생성하는 동안 메모리와 시간을 절약할 수 있다. 
  • flyweight는 객체의 set에 대한 공유 인스턴스 역할을 하므로 중복 복사본을 만들지 않고도 해당 객체에 접근할 수 있다. 
  • flyweight 패턴은 반드시 고유해야 하는 객체가 아닌 객체를 생성할 수 있는 방법을 제공한다. 이러한 예시로는 문자열이나 이미지처럼 일반적으로 사용되는 항목이 있다. 

 

 

예제 코드) 책을 추가할 수 있는 앱 

- 모든 책은 title, author, isbn 속성을 가지고 있다.

- 하지만 도서관은 보통 같은 책을 한 권만 가지고 있는 것이 아니라 여러 권을 보유하고 있다. 

- 동일한 책에 대한 새로운 클래스를 매번 생성하는 것이 아니라, 하나의 책을 의미하는 Book 클래스의 인스턴스를 여러 개 만들도록 한다. 

 

class Book {
	constructor(title, author, isbn) {
    	this.title = title;
        this.author = author;
        this.isbn = isbn;
    }
}

 

- books라는 리스트에 새로운 책을 추가하는 기능을 구현해 보자. 

- 기존에 등록된 isbn이 있다면 새로운 Book 인스턴스를 만들 필요가 없기 때문에 해당 책이 이미 존재하는지 먼저 검사를 한다.

const books = new Map();

const creatBook = (title, author, isbn) => {
	const existingBook = books.has(isbn);
    
    if (existingBook) {
    	return books.get(isbn);
    }
    
    // 등록되지 않은 isbn일 때만 새로운 책 인스턴스를 만들고, 이를 리스트에 등록한다.
    const book = new Book(title, author, isbn);
    book.set(isbn, book);
    
    return book;
}

 

- 위의 createBook 함수는 새로운 책을 만들 때 사용할 수 있다. 

- 앞서 언급한 대로 도서관은 동일한 책을 여러 권 보유할 수 있다. 이제 같은 책을 여러 권 추가할 수 있는 addBook 함수를 만들어보자.

- addBook 함수에서는 책 인스턴스를 새로 만들거나 이미 존재하는 경우를 고려하여 이전에 구현한 createBook 함수를 호출한다. 

- 사본의 개수를 추적하기 위해 bookList 배열을 만들어 도서관이 가지고 있는 모든 책을 포함시킨다.

 

const bookList = []

const addBook = (title, author, isbn, availability) => {
	const book = {
    	...createBook(title, author, isbn),
        availability,
    }
    
    bookList.push(book);
    return book;
}

- 이제 사본을 추가할 때마다 Book 인스턴스를 새로 만드는 대신, 이미 존재하는 책일 경우 해당 인스턴스를 재사용하도록 구현했다. 

- 아래는 이 함수를 이용하여 3종류의 책 다섯 권을 추가하는 예제이다. 다섯 권의 책을 추가했지만 Book 인스턴스는 3개만 만들었다. 

 

addBook('Harry Potter', 'JK Rowling', 'AB123', false)
addBook('Harry Potter', 'JK Rowling', 'AB123', true)
addBook('To Kill a Mockingbird', 'Harper Lee', 'CD345', true)
addBook('To Kill a Mockingbird', 'Harper Lee', 'CD345', false)
addBook('The Great Gatsby', 'F. Scott Fitzgerald', 'EF567', false)

console.log("Total amount of copies: ", bookList.length); // 5
console.log("Total amount of books: ", books.size); // 3

 

 

📚 참고 자료

https://www.ramotion.com/blog/frontend-design-patterns