플라이웨이트 패턴

접근

  • 동일한 클래스의 객체를 많이 만들어야 하는 상황에서 성능 상 이점을 취하기 위해 객체 하나로 여러 개의 가상 객체를 제공해야 한다.

  • 가상 객체들의 상태를 관리하는 객체를 만들고, 상태를 갖지 않는 객체 하나를 만든다. 객체에 대한 정보를 얻으려면 상태 관리 객체에 요청을 보내야 한다.

개념

  • 수많은 객체를 생성하여 각각 데이터를 유지하는 대신 여러 객체 간 공통 부분을 공유하여 메모리 용량을 줄일 수 있는 디자인 패턴이다.

  • 객체마다 일정하게 유지되는 데이터를 고유한 상태라고 하며, 계속 변화하는 데이터를 공유한 상태라고 한다.

  • 고유한 상태는 객체 내부에 저장하여 컨텍스트가 다른 곳에서도 재사용되도록 한다. 이 때 저장되는 객체를 플라이웨이트라고 부른다.

  • 플라이웨이트 팩토리 클래스는 기존 플라이웨이트 객체를 재사용할지 새로 객체를 만들지 결정한다.

  • 공유한 상태는 객체 내부에 저장하지 않고, 컨텍스트 클래스에 포함해두고 상태에 의존하는 메서드들을 작성해 변화된 상태가 전달되도록 한다. 컨텍스트 클래스에는 고유한 상태인 플라이웨이트도 포함해둔다.

장단점

  • 장점

    • 실행 시 객체 개수를 줄여 메모리를 절약할 수 있다.

    • 여러 가상 객체의 상태를 한 곳에 모아둘 수 있다.

  • 단점

    • 특정 객체만 다르게 행동하도록 구현할 수 없다.

사용 방법

  • 플라이웨이트를 만들어야 할 만큼 많이 생성되는 클래스의 필드를 고유한 상태와 공유한 상태로 구분한다.

  • 고유한 상태를 나타내는 필드들은 그대로 두고 변경할 수 없도록 한다.

  • 공유한 상태를 사용하는 메서드들을 확인하고, 이 데이터들을 외부로 분리할 것이기 때문에 메서드 매개변수로 받도록 수정한다.

  • 필요 시 플라이웨이트 풀을 관리하기 위한 팩토리 클래스를 생성한다.

  • 클라이언트는 플라이웨이트 객체들의 메서드들을 호출할 수 있도록 공유한 상태의 값들​(콘텍스트)​을 효율적으로 저장/계산해야 한다.

예시

  • TreeManager는 여러 Tree 객체의 공유한 상태를 저장하는 Context 클래스이다.

public class TreeManager {
    int[][] treeArr;

    public void displayTrees() {
        for(int i=0;i<treeArr.length;i++) {
            display(treeArr[i][0], treeArr[i][1], age);
        }
    }
}
  • Tree는 고유한 상태를 저장하는 플라이웨이트 클래스이다.

public class Tree {
    public void display(int x, int y, int age) {
        System.out.println("위치 x: " + x + " y: " + y + " age: " + age);
    }
}

Last updated