싱글톤 패턴

반응형
반응형

이 패턴의 가장 큰 특징은 이름에서 부터 알 수 있듯이 싱글 + 톤으로 하나만 존재한다는걸 알 수 있다.

그런데... 프로그래밍상에서는 객체를 여러개 생성할 수 있다.

new a, new a 이런식으로요. 근데 이러면 하나가 아니라 두개 이상이 되버리니까 싱글 톤이 아니겠죠?

뭐 당연한 말이겠지만... 사실 싱글톤이라는건 메모리상에 하나만 존재한다는 뜻입니다. 그러니까 객체를 생성하려고 시도하든 뭐하든 메모리상에 하나만 존재하면 싱글톤이라는 겁니다. 근데 문제는 메모리상에는 하나니까 

만들어진 객체들은 서로 공유가 됩니다. 왜냐하면 같은 객체니까.

메모리상에 주소값도 똑같기 때문에 같은 객체라고 할 수 있습니다. 

 

또, 이 패턴은 겉보기에는 굉장히 쉽군 할 수 있지만, 사실 까면 또 까보고 싶은 양파같은 매력의 패턴입니다. 이렇게 하니 또 이런 버그가 생기네... 또 이 버그를 고치니 이 버그가 생기네 하는 식으로 말입니다.

 

 

이제 본격적으로 싱글톤에 대해 알아 보도록 하겠습니다.

위에서 말했듯이 싱글톤은 하나입니다. 물론, 메모리상에서요.

(메모리상에 하나가 존재하면 객체를 몇개를 만드든 상관 없담니다.)

 

그럼 코드를 작성해 봅시다.

package singleton;

public class ChocolateBoiler {
	private boolean empty;
	private boolean boiled;
	private static ChocolateBoiler unique;
	
	private ChocolateBoiler() {
		empty = true;
		boiled = false; 
	}
	
	public void fill() {
		if (isEmpty()) {
			empty = false;
			boiled = false;
		}
	}
	
	public void drain() {
		if (!isEmpty() && !isBoiled()) {
			empty = true;
		}
	}
	
	public static ChocolateBoiler getInstance() {
		if (unique == null) {
			unique = new ChocolateBoiler();		
		}
		return unique;
	}
	
	public void boil() {
		if (!isEmpty() && !isBoiled()) {
			boiled = true;
		}
	}
	
	public boolean isEmpty() {
		return empty;
	}
	
	public boolean isBoiled() {
		return boiled;
	}

}
 

 

귀찮아서 해드퍼스트 교재에 있는 예제 가지고 왔습니다. 어차피 싱글톤은 코드는 굉장히 쉽기 때문에 상관없습니다. 문제는 그게 아니지만요. ㅜㅜ

 

여기서 싱글톤의 핵심을 말씀드리겠습니다.

 첫 번째, 다른 클래스에서 호출 할 수 없게 생성자를 private로 해둔다. 

이것을 하는 목적은 인스턴스 생성을 막기 위해서입니다. 위에서 객체를 많이 만들 수 있다는 식으로 말한것 같은데 이건 위에서 설명하겠습니다.

두 번째, 자기 자신이 인스턴스를 생성한다.

이렇게 하는 목적인 자기 자신이 인스턴스가 되서 메모리상에 하나만 존재하게 만드는 행위입니다. 근데 왜 static을 사용하는 static을 붙이지 않는 상태에서 해당 메소드를 사용하려고 하면 셍성자를 호출해야 하기 때문에 이를 방지하고자 static을 활용해서 값을 전달합니다. 다른 언어에서는 이런거 사용안해도 될 수도 있겠지만, (다른 언어 모릅니다. ) 최소한 자바에서는 그렇답니다.

 

이 두 가지만 지키면 싱글톤은 완성입니다.

그런데 문제가 발생했습니다.  

 

객체를 여러개 만들 수 는 있지만 사실은 같은 객체이기 때문에, 값을 수정하게 되면 다른 객체들도 값이 바뀌게 됩니다. 예가 조금 안 맞을 수 있는데... 그냥 해보겠습니다.

학교에서 친구들이 A라는 학생을 부른다고 가정하겠습니다.  그럼 A라는 학생은 전부 대답합니다. (실제로는 무시할건 무시하겠죠. 아마...ㅎㅎ) 또, 어떤 친구가 A에게 샤프를 선물했고 또, 어떤 친구가 볼펜을 선물했습니다. 근데 어떤 친구가 그 볼펜에 장난을 칩니다. 또 누군가 장난치고... 그렇다고 해서 A라는 인물이 변하는건 아닙니다. 하지만 애석하게도 누군가 볼펜에 장난을 쳐서 볼펜이 고장났습니다. 또 볼펜심이 사라지기도 했습니다.ㅜㅜ

문제는 이게 동시에 일어난다는게 문제입니다. 순차적으로 일어나면 A가 대체할 수 있을지도 모르는데 몇 백개가 동시에 일어난다고 생각해보죠. 그럼 그 볼펜은 망신창이가 되버립니다. 누군가는 A의 볼펜을 고치려고 시도해도 소용없습니다. 동시에 장난쳤기 때문에 그럴 겨를도 없죠. 하지만 순차적으로 일어난다면 어떨까요? 아무리 장난을 쳐도 중간에 누군가 볼펜을 수리해주면, 정상적이지 않아도... 그냥 정상적이라 말할게요. A는 정상적인 볼펜을 사용할 수 있죠.

 

프로그래밍상에서도 이와 비슷하게 scsynchronized를 붙여주면 된다고 합니다. 이것도 또 문제가 있는데 그건 책을 참조해주세요. 네 맞아요 까먹었어요.

아무튼 이렇게 싱글톤은 핵심은 쉬우나 많은 문제점이 많아 까다로운 패턴이라 생각합니다.

 

 

정리하면 위에서 객체를 많이 만들 수 있다는 말은 그 객체를 호출할 수 있다는 뜻입니다. 

또, 싱글톤을 사용시 메모리상에 직접적으로 접근하기 때문에 사용도를 최소로 사용하는것이 좋다라고 할 수 있겠네요.

 

 

 

반응형

'디자인패턴' 카테고리의 다른 글

빌더 패턴  (0) 2020.05.27
프록시 패턴  (0) 2020.05.18
팩토리 패턴  (0) 2020.05.06
데코레이터 패턴  (0) 2020.05.02
컴포지트 패턴  (0) 2020.05.01

댓글

Designed by JB FACTORY