ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] 플라이웨이트 패턴 (Flyweight Pattern)
    공부/디자인 패턴 2020. 7. 26. 18:14

    Flyweight 패턴은 비용이 큰 자원을 공통으로 사용할 수 있도록 만드는 패턴입니다. 여기서 자원에 대한 비용은 크게 두가지로 나눠 볼 수 있습니다.

    중복 생성될 가능성이 높음

    중복 생성될 가능성이 높다는 의미는 동일한 자원이 자주 사용될 가능성이 높은 것입니다. 이러한 자원은 공통 자원으로 관리하고 있다가 요청이 있을 때 제공해 주는 것이 좋습니다.

    자원 생성 비용은 큰데 사용 빈도는 낮음

    생성 비용이 크지만 사용 빈도가 낮은 자원을 미리 생성해 두는 것은 좋지 않습니다. 따라서 요청이 있을 때, 생성해서 제공해 주는 편이 좋습니다.


    일반적으로 Factory와 관리 역할을 분리하는 것이 좋아 보이지만 굳이 나누고자 할 정도로 크기가 크지 않아서 하나의 클래스가 담당하도록 구현을 합니다. 이러한 패턴을 적용하면 메모리 사용공간의 낭비를 줄일 수 있습니다.

    예시

    class Flyweight {
      Map<String, Subject > map = new HashMap<String, Subject>();
    
      public Subject getSubject(String name){
        Subject subject = map.get(name);
        if(subject == null) {
          subject = new Subject(name);
          map.put(name, subject);
        }
        return subject;
      }
    }
    
    class Subject {
      private String name;
      public Subject(String name){
        this.name = name;
        System.out.println("create : " + name);
      }
    }
    
    
    public static void main(String[] args) {
            Flyweight flyweight = new Flyweight();
            flyweight.getSubject("김씨"); // create: 김씨
            flyweight.getSubject("김씨");
            flyweight.getSubject("이씨"); // create: 이씨
            flyweight.getSubject("전씨"); // create: 전씨
    }


    해당 패턴을 적용한 예시는 자바의 String Pool입니다.

    public static void main(String[] args){
        String s = "hello";
        String s1 = new String("hello");
        String s2 = "hello";
     
        System.out.println("s == s1 ? " + (s == s1));
        System.out.println("s == s2 ? " + (s == s2));
     }
       
    
    // s == s1 ? false
    // s == s2 ? true


    자바에서 대입 연산자를 통해 문자열을 선언할 때, 해당 문자열이 메모리에 존재하는지 확인한 다음, 메모리에 존재하면 해당 메모리 값을 참조 합니다. 

    파이썬에서..

    class Flyweight:
        def __init__(self):
            self.map = {}
    
        def get_subject(self, name):
            subject = self.map.get(name, None)
            if not subject:
                subject = Subject(name)
                self.map[name] = subject
    
            return subject
    
    
    class Subject:
        def __init__(self, name):
            self.name = name
            print('create: ' + self.name)
    
    
    flyweight = Flyweight()
    a = flyweight.get_subject('김씨')
    b = flyweight.get_subject('김씨')
    c = flyweight.get_subject('이씨')
    d = flyweight.get_subject('전씨')
    
    print(a)
    print(b)
    print(c)
    print(d)
    
    
    
    # create: 김씨
    # create: 이씨
    # create: 전씨
    # <__main__.Subject object at 0x101b1b490>
    # <__main__.Subject object at 0x101b1b490>
    # <__main__.Subject object at 0x101b22190>
    # <__main__.Subject object at 0x101bfce50>


    댓글