티스토리 뷰

★ Design Pattern

디자인패턴 1) Singleton 패턴

유쾌한 개발자 anyjava 2014. 2. 3. 02:08
싱글턴 패턴(Singleton Pattern)

1. 개요

지정한 클래스의 인스턴스(객체)가 오로지 하나만 존재해야만 하는경우, 인스턴스가 하나인 경우만을 프로그램으로 나타낼때 이용하는 패턴이다.

ex) 티켓팅 클래스가 있을때, 이 클래스가 티켓번호를 하나씩 증가시켜 생성한다. 이때 싱글턴 패턴을 이용하면 단하나의 객체만으로 티켓번호 값이 중복되지 않게 증가되는것이 가능하다.


2. 클래스 다이어그램



3. Java 로 구현한 싱글턴패턴

- 생성자는 다른클래스가 접근하지 못하도록 private로 설정

- getInstance() 메소드는 synchronized 를 설정 ( 멀티스레드 환경 대비 )

- 객체맴버 변수와 메소드는 static

// 1. synchronized 를 이용한 singleton
public class Singleton {
    private static Singleton sigleton = null;
    private Singleton() {
        System.out.println("인스턴스를 생성했습니다.");
    }
    public static synchronized Singleton getInstance() {
        if( singleton == null )
            sigleton = new Singleton();
        return signleton; 
   }
   public static void doSometing() {
        System.out.println("do Someting!!");
   }
}
// 2. static member 변수 초기화를 이용한 Singleton
public class Singleton {
    private static Singleton sigleton = new Singleton();
    private Singleton() {
        System.out.println("인스턴스를 생성했습니다.");
    }
    public static Singleton getInstance() {
        return signleton; 
   }
   public static void doSometing() {
        System.out.println("do Someting!!");
   }
}



public class SingletonMain {
    public static void main( String[] args ) {
        System.out.println("Start.");
        Singleton sgt1 = Singleton.getInstance();
        Singleton sgt2 = Singleton.getInstance();
        if( sgt1 == sgt2 )
            System.out.println("sgt1 과 sgt2 는 같은 객체입니다.");
        else
            System.out.println("sgt1 과 sgt2 는 다른 객체입니다.");
        System.out.println("End.");
    }
}


 java 코드로 구분되는 싱글턴패턴의 특징은 다음과 같다. 일반적인 경우 new 키워드를 이용하여 아래와 같이 객체를 생성한다.


    Singleton sgtObj = new Singleton();

 하지만, 싱글턴의 경우 new를 이용하면 새로운 객체를 새롭게 생성하는 결과를 초래하므로 아래와 같이 구현해주어야 한다.

    Singleton sgtObj = Singleton.getInstance(); // 객체의 참조를 가져와서 사용할 경우
    Singleton.getInstance().doSometing();       // 객체를 리턴받으면서 바로 doSometing() 메소드를 호출가능


4. 활용되는 분야

    1) Logging Class / Configure Class

  하나의 어플리케이션에서 로그를 남길경우 사용한다. 여러 스레드에서 동시에 하나의 파일에 로깅을 할 경우 파일을 오픈하는 객체는 하나만 필요하기 때문에 Singleton을 활용하면 유용하다.

    2) DB Connection Pool Manager Class

    3) 한정되 하나의 자원에 접근하는 경우


5. multi-thread 환경에서의 Singleton

  위 첫번째 예제 소스를 보면 getInstance() 를 호출할 때, synchronized 키워드를 통해서 멀티스레드 환경에서 발생할 수 있는 문제점을 막을 수 있다. 하지만, 동기화 구문을 수행할때 많은 비용을 발생하여 자주사용되는 코드의 경우 성능상의 문제를 야기할지도 모른다.

  따라서 위 두번째 코드처럼 static 멤버변수 선언과 초기화를 동시에 해주어서 객체의 사용시점이 아닌 초기화 시점에 객체를 생성하여 예방할 수 있다.


6. 객체 직렬화(Serialization) 에서의 Singleton

  객체를 직렬화하여 수신측으로 해당객체를 보낼경우, 보낼때마다 새로운 객체를 생성하기 때문에 여러개의 객체가 생성될 위험이 있다. 따라서 Serializable interface를 구현한 클래스일 경우, 아래와 같이 readResolve() 메소드를 오버라이딩 해주면 Singleton 패턴의 구현이 가능하다.

	public class Singleton implements Serializable {

		// This method is called immediately after an object of this class is deserialized.
		// This method returns the singleton instance.
		protected Object readResolve() {
			return getInstance();
		}
	}


7. 마치며

  Singleton Pattern을 Java 예제와 함께 알아 보았습니다. 실제 개발단계에서 이 패턴을 자주 사용할 수 있을지 모르겠다. 하지만 공통부분을 맡았거나 처음부터 프로그램을 설계하는 개발자라면 필수적으로 필요한 개념일 것이다. 간단한 패턴이지만 중요하고 유용한 패턴이니 꼭 머릿속에 기억해두었다가 사용했으면 좋을 것이다.



<< 참고사이트 >>

http://www.oodesign.com/singleton-pattern.html

댓글
댓글쓰기 폼