본문 바로가기
DesignPattern

[디자인패턴] Flyweight Pattern / 플라이웨이트 패턴 구현

by 발개발자 2022. 9. 7.
반응형

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

플라이웨이트 패턴은 불필요한 메모리 낭비를 줄이기 위해 고안된 패턴으로, 공통된 자원의 인스턴스를 한번만 생성하여 공유시켜주는 것이다.

즉, 공유를 통하여 대량의 객체들을 효과적으로 지원하는 방법이다.

 

여기서 어떤 자원을 플라이웨이트 패턴에 적용시킬까에 대한 관점은 보통 두가지로 축약된다.

 

1. 중복 생성될 가능성이 높은 경우

  • 중복 생성될 가능성이 높다는 것은 동일한 자원이 자주 사용될 가능성이 매우 높다는 것을 의미한다. 이런 자원은 고통 자원 형태로 관리해 주는 편이 좋다.

2. 자원 생성 비용은 큰데 사용 빈도가 낮은경우

  • 이런 자원을 항상 미리 생성해 두는 것은 낭비이다. 따라서 요청이 있을 때에 생성해서 제공해주는 편이 좋다.

 

이 두가지 목적을 위해서 플라이웨이트 패턴은 자원생성과 제공을 책임진다.

그럼 Flywegith Patten의 다이어그램을 살펴보자.

 

 

  플라이웨이트 패턴의 구조

 

Flyweight

  • 공유자원으로 사용될 클래스들의 인터페이스이다.

 

ConcreteFlyweight

  • Flyweight를 구현할 실제 공유 객체이다.

 

FlyweightFactory

  • ConcreteFlyweight를 공유자원으로 저장하고 제공을 하는 역할을 담당하는 객체이다.

 

Client

  • Flyweight 패턴을 이용하는 실사용자이다.

 

  예제

Flyweight - Publisher

public interface Publisher {
	public void publish();
}

 

 

ConcreteFlyweight - Book

public class Book implements Publisher{
	
	private String name;
	private String writer;
	private int price;
	
	public Book(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	@Override
	public void publish() {
		System.out.println("새로운 책을 출판하였습니다. 책이름 : " + this.name);
		
	}
}

 

 

FlyweightFactory - BooksFactory

public class BooksFactory {
	private static final Map<String, Book> booksMap = new HashMap<>();
	
	public static final Book getBook(String name) {
		Book book = booksMap.get(name);
		if(book == null) {
			book = new Book(name);
			booksMap.put(name, book);
			System.out.println("========= 새로운 책이 들어왔습니다. 책이름 : " + name + " =========" );
			
		}
		return book;
		
	}
}

 

 

Main

public class Main {

	public static void main(String[] args) {
		Book newBook1 = new Book("java의 정석");
		newBook1.setWriter("홍길동");
		newBook1.setPrice(20000);
		newBook1.publish();

		Book newBook2 = new Book("만화 삼국지");
		newBook2.setWriter("김길동");
		newBook2.setPrice(30000);
		newBook2.publish();

		Book newBook3 = new Book("해커스 토익");
		newBook3.setWriter("최길동");
		newBook3.setPrice(25000);
		newBook3.publish();
		
		List<Book> newBooks = Arrays.asList(newBook1, newBook2, newBook3);
		
		
		for(int i = 0 ; i < 10; i++) {
			int idx = (int)(Math.random()*3);
			Book book = BooksFactory.getBook(newBooks.get(idx).getName());
			
		}
	}
}

 

결과

 

플라이웨이트 패턴의 구현을 통해 많은 요청이 와도 한번만 객체를 생성한 후, 저장된 객체를 재사용하여 불필요한 객체 인스턴스를 생성하는 것을 막아주는 것을 확인할 수 있다.

 

 

  장점 / 단점

장점

  • 많은 객체를 만들 때 성능을 향상시킬 수 있다.
  • 많은 객체를 만들 때 메모리를 줄일 수 있다.
  • State pattern과 쉽게 결합될 수 있다.

 

단점

  • 특정 인스턴스의 공유 컴포넌트를 다르게 행동하게 하는 것이 불가능하다. (개별 설정이 불가능하다.)

 

  실사용 사례

  • Java.lang.String
  • Java.lang.Integer#valueOf(int)
  • Java.lang.Boolean#valueOf(boolean)
  • Java.lang.Byte#valueOf(byte)
  • Java.lang.Character#valueOf(char)

java에서 해당 객체들에서 실제로 플라이웨이트 패턴이 구현되어 지고 있다.

 

예를 들어, String에서는

		String name1 = "아무개";
		String name2 = "아무개";

위와 같이 소스를 작성할 경우, 하나의 객체만 생성하여 메모리 주소를 공유하는 것을 확인할 수 있다.

 

 

오늘은 여기까지,,

반응형

댓글