You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
모자액 12장 날짜와 시간 API를 읽고 관련해서 더 공부할 내용을 찾아보다가 새로운 키워드를 발견하여 선정하였습니다.
자신이 생각한 답변은 무엇인가?
FlyWeight 패턴이란 무엇인가?
FlyWeight Pattern은 재사용 가능한 객체 인스턴스를 공유시켜 메모리 사용량을 최소화 하는 패턴이다.
프로그램에서 많은 객체를 생성해야 하는 경우, 객체들의 일부 데이터를 공유하여 메모리 소비를 줄이는 방식으로 동작한다.
간단히 말하면, 캐시(Cache) 개념을 코드로 패턴화한 것으로 보면 되는데, 자주 변하는 속성(extrinsit)과 변하지 않는 속성 (intrinsit)을 분리하고 변하지 않는 속성을 캐시하여 재사용해 메모리 사용량을 줄이는 방식이다.
두 가지 개념
Intrinsit(내재 상태)
객체 간에 공유할 수 있는 불변 데이터. 날짜/시간 API에서는 시간대나 로케일 정보가 여기에 해당한다.
Extrinsit(외재 상태)
객체마다 다른 데이터로, 공유할 수 없다. 예를 들어, 특정 날짜나 시간 값이 여기에 해당한다.
FlyWeight 패턴에서는 내재 상태를 가진 객체를 FlyWeight 객체라고 부르며, 별도의 풀(Pool)에 저장하여 재사용한다.
클라이언트는 필요한 FlyWeight 객체를 FlyWeightFactory로부터 받아와 사용하고, 사용 후에는 다시 풀에 반환한다.
예시
나무 심기 예시
숲을 만들기 위해서 지형(Terrain)에 나무 객체들을 심으려고 한다.
이 나무(Tree) 객체에 대해 필요한 데이터는 다음과 같다.
나무 종류
mesh
나무껍질 텍스쳐
잎 텍스쳐
위치 매개변수 (x,y)
나무의 종류에도 여러가지가 있으며, 나무의 형태를 결정하는 mesh와 texture 그리고 나무가 어느 지형에 심어질지에 대한 x,y 위치 매개 변수가 필요하다.
적용 코드 (FlyWeight 객체 정의)
// ConcreteFlyWeightfinalclassTreeModel {
// 메시, 텍스쳐 총 사이즈longobjSize = 90; // 90MBStringtype; // 나무 종류Objectmesh; // 메쉬Objecttexture; // 나무 껍질 + 잎사귀 텍스쳐publicTreeModel(Stringtype, Objectmesh, Objecttexture) {
this.type = type;
this.mesh = mesh;
this.texture = texture;
// 나무 객체를 생성하여 메모리에 적재했으니 메모리 사용 크기 증가Memory.size += this.objSize;
}
}
// UnsahredConcreteFlyweightclassTree {
// 죄표값과 나무 모델 참조 객체 크기를 합친 사이즈longobjSize = 10; // 10MB// 위치 변수doubleposition_x;
doubleposition_y;
// 나무 모델TreeModelmodel;
publicTree(TreeModelmodel, doubleposition_x, doubleposition_y) {
this.model = model;
this.position_x = position_x;
this.position_y = position_y;
// 나무 객체를 생성하였으니 메모리 사용 크기 증가Memory.size += this.objSize;
}
}
이때 Tree 클래스와 TreeModel 간의 관계를 맺어주어야 하는데, 상속(Heritance)을 통해서 해줘도 되고 합성(Composition)을 통해서 맺어도 된다.
그리고 ConcreteFlyWeight인 TreeModel 클래스를 final화시켜 불변 객체로 만들어준다.
TreeModel의 texture과 mesh는 중간에 변경될 일이 없기 때문이다.
FlyWeight 팩토리 정의
// FlyweightFactoryclassTreeModelFactory {
// Flyweight Pool - TreeModel 객체들을 Map으로 등록하여 캐싱privatestaticfinalMap<String, TreeModel> cache = newHashMap<>(); // static final 이라 Thread-Safe 함// static factory methodpublicstaticTreeModelgetInstance(Stringkey) {
// 만약 캐시 되어 있다면if(cache.containsKey(key)) {
returncache.get(key); // 그대로 가져와 반환
} else {
// 캐시 되어있지 않으면 나무 모델 객체를 새로 생성하고 반환TreeModelmodel = newTreeModel(
key,
newObject(),
newObject()
);
System.out.println("-- 나무 모델 객체 새로 생성 완료 --");
// 캐시에 적재cache.put(key, model);
returnmodel;
}
}
}
FlyWeight Factory의 핵심은 다음과 같다.
FlyWeightPool : HashMap 컬렉션을 통해 Key와 나무 모델 객체를 저장하는 캐시 저장소 역할
getinstance 메소드 : Pool에 가져오고자 하는 객체가 있는지 검사를 하여 있으면 그대로 반환, 없으면 새로 생성
// FlyweightFactoryclassTreeModelFactory {
// Flyweight Pool - TreeModel 객체들을 Map으로 등록하여 캐싱privatestaticfinalMap<String, TreeModel> cache = newHashMap<>(); // static final 이라 Thread-Safe 함// static factory methodpublicstaticTreeModelgetInstance(Stringkey) {
// 만약 캐시 되어 있다면if(cache.containsKey(key)) {
returncache.get(key); // 그대로 가져와 반환
} else {
// 캐시 되어있지 않으면 나무 모델 객체를 새로 생성하고 반환TreeModelmodel = newTreeModel(
key,
newObject(),
newObject()
);
System.out.println("-- 나무 모델 객체 새로 생성 완료 --");
// 캐시에 적재cache.put(key, model);
returnmodel;
}
}
}
Client 최적화 하기
기존 Terrain 클래스의 나무를 생성하는 render() 메소드의 내부 로직은 단순히 사용자로부터 매개변수를 받아 그대로 tree 객체를 생성할 뿐이다.
하지만 기존 tree 객체를 따로 TreeModel로 나누고, TreeModelFactory까지 생성했으니 이제 이들을 이용하는 클라이언트의 코드를 최적화 작업을 진행해 주어야 한다.
최적화 작업은 아래와 같다.
TreeModel에서 공유되고 있는 나무 모델 객체를 가져온다. (없다면 생성)
가져온 나무 모델과 좌표값을 이용해 나무 객체를 새로 생성한다.
// ClientclassTerrain {
// 지형 타일 크기staticfinalintCANVAS_SIZE = 10000;
// 나무를 렌더릴publicvoidrender(Stringtype, doubleposition_x, doubleposition_y) {
// 1. 캐시 되어 있는 나무 모델 객체 가져오기TreeModelmodel = TreeModelFactory.getInstance(type);
// 2. 재사용한 나무 모델 객체와 변화하는 속성인 좌표값으로 나무 생성Treetree = newTree(model, position_x, position_y);
System.out.println("x:" + tree.position_x + " y:" + tree.position_y + " 위치에 " + type + " 나무 생성 완료");
}
}
문제가 무엇인가?
FlyWeight 패턴이란 무엇인가? (날짜, 시간 API와 관련 없음)
왜 이런 문제를 선정하였는가?
모자액 12장 날짜와 시간 API를 읽고 관련해서 더 공부할 내용을 찾아보다가 새로운 키워드를 발견하여 선정하였습니다.
자신이 생각한 답변은 무엇인가?
FlyWeight 패턴이란 무엇인가?
두 가지 개념
Intrinsit(내재 상태)
Extrinsit(외재 상태)
FlyWeight 패턴에서는 내재 상태를 가진 객체를 FlyWeight 객체라고 부르며, 별도의 풀(Pool)에 저장하여 재사용한다.
클라이언트는 필요한 FlyWeight 객체를 FlyWeightFactory로부터 받아와 사용하고, 사용 후에는 다시 풀에 반환한다.
예시
나무 심기 예시
나무의 종류에도 여러가지가 있으며, 나무의 형태를 결정하는 mesh와 texture 그리고 나무가 어느 지형에 심어질지에 대한 x,y 위치 매개 변수가 필요하다.
적용 코드 (FlyWeight 객체 정의)
이때 Tree 클래스와 TreeModel 간의 관계를 맺어주어야 하는데, 상속(Heritance)을 통해서 해줘도 되고 합성(Composition)을 통해서 맺어도 된다.
그리고 ConcreteFlyWeight인 TreeModel 클래스를 final화시켜 불변 객체로 만들어준다.
TreeModel의 texture과 mesh는 중간에 변경될 일이 없기 때문이다.
FlyWeight 팩토리 정의
FlyWeight Factory의 핵심은 다음과 같다.
Client 최적화 하기
기존 Terrain 클래스의 나무를 생성하는 render() 메소드의 내부 로직은 단순히 사용자로부터 매개변수를 받아 그대로 tree 객체를 생성할 뿐이다.
하지만 기존 tree 객체를 따로 TreeModel로 나누고, TreeModelFactory까지 생성했으니 이제 이들을 이용하는 클라이언트의 코드를 최적화 작업을 진행해 주어야 한다.
최적화 작업은 아래와 같다.
결과
The text was updated successfully, but these errors were encountered: