Featured image of post 14. 다양한 패턴 빠르게 알아보기 - 플라이웨이트 패턴

14. 다양한 패턴 빠르게 알아보기 - 플라이웨이트 패턴

헤드 퍼스트 디자인 패턴

플라이웨이트(Flyweight) 패턴

어떤 클래스의 인스턴스 하나로 여러 개의 가상 인스턴스를 제공하고 싶다면 플라이웨이트 패턴을 사용한다.

플라이웨이트 패턴 구조

플라이 웨이트 패턴은 여러 객체가 공유되어야 하는 대상을 효과적으로 처리하는 구조적 디자인 패턴이다.

이 패턴은 객체의 중복된 인스턴스를 피하고 메모리를 절약하면서 객체의 공유 가능성을 지원한다.

어떤 클래스의 인스턴스가 아주 많이 필요하지만 모두 똑같은 방식으로 제어해야 할 때 유용하게 쓰인다.

구성 요소

  • Flyweight
    • 인스턴스를 공유할 수 있도록 만드는 인터페이스 또는 추상 클래스
  • ConcreteFlyweight
    • Flyweight 인터페이스를 구현하여 공유 가능한 객체
  • UnsharedConcreteFlyweight
    • Flyweight를 구현하지만, 공유되지 않는 경우의 객체
  • FlyweightFactory:
    • Flyweight 객체를 생성하고 관리하는 역할 수행
    • 객체를 공유하고, 이미 생성된 객체를 반환
  • Client
    • Flyweight 객체를 사용하는 클라이언트 코드
    • 팩토리를 통애 이미 생성된 객체를 얻어옴

예시

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Flyweight 인터페이스
public interface Flyweight {
    void operation();
}

// ConcreteFlyweight 구현
public class ConcreteFlyweight implements Flyweight {
    private String sharedState;

    public ConcreteFlyweight(String sharedState) {
        this.sharedState = sharedState;
    }

    @Override
    public void operation() {
        System.out.println("ConcreteFlyweight: " + sharedState);
    }
}

// FlyweightFactory
public class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        Flyweight flyweight1 = factory.getFlyweight("A");
        Flyweight flyweight2 = factory.getFlyweight("B");
        Flyweight flyweight3 = factory.getFlyweight("A");

        flyweight1.operation();  // ConcreteFlyweight: A
        flyweight2.operation();  // ConcreteFlyweight: B
        flyweight3.operation();  // ConcreteFlyweight: A (이미 생성된 객체 공유)
    }
}

특징

장점

  • 실행 시에 객체 인스턴스의 개수를 줄여서 메모리를 절약할 수 있다.
  • 여러 가상 객체의 상태를 한곳에 모아 둘 수 있다.

단점

  • 특정 인스턴스만 다른 인스턴스와 다르게 행동하게 할 수 없다.
  • 플라이 웨이트 객체가 공유되므로, 한 객체의 상태를 변경하면 다른 객체에도 영향을 미칠 수 있다.