CS/DesignPattern
(DesignPattern) 싱글턴 패턴
주누
2020. 5. 2. 19:55
https://jwdeveloper.tistory.com/29?category=823919
싱글턴 패턴이란?
인스턴스를 오직 하나만 생성할 수 있는 클래스를 뜻함.
장점
- 고정된 메모리 영역을 얻으면서 한 번의 new로 인스턴스를 공유하기 때문에 메모리 낭비를 방지할 수 있다.
- 두 번째 사용부터는 객체 로딩 시간이 줄어들어 성능이 좋아진다.
단점
- 싱글턴 인스턴스가 너무 많은 일을 하면 인스턴스의 간의 결합도가 높아진다. (OCP의 원칙에 위배 )
- 디버깅이 어려움이 있다.
- 테스트 코드의 작성의 어려움이 있다.
실습
개발 중인 시스템에서 스피커에 접근할 수 있는 클래스를 만들어보자
version 01
public class SystemSpeaker {
private static SystemSpeaker instance;
private int volume;
private SystemSpeaker() {
}
public static SystemSpeaker getInstance() {
if (instance == null) {
instance = new SystemSpeaker();
}
return instance;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
}
version 02
public class SystemSpeaker {
private final static SystemSpeaker INSTANCE = new SystemSpeaker();
private SystemSpeaker() {}
public SystemSpeaker getInstance() {
return INSTANCE;
}
}
생성자를 private으로 막아서 인스턴스가 생성되는 것을 막았는데 과연 이것이 안전한 방법일까?
답은 아니다! 왜냐면 리플렉션으로 해당 생성자의 접근을 가능하게 할 수 있기 때문이다.
public class Main {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
SystemSpeaker instance1 = SystemSpeaker.getInstance();
SystemSpeaker instance2 = SystemSpeaker.getInstance();
Class<SystemSpeaker> systemSpeakerClass = SystemSpeaker.class;
Constructor<SystemSpeaker> declaredConstructor = systemSpeakerClass.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
SystemSpeaker instance3 = declaredConstructor.newInstance();
System.out.println(instance1);
System.out.println(instance2);
System.out.println(instance3);
}
}