Limit Instantiation with Singleton (396)
20 Jun 2021 | DesignPattern Refactoring개요
어떤 클래스의 인스턴스를 여러 개 생성해 사용하고 있는데 그로 인해 메모리 사용량이 너무 커지거나 시스템 성능이 저하된다면, 여러 개의 객체를 하나의 싱글턴 객체로 대체한다.
동기
바로 전 포스트에서 싱글턴 패턴은 정말 특정한 상황이 아니면 필요하지 않다고 했다. 하지만 다음의 특정한 상황의 경우 싱글턴 패턴을 고려해보자.
- 시스템 성능에 대한 사용자의 불만이 높다.
- 프로파일러를 통해 확인한 결과, 객체를 반복적으로 생성하는 것이 시스템 성능에 악영향을 미친다.
- 공유하려는 객체가 상태를 갖지 않거나, 갖더라도 상태를 공유할 수 있다.
장점
- 성능을 향상시킨다.
단점
- 어느 곳에서나 객체를 접근할 수 있게 된다. 많은 경우, 이는 좋지 않은 설계로 평가된다.
- 객체를 공유하면 안 되는 상태가 존재할 때에는 적용할 수 없다.
절차
이 리팩터링을 적용하기 전에, 대상이 되는 객체에 상태가 없거나 있더라도 공유가 가능한지 확인해야 한다.
-
인스턴스를 여러 개 가지는 클래스. 즉, 하나 이상의 클라이언트에 의해 두번 이상 생성되는 클래스를 찾는다. 그 클래스에 Replace Constructor with Creation Methods을 적용한다. 생성자가 하나뿐인 경우라도 마찬가지다. 생성 메서드의 리턴 타입은 대상 클래스 타입이어야 한다.
-
싱글턴 필드를 만든다. 필드는 private static 타입으로, 타입은 대상 클래스 타입으로 선언한다. 가능하다면 대상 클래스의 인스턴스로 싱글턴 필드를 초기화한다.
런타임에 클라이언트로부터 받아야 할 파라미터가 존재한다면 초기화할 수 없을 것이다. 이럴 경우 필드만 선언하고 초기화는 하지 않는다. -
앞서 만든 생성 메서드가 싱글턴 필드의 값을 리턴하도록 수정한다. 단계 2에서 초기화를 하지 못했다면, 전달받은 파라미터를 이용해 이 생성 메서드에서 초기화를 수행하도록 한다.