[구조 패턴] Flyweight 패턴
= '캐시' 를 패턴화 한 것!
객체를 가볍게 유지하여 '메모리 사용량을 줄이는' 데 집중함!
자주 변화하는 속성(extrinsit)과 변하지 않는 속성(intrinsit)을 분리
intrinsit(변하지 않는 속성): 캐시하여 재사용(메모리 사용 줄이다!). 그래서 수천, 수만 개의 객체를 효율적으로 관리 가능!
[패턴 구조]
- Flyweight : 경량 객체를 묶는 인터페이스
- ConcreteFlyweight : 공유 가능, 재사용되는 객체(intrinsic)
- UnsharedConcreteFlyweight : 공유 불가능한 객체(extrinsic)
- FlyweightFactory : 경량 객체를 만드는 공장 역할과 캐시 역할을 겸비하는 Flyweight 객체 관리 클래스
- Client : 클라이언트는 FlyweightFactory를 통해 Flyweight 타입의 객체를 얻어 사용한다.

- Intrinsic State (본질적 상태) : 객체 내부에서 공유되는 불변 정보 (ex: 나무 모양, 텍스쳐)
- Extrinsic State (외적 상태) : 인스턴스마다 변하는 정보 (ex: 나무 좌표, 색상 농도)
[장점]
- 어플리케이션에서 사용하는 메모리를 줄일 수 있다.
- 프로그램 속도 개선
[단점]
- 코드의 복잡도 증가
ex) 폭탄 피하기 게임
ㄴ 변함: 폭탄의 위치
ㄴ 변하지 않음(캐시) : 폭탄의 형태, 색
ex) 마인크래프트 필드에 나무 심기
- mesh, texture 재사용한다!
- 위치는 모두 다르다.
ㄴ ConcreteFlyweight (불변, 캐시) : Treemodel (메쉬, 텍스쳐...)
ㄴ UnsharedConcreteFlyweight (변함) : Tree (좌표값을 가지고 있음)
//공통(변하지 않음)
class TreeModel {
long objsize = 100; //100MB
String type; //나무 종류
Object mesh; //메쉬
Object texture; //나무껍질+잎사귀 텍스쳐
public Tree(String type, Object mesh, Object texture) {
...
Memory.size += this.objsize;
}
}
//변함(Unshared)
class Tree {
long objsize = 10; //10MB
//위치 변수
double position_x;
double position_y;
//나무 모델
Treemodel model;
public Tree(Treemodel model, double position_x, double position_y) {
...
Memory.size += this.objsize;
}
}
//Flyweight팩토리(관리 공장)
class TreeModelFactory {
//treemodel 객체들을 map으로 등록하여 캐싱
private static final Map<String, Treemodel> chche = new HashMap<>();
public static Treemodel getInstance(String key) {
//캐시되어 있다면
if(chche.containsKey(key)) {
return chche.get(key); //그대로 가져와 반환
}
//캐시되어있지 않다면 나무 모델 객체를 새로 생성하고 반환
else {
Treemodel m = new Treemodel (
key,
new Object();
new Object();
);
}
//캐시에 적재
chche.put(key, model) {
return model;
}
}
}
//client
class Terrain {
//지형타일 크기
static final int CANVAS_SIZE = 10000;
//나무를 렌더링
public void render(String type, double position_x, double position_y) {
//캐시되어있는 나무모델객체 가져오기
Treemodel m = Treemodelfactory.getInstance(type);
//재사용한 나무 모델 객체와 변화하는 속성인 좌표값으로 나무 생성
Tree t = new Tree(model, position_x, position_y);
}
}
//main
public class main {
public static class main(String[] args) {
//지형 생성
Terrain terrain = new Terrain();
//Oak나무 5개 생성
for(int i = 0; i<5; i++) {
terrain.render(
"Oak",
Math.random() * terrain.CANVAS_SIZE;
Math.random() * terrain.CANVAS_SIZE;
);
}
//Acacia나무 10개 생성
for(int i = 0; i<10; i++) {
terrain.render(
"Acacia",
Math.random() * terrain.CANVAS_SIZE;
Math.random() * terrain.CANVAS_SIZE;
);
}
//Jungle나무 6개 생성
for(int i = 0; i<6; i++) {
terrain.render(
"Jungle",
Math.random() * terrain.CANVAS_SIZE;
Math.random() * terrain.CANVAS_SIZE;
);
}
}
}
[실사용 사례]
- Java의 String
| String s1 = "hello" String s2 = "hello" |
* == 비교하면 true나옴!(같은 주소값을 가리킴) (hello라는 문자열 객체를 하나만 만들어 공유하기 때문에)
'Study > Design Pattern' 카테고리의 다른 글
| [Design Pattern] Mediator Pattern (중재자 패턴) (0) | 2026.06.09 |
|---|---|
| [Design Pattern] Interpreter Pattern (인터프리터 패턴) (0) | 2026.06.07 |
| [Design Pattern] Decorator Pattern (데코레이터 패턴) (0) | 2026.06.07 |
| [Design Pattern] Composite Pattern (컴포지트 패턴) (0) | 2026.06.06 |
| [Design Pattern] Bridge Pattern (브릿지 패턴) (0) | 2026.06.06 |