Design Patterns

[Design Patterns] Flyweight

우라릭 2024. 3. 27. 00:17

 

 

목차

    개요

    내용

    요약

    수많은 객체들을 효율적으로 관리하기 위해서 객체를 공유하자

    예시

     악보를 그려주는 프로그램을 생각해봅시다. 악보엔 음표가 있을 것이고 프로그램은 악보를 그리기 위해 음표들을 메모리에 저장하겠죠. 가장 단순하면서도 세밀한 컨트롤이 가능한 방법은 모든 음표를 객체화하는 것입니다.

    하지만 이 방식은 악보가 많아졌을 때 수많은 객체를 만들어낼 수 있습니다. 즉, 저장공간에 대한 비용이 매우 높을 수 있습니다. 이 때 플라이웨이트 패턴이 사용됩니다.

     플라이웨이트는 동시에 여러 곳에서 사용될 수 있는 공유되는 객체입니다. 플리웨이트는 공유되어야하기 때문에 그들이 쓰이는 문맥(context)에 대한 정보를 가질 수 없습니다.

     이 패턴에서 쓰이는 핵심 개념을 참고해주세요.

    • Intrinsic state - 문맥과 무관한 클래스 고유의 정보들이며 플라이웨이트 클래스 안에 위치합니다.
    • Extrinsic state - 문맥에 연관이 있으며 공유될 수 없는 상태들입니다. 필요하면 사용자가 플라이웨이트 객체 안으로 상태를 넣어줘야 합니다.

    구조

    이 때 FlyweightFactory에는 쓰레드풀, DB 커넥션 풀과 같은 역할을 하는 플라이웨이트 풀을 가지고 있습니다. 플라이웨이트 풀은 기존 플라이웨이트를 가지고 있으며 사용자가 요청하면 해당 객체를 반환해줍니다.

    이야깃거리

    언제 써야 할까?

    이 패턴은 잘못 사용하면 이점이 없이 단점만 가지게 되므로 신중히 사용해야 합니다. 아래 조건이 모두 만족할 때 사용합시다.

    • 시스템이 수많은 객체를 사용함.
    • 객체가 너무 많아서 메모리에 저장하기 부담스러움.
    • 대부분의 객체 상태는 extrinsic state로 만들 수 있음.
    • 시스템에서 객체의 비교가 필요없음. 플라이웨이트는 공유되는 객체이기 때문에 == 비교가 어렵습니다.
    • Extrinsic state만 제거되면 적은 수의 공유 객체 그룹으로 대체될 수 있음.

    장단점

    • (Pros) 저장 비용이 줄어듭니다.
    • (Cons) 객체를 가져오기위한 작업 등 연산 비용이 늘어납니다. 

    Case Study

    Case 1. Java Reference Types

    자바의 많은 참조 타입들은 플라이웨이트 패턴을 사용합니다. 예를 위해 Integer 클래스를 살펴봅시다. Integer.valueOf 메소드는 아래와 같은 구현을 가집니다.

    이 때 IntegerCache.low = -128이고 IntegerCache.high는 설정가능한 값이지만 기본값으로 127이 들어갑니다. 즉, ~128~127까지의 정수를 인자로 받으면 새로운 객체를 만들지 않고 캐시에서 객체를 가져옵니다.

    이와 같은 구조  IntegerCache는 플라이웨이트 풀, Integer는 플라이웨이트이면서 플라이웨이트 팩토리의 역할을 하는 플라이웨이트 구조로 볼 수 있습니다.

     

     

    출처

    GoF Design Patterns

    'Design Patterns' 카테고리의 다른 글

    [Design Patterns] Chain of Responsibility  (0) 2024.03.31
    [Design Patterns] Proxy  (0) 2024.03.31
    [Design Patterns] Facade  (0) 2024.03.24
    [Design Patterns] Decorator  (0) 2024.03.20
    [Design Patterns] Composite  (0) 2024.03.17