디자인패턴

플라이웨이턴 패턴 (Flyweight Pattern)

JUNGKEUNG 2022. 8. 15. 18:23
반응형

플라이웨이턴 패턴 (Flyweight Pattern) 란?

  • 여러 클래스의 인스턴스 한 개만 가지고 여러 개의 "가상 인스턴스"를 제공하고 싶을 때 사용하는 패턴이다.
  • 인스턴스를 가능한 대로 공유시켜 슬데없이 new 연산자를 통한 메모리 낭비를 줄이는 방식이다.
  • 자주 변하는 속성(외적인 속성, extrinsit)과 변하지 않는 속성(내적인 속성, intrinsit)을 분리하고 재사용하여 메모리 사용을 줄인다

Character 클래스

  • 글자 하나를 표현한 도메인
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;
    }
}

Client

  • 편집기에 글을 입력하는 클라이언트
  • 글자 하나마다 Character 인스턴스를 생성한다.
public class Client {

    public static void main(String[] args) {
        Character c1 = new Character ('h', "white", "Nanum", 12);
        Character c2 = new Character ('e', "white", "Nanum", 12);
        Character c3 = new Character ('l', "white", "Nanum", 12);
        Character c4 = new Character ('l', "white", "Nanum", 12);
        Character c5 = new Character ('o', "white", "Nanum", 12);
    }
}

 

편집기에 글을 쓰면 한글자 한글자 모두 new 생성자를 통해 객체를 생성하게 되는데, 메모리를 아끼기 위해 자주 변하는 속성(공유불가), 자주 변하지 않는 속성(공유)을 분류해보자.
  • 문자  : 자주 변하는 속성
    • 은 ENUM 타입으로 선언해주어도 좋을 것 같다.
  • 글자 폰트 크기 자주 변하지 않는 속성

 

Font 라는 클래스(Flyweight)로 만들어서 개선해보자.

 

플라이웨이트 패턴 적용

Character 인스턴스가 모든 데이터를 따로 저장하지 않고, 공유할 수 있는 부분을 공유해서 메모리를 아껴보자.

자주 변하지 않아서 공유할 수 있는 속성으로 분류했던 글자 폰트 글자 크기 속성을 Font 클래스로 선언했다.

 

Font

public final 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;
    }

}
  • 공유하는 객체이기 때문에 불변으로 선언 (final)
  • 생성자로만 선언 + getter 접근

 

Character

Font를 field로 갖도록 수정했다.

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;
    }
}

FontFactory

Font 생성을 관리해주는 팩토리는 다음과 같다.

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;
        }
    }
}
  • FontFactory의 getFont() 메소드를 통해 Font 생성을 하게 되면, HashMap에 데이터가 있는지 먼저 검사하게 된다.
  • 기존에 저장해둔 Font 인스턴스가 있다면, 새로 생성하지 않고 기존 인스턴스를 반환해준다.

Client

public class Client {

    public static void main(String[] args) {

        FontFactory fontFactory = new FontFactory();
        Character c1 = new Character('h',"white", fontFactory.getFont("nanum:12"));
        Character c2 = new Character('e',"white", fontFactory.getFont("nanum:12"));
        Character c3 = new Character('l',"white", fontFactory.getFont("nanum:12"));
        Character c4 = new Character('l',"white", fontFactory.getFont("nanum:12"));
        Character c5 = new Character('o',"white", fontFactory.getFont("nanum:12"));
    }
}

 

장점

  • 많은 객체를 만들때 성능을 향상시킬수 있다
  • 많은 객체를 만들때 메모리를 줄일수 있다

단점

  • 특정 인스턴스를 다르게 처리하는게 힘들다

 

 

참고


 

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com

 

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

템플릿 메소드 패턴(Template Method Pattern)  (1) 2022.09.25
전략패턴(Strategy Pattern)  (1) 2022.09.20
퍼사드 패턴(Facade Pattern)  (0) 2022.08.14
데코레이터(Decorator) 패턴  (0) 2022.08.04
컴포짓(composite) 패턴  (0) 2022.07.30