반응형

[ 이 글은 Effective Java를 참조하여 작성되었습니다. ]


 싱글턴 패턴에 대해서 모르시는 분은 먼저 싱글턴 패턴에 대해 공부하고 오시는 것이 좋습니다.

 싱글턴은 간단하게 객체를 하나만 만들 수 있는 클래스 입니다. 때문에 보통 유일할 수 밖에 없는 컴포넌트를 나타내곤 하죠. 하지만 클래스를 싱글턴으로 만들면 테스트하기가 어려울수도 있습니다. 싱글턴 패턴을 구현하는 방법은 크게 2가지가 있습니다. 두 방법 모두 생성자는 private이고 객체는 static멤버를 이용합니다.

 첫번째 방법은 정적 멤버를 final로 선언하는 것입니다. 

public class Sw{

     public static final Sw INSTANCE = new Sw();

     private Sw(){ ... }

     메소드...

}


와 같은 방식이죠. private 생성자는 INSTANCE를 초기화 할 때 단 한번만 호출됩니다. public 또는 protected로 선언된 생성자가 없기 때문에 오로자 하나만 존재하게 되는거죠. 


 두번째 방법은 정적 팩토리 메서드를 사용하는 것입니다. 

public class Sw{

     private static final Sw INSTANCE = new Sw();

     private Sw() { ... }

   

     public static Sw getInstance() { return INSTANCE; }

}


와 같은 방식입니다. 여기서 getInstance는 항상 같은 객체만을 return 해줍니다. 이 두가지 방법은 JDK 1.5이전에 주로 사용하던 방법이기 때문에 최적의 방법은 아닐 수도 있습니다. 왜냐하면 최신 Java Virtual Machine은 정적 팩토리 메서드를 항상 인라인 처리하기 때문입니다. 하지만 이 정적 팩토리 메서드를 사용하는 방식은 2가지의 장점이 존재합니다.


(1) API를 변경하지 않고도 싱글턴을 포기할 수 있다는 것입니다.


싱글턴 객체를 참조하는 유일한 필드가 private이므로 이를 지우고 getInstance의 구현을 변경해도 API는 영향을 받지 않겠죠.


(2) 제네릭 타입을 수용하기 쉽다.


간단히 설명하자면 자료형 유추가 가능하고, 형 안정성을 제공할 수 있다는 것이다. 하지만 이 장점이 필요 없는 경우도 많습니다. 

이럴 때는 public 필드를 사용하는 쪽이 더 간단합니다.



그렇다면 JDK 1.5 이후에는 어떤 방법을 사용하는지 알아봅시다.

바로 원소가 단 하나뿐인 enum 자료형을 정의하는 방법입니다.

public enum Sw{

     INSTANCE;



 이와 같은 방법은 기능적으로는 public 필드를 사용하는 방법과 동등하지만 좀 더 간결하다는 것과 직렬화가 자동으로 처리된다는 장점이 있다. 또한, enum은 인스턴스가 여러 개 생기지 않도록 확실하게 보장해주며 유일한 INSTANCE가 생성될 떄, 멀티 쓰레드 환경에서 안전하기도 하다.

Effective Java에서는 enum을 사용하는 것이 가장 좋은 방법이라고 언급하고 있다. 하지만 enum은 익숙하지 않은 방법이라 자주 사용할지는 모르겠지만 의식적으로라도 한 번씩 사용하도록 노력해야겠다.

반응형

+ Recent posts