티스토리 뷰

‘플라이급'이란 의미로, 권투에서 가장 체중이 가벼운 체급을 나타낸다.

이 디자인 패턴은 객체를 ‘가볍게' 하기 위한 것이다.

여기서 말하는 무게는 ‘메모리의 사용량'을 의미한다.

많은 메모리를 사용하는 객체를 ‘무겁다'고 표현한다.

 

Java에서는 new Something() 처럼, Something 클래스의 인스턴스를 만들 수 있다.

이 때, 그 인스턴스를 저장하기 위해서 메모리가 확보된다.

Something 클래스의 인스턴스가 많이 필요할 때에, new를 많이 하면 메모리의 사용량이 커지게 된다.

 

플라이웨이트 패턴에서 사용하는 기법을 간단하게 표현하면 다음과 같다.

🐻
인스턴스를 가능한 대로 공유시켜서 쓸데없이 new하지 않도록 한다.

 

인스턴스가 필요할 때 항상 new하는 것이 아니라, 이미 만들어져 있는 인스턴스를 이용할 수 있으면 그것을 이용해서 사용한다.

 

다음 링크는 플라이웨이트 패턴의 예제 코드다.

 

GitHub - kkoon9/Java-Design-Pattern: Java 언어로 배우는 디자인 패턴 입문 예제 코드

Java 언어로 배우는 디자인 패턴 입문 예제 코드. Contribute to kkoon9/Java-Design-Pattern development by creating an account on GitHub.

github.com

플라이웨이트 패턴의 등장인물

Flyweight(플라이급)의 역할 - BigChar

공유하는 것이 좋은 것을 나타내는 역할

FlyweightFactory(플라이급 팩토리)의 역할 - BigCharFactory

이 공장을 사용해서 Flyweight 역할을 만들면 인스턴스가 공유된다.

Client(의뢰자)의 역할 - BigString

FlyweightFactory 역할을 사용해서 Flyweight 역할을 만들고 그것을 이용하는 역할

여러 장소에 영향을 미친다

플라이웨이트 패턴에서는 인스턴스를 공유하는 것이 핵심이다.

🤔
인스턴스를 공유할 때에는 어떤 점에 주의해야 할까?

 

공유하고 있는 것을 변경하면 여러 장소에 영향을 미친다는 점을 주의해야 한다.

여러 장소에 영향을 미치는 것이 항상 나쁜 것은 아니고, 프로그램이 취급하는 문제에 따라서 다르다.

어쨌든 공유는 하나를 변경하면 그것을 사용하고 있는 장소 전체에 영향을 미친다는 특성을 가진다.

따라서 Flyweight 역할에게 제공하는 정보는 신중히 선택해야 한다.

반드시 여러 장소에 공유시켜야 할 정보만을 Flyweight 역할에게 제공하는 것이 좋다.

intrinsic와 extrinsic

intrinsic

공유시키는 정보를 의미한다.

‘원래 구비하고 있다', ‘본질적인' 이라는 뜻을 가진다.

인스턴스를 어디에서 가지고 있더라도 어떠한 상황에서도 변하지 않는 정보, 상태에 의존하지 않는 정보다.

BigChar의 필드 데이터는 BigString의 어디에 등장해도 변하지 않는다.

따라서 BigChar의 폰트 데이터는 intrinsic한 정보가 된다.

extrinsic

공유시키지 않는 정보를 의미한다.

‘외부에서 온’, ‘비본질적인' 이라는 뜻을 가진다.

인스턴스를 두는 장소에 따라서 변화하는 정보, 상황에 따라서 변화하는 정보, 상태에 의존하는 정보다.

두는 장소에 따라서 변하는 정보를 공유시킬 수는 없다.

BigChar의 인스턴스가 BigString의 몇 번째 문자인가 하는 정보는 BigChar가 놓이는 장소에 따라 변하기 때문에 BigChar에게 제공할 수 없다.

인스턴스와 GC

BigCharFactory에서는 java.util.HashMap를 사용해서 BigChar의 인스턴스를 관리하고 있다.

‘인스턴스를 관리'하는 기능을 Java에서 구현할 때에는 ‘관리되고 있는 인스턴스는 GC에 담기지 않는다'라는 점을 주의해야 한다.

Java는 new에 의해 메모리를 확보한다.

많은 메모리를 확보하다 보면 메모리가 부족하게 된다.

메모리가 부족할 때 Java를 동작시키고 있는 가상 기계는 GC를 동작시킨다.

이것은 자신의 메모리 공간(heap 영역)을 조사해서 사용되지 않는 인스턴스를 해제하여 메모리의 빈 영역을 늘리는 처리다.

G(Garbage)는 ‘쓰레기'이고 C(collection)은 ‘수집'이라는 의미다.

요약하면 사용되지 않는 메모리를 쓰레기수집차처럼 모아서 재활용하는 것이다.

GC 기능 덕에 new한 인스턴스를 그대로 방치할 수 있다.

 

여기에서 핵심은 ‘GC의 사용되지 않는 인스턴스를 해제한다’는 부분이다.

GC를 실행할 때에 각 인스턴스에 대해서 garbage(쓰레기)인지 아닌지의 판정이 이루어지지만, 외부에서 참조되고 있는 인스턴스는 ‘사용되고 있다'고 간주되어 garbage로 판정되지 않는다.

 

예제 코드에서는 pool 필드에서 작성한 BigChar의 인스턴스를 관리하고 있다.

만약, 그 BigChar의 인스턴스가 실제로는 BigString의 인스턴스에서 참조하지 않더라도 pool 필드에서 관리되고 있는 인스턴스는 garbage로 간주되지 않는다.

이건 일단 한 번 만든 BigChar 클래스의 인스턴스는 계속 메모리에 남아있게 된다는 의미다.

 

인스턴스를 명시적으로 삭제할 수는 없지만, 인스턴스에 대한 참조를 없앨 수는 있다.

관리되고 있는 인스턴스를 garbage로 하기 위해서는, 명시적으로 참조를 없애서 관리되지 않도록 해야한다.

HashMap으로부터 그 인스턴스를 포함하는 엔트리를 삭제하면 인스턴스에 대한 참조를 없앨 수 있다.

메모리 이외의 리소스

인스턴스를 공유하면 메모리 사용량을 줄일 수 있다고 했다.

일반적으로 말하면 인스턴스를 공유하면 인스턴스를 생성하기 위해 필요한 리소스의 양을 줄일 수가 있다.

시간도 리소스의 일종이다.

인스턴스를 new할 때에 일정 시간이 걸린다고 하자.

플라이웨이트 패턴을 사용해서 인스턴스를 공유하면 인스턴스를 new하는 수를 줄일 수 있다.

따라서, 프로그램의 속도를 올릴 수 있다.

관련 패턴

  • Singleton 패턴
  • Proxy 패턴
  • Composite 패턴

'JAVA > 디자인 패턴' 카테고리의 다른 글

커맨드(Command) 패턴  (0) 2022.04.18
프록시(Proxy) 패턴  (0) 2022.04.18
상태(State) 패턴  (0) 2022.04.18
메멘토(Memento) 패턴  (0) 2022.04.03
옵저버(Observer) 패턴  (0) 2022.04.02
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함