플라이웨이트 flyweight 패턴 - 자바스크립트 예제
요약
플라이웨이트(Flyweight) 패턴을 자바스크립트 코드와 함께 알아봅니다. 정보처리기사 대비 문제가 포함되어있습니다.
플라이웨이트 패턴 요약
| 패턴 종류 | 핵심 키워드 |
|---|---|
| 플라이웨이트 (Flyweight) | 객체 공유 , 가상 인스턴스 제공, 메모리 사용량 줄입니다. |

플라이웨이트 (Flyweight) 패턴
플라이웨이트 패턴은 많은 수의 객체를 효율적으로 지원하기 위해 객체의 공유를 통해 메모리 사용량을 줄이는 디자인 패턴입니다. '플라이웨이트'는 권투의 경량급을 의미하며, 이름처럼 객체를 가볍게 만들어 메모리 부담을 최소화하는 데 목적이 있습니다.
이 패턴은 객체의 상태를 두 가지로 분리합니다.
- 내재적 상태 (Intrinsic State): 객체 내부에서 관리되며, 여러 컨텍스트에서 공유될 수 있는 불변(immutable)의 상태입니다. 플라이웨이트 객체 내에 저장됩니다. (예: 나무의 모델, 텍스처, 색상)
- 외재적 상태 (Extrinsic State): 각 객체마다 달라질 수 있으며, 클라이언트가 관리하고 필요할 때 플라이웨이트 객체에 전달하는 상태입니다. (예: 나무의 위치(x, y 좌표), 크기)
기본 구조
- Flyweight: 공유될 객체들의 인터페이스를 정의합니다.
- ConcreteFlyweight:
Flyweight인터페이스를 구현하고, 내재적 상태를 저장합니다. 이 객체는 공유되어 재사용됩니다. - FlyweightFactory: 플라이웨이트 객체들을 생성하고 관리하는 팩토리입니다. 클라이언트가 요청한 플라이웨이트가 이미 존재하면 기존 객체를 반환하고, 없으면 새로 생성하여 풀(pool)에 저장합니다.
- Client: 외재적 상태를 관리하고,
FlyweightFactory를 통해 플라이웨이트 객체를 받아 필요한 작업을 수행합니다.
예시: 게임에서 수많은 나무 렌더링하기
수천, 수만 그루의 나무로 숲을 표현해야 하는 게임을 만든다고 가정해 봅시다. 각 나무마다 모델, 텍스처 등 무거운 데이터를 가진 객체를 생성한다면 엄청난 메모리가 소모될 것입니다. 플라이웨이트 패턴을 사용하면 이 문제를 효과적으로 해결할 수 있습니다.
먼저, 공유될 나무 모델(TreeModel)을 정의합니다.
이제 TreeModel 객체를 관리하는 TreeModelFactory를 만듭니다.
클라이언트(게임 엔진) 코드에서 팩토리를 통해 나무를 생성하고 화면에 그립니다.
출력 결과:
숲에 4그루의 나무를 심었지만, 실제로 메모리를 많이 차지하는 TreeModel 객체는 '소나무'와 '참나무' 단 2개만 생성되었습니다. '소나무' 모델은 한 번 생성된 후 계속 재사용되었습니다. 각 나무의 고유한 정보(위치, 크기 등)는 외재적 상태로 클라이언트가 직접 관리합니다.
이처럼 플라이웨이트 패턴은 공유 가능한 상태(내재적 상태)를 가진 객체를 재사용하여 메모리 사용량을 획기적으로 줄일 수 있습니다.
'가상 인스턴스'는 무슨 의미일까?
"여러 개의 가상 인스턴스를 제공해서 메모리를 절감한다"는 표현은 플라이웨이트 패턴의 핵심을 잘 나타내지만, '가상 인스턴스'라는 용어 때문에 헷갈릴 수 있습니다.
'고무 도장' 비유를 통해 쉽게 이해해 봅시다.
수천 페이지 분량의 문서에 '소나무' 그림을 계속 찍어야 한다고 상상해 보세요.
- 플라이웨이트 패턴 미적용: 나무 1,000그루를 찍으려면, 실제 '소나무' 도장 1,000개가 필요합니다. 도장을 보관할 엄청나게 큰 공간(메모리)이 필요합니다.
- 플라이웨이트 패턴 적용:
- '소나무' 모양의 고무 도장 딱 하나만 만듭니다. 이 도장이 바로 플라이웨이트 객체이며, '소나무'라는 본질적인 모양(내재적 상태)을 가집니다.
- 나무를 찍을 때마다 이 유일한 '소나무' 도장을 재사용합니다.
- 대신, 나무마다 달라지는 정보, 즉 어디에(x, y 좌표), 어떤 크기로 찍을지는 도장을 찍는 순간에 외부에서 알려줍니다. 이것이 바로 외재적 상태입니다.
여기서 '가상 인스턴스' 란, 우리 눈에 보이는 각각의 '소나무' 그림을 의미합니다. 실제 메모리에는 '소나무' 모양을 가진 객체(도장)는 단 하나만 존재하지만, [공유되는 실제 객체 1개] + [각기 다른 외부 상태(좌표, 크기)] 의 조합으로 마치 여러 개의 독립된 객체가 있는 것처럼 '보여주는' 것입니다.
게임 예제에서
TreeModel객체는 단 2개('소나무', '참나무')만 생성되었지만, 화면에는 4그루의 나무, 즉 4개의 '가상 인스턴스'가 보이는 것과 같습니다.
플라이웨이트 패턴 중요 키워드
- 객체 공유와 가상 인스턴스 제공을 통해 메모리 사용량을 줄입니다.
- 객체의 상태를 내재적 상태(공유 가능) 와 외재적 상태(공유 불가) 로 분리합니다.
- 팩토리를 사용하여 공유 객체를 관리합니다.
- 게임, 문서 편집기 등 대량의 객체를 효율적으로 다뤄야 할 때 매우 유용합니다.