반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- 스프링 부트
- spring
- DIP
- 스프링 프레임워크
- springboot
- 스프링
- 생성자 주입
- @Configuration
- 스프링 부트 입문
- Javascript
- 스프링 부트 기본
- SQL
- assertThrows
- db
- java
- sqld
- JPA
- thymeleaf
- 필드 주입
- 싱글톤
- resultMap
- jdbc
- 스프링 빈
- assertThat
- 스프링부트
- kafka
- Effective Java
- 스프링 컨테이너
- mybatis
- DI
Archives
- Today
- Total
선 조치 후 분석
[Design Pattern] 구조패턴 - Flyweight 본문
728x90
반응형
SMALL
플라이웨이트 (Flyweight) 패턴
- 객체를 가볍게 만들어 메모리 사용을 줄이는 목적을 가진 패턴
- 자주 변하는 속성과 변하지 않는 속성을 분리하고 재사용하여 메모리 사용을 줄이는 구조를 설계하는 패턴
- 주로 비교적 많은 인스턴스를 가지고 있는 애플리케이션에 사용되는 패턴
- 인스턴스가 많으면 메모리를 잡아먹고 OOM (Out Of Memory) 문제가 발생할 수 있기에 이를 예방하기 위함
- 공통으로 사용하는 클래스(Flyweight)를 생성하는 팩토리 클래스(Flyweight Factory)를 만들어,
- 인스턴스를 최초 1개만 생성하고 공유하여 재사용
구조
- Flyweight : 공유하여 사용하는 클래스 또는 API
- Flyweight Factory : 인스턴스를 생성 또는 공유 (공장 역할)
- Client : Flyweight 인스턴스를 필요로 하는 클라이언트

사용시기
- 공통적인 인스턴스를 많이 생성하는 로직이 포함된 경우
- 자주 변하지 않는 속성을 재사용할 수 있는 경우
요구사항
- 편집기에 글을 쓸 수 있어야 한다.
- 편집기니까 한 글자마다 폰트와 글씨 색, 크기를 바꿀 수 있어야 한다.
플라이웨이트 (Flyweight) 패턴 적용 전
- 글자 하나를 표현한 도메인
public class Character {
private char value;
private String color;
private String fontFamily;
private int fontSize;
public Character(char value, String color, String fontFamily, int fontSize) {
this.value = value;
this.color = color;
this.fontFamily = fontFamily;
this.fontSize = fontSize;
}
}
- 편집기에 글을 입력하는 클라이언트
- 글자 하나마다 새로운 Character 인스턴스 생성
@Test
void client1() {
Character c1 = new Character('H',"yellow", "Nanum", 12);
Character c2 = new Character('I',"white", "Nanum", 12);
}
글자 하나마다 새로운 생성자를 통해 객체를 생성하게 되는데 이렇게 메모리를 잡아먹는 것을 잡아야한다.
그래서 메모리를 아끼기 위해 자주 변하는 속성과 자주 변하지 않는 속성을 분류해야 한다.
플라이웨이트 (Flyweight) 패턴 적용 후
- 문자와 색 : 자주 변하는 속성
- 글자 폰트와 크기 : 자주 변하지 않는 속성
- Character 인스턴스가 가지는 속성 중에서 자주 변하는 속성과 자주 변하지 않는 속성을 분리
- 자주 변하지 않는 '폰트와 크기'를 묶어서 클래스 선언
- 공유객체 이므로 final로 불변으로 선언
public class Font {
final String family;
final int size;
public Font(String family, int size) {
this.family = family;
this.size = size;
}
public String getFamily() {
return family;
}
public int getSize() {
return size;
}
}
- 공유받는 Font 클래스를 필드로 받는다.
public class Character {
private char value;
private String color;
private Font font;
public Character(char value, String color, Font font) {
this.value = value;
this.color = color;
this.font = font;
}
}
- Font 생성을 관리해 주는 팩토리 생성
- getFont()를 통해서 Font 생성을 하게 되면, Cache에 데이터가 있는지 먼저 검사
- Cache에 존재하면 새로 생성하지 않고 기존 인스턴스 반환
public class FontFactory {
private Map<String, Font> cache = new HashMap<>();
public Font getFont(String font) {
if(cache.containsKey(font)) {
return cache.get(font);
}else {
String[] split = font.split(",");
//폰트이름, 폰트사이즈 분리
Font newFont = new Font(split[0], Integer.parseInt(split[1]));
cache.put(font, newFont);
return newFont;
}
}
}
@Test
void client1() {
// 플라이웨이트 패턴 적용 후 테스트 코드
FontFactory fontFactory = new FontFactory();
Character c1 = new Character('H',"white",fontFactory.getFont("Nan-um,12"));
Character c2 = new Character('I',"white",fontFactory.getFont("Nan-um,12"));
System.out.println(c1.getFont()); // Flyweight.Font@41d477ed
System.out.println(c2.getFont()); // Flyweight.Font@41d477ed
// 같은 인스턴스 사용
}
Flyweight로 추출한 객체는 불변해야 하기 때문에 final로 선언되어야 한다.
불변 객체가 아니라면, 데이터 변경이 일어날 수 있기 때문에 final로 선언해 변경이 불가하도록 만들어야 한다.
싱글톤 (Singleton)과의 차이점?
- 싱글톤 패턴은 '클래스 자체'가 오직 1개의 인스턴스만을 가지도록 제한하지만.
플라이웨이트 패턴은 '팩토리'가 제어하는 것이다. - 즉, 인스턴스 생성의 제한을 어디서 하느냐에 차이
플라이웨이트 (Flyweight) 패턴
장점
- 많은 객체를 만들 때 성능을 향상할 수 있다.
- 많은 객체를 만들 때 메모리를 줄일 수 있다.
단점
- 특정 인스턴스를 다르게 처리하는 게 힘들다.
728x90
반응형
LIST
'Language > Design Pattern' 카테고리의 다른 글
[Design Pattern] 행동패턴 - Interpreter (0) | 2023.11.01 |
---|---|
[Design Pattern] 행동패턴 - Command (0) | 2023.11.01 |
[Design Pattern] 구조패턴 - Facade (0) | 2023.10.30 |
[Design Pattern] 구조 패턴 - Decorator (0) | 2023.10.27 |
[Design Pattern] 구조 패턴 - Composite (1) | 2023.10.26 |