티스토리 뷰
반응형
싱글톤이란, 하나의 인스턴스만 생성하도록 구현하는 것을 말한다.
기본적인 설계
요구사항
- 개발 중 시스템에서 스피커에 접근할 수 있는 클래스를 만들어달라.
싱글톤 객체 정의
public class SystemSpeaker {
static private SystemSpeaker instance;
private int volume;
private SystemSpeaker() {
volume = 5;
}
//하나의 인스턴스만을 만들기 위한 메소드
public static SystemSpeaker getInstance() {
if(null == instance) {
return instance = new SystemSpeaker();
}
return instance;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
}
Main
public static void main(String [] args) {
SystemSpeaker systemSpeaker1 = SystemSpeaker.getInstance();
SystemSpeaker systemSpeaker2 = SystemSpeaker.getInstance();
System.out.println("systemSpeaker1 : " + systemSpeaker1);
System.out.println("systemSpeaker2 : " + systemSpeaker2);
}
실행결과
- 두개의 객체는 같은 주소를 가지고 있는 것을 확인할 수 있다.
리플렉션을 사용해서 싱글톤 깨버리기
- Java에서는 위와 같은 싱글톤 정의를 깨버릴 수 있는 경우도 있다.
public static void main(String [] args) throws ClassCastException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchFieldException {
SystemSpeaker systemSpeaker1 = SystemSpeaker.getInstance();
SystemSpeaker systemSpeaker2 = SystemSpeaker.getInstance();
System.out.println("systemSpeaker1 : " + systemSpeaker1);
System.out.println("systemSpeaker2 : " + systemSpeaker2);
//리플렉션을 활용하여 싱글톤 깨버리기
Class<?> speakerClass = Class.forName("com.pattern.ch05_singleton.SystemSpeaker");
Constructor<?> constructor = speakerClass.getDeclaredConstructor();
//접근 제한자에 상관없이 모두 접근 가능
constructor.setAccessible(true);
SystemSpeaker systemSpeaker3 = (SystemSpeaker) constructor.newInstance();
System.out.println(systemSpeaker3);
}
- 소스에서 보는 봐와 같이 reflection을 활용하여 해당 클래스의 생성자 메소드에 접근하여 아예 새로운 인스턴스를 만들 수 있다.
- 그로 인해 정말 안정적인 싱글톤을 생성하고자 한다면 enum을 사용하여 싱글톤 객체를 만들 수 있도록 해야한다.
Enum 사용
public enum EnumSystemSpeaker {
INSTANCE;
private int volume = 5;
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
}
//Main
//enum 사용
public static void main(String [] args) {
System.out.println(System.identityHashCode(EnumSystemSpeaker.INSTANCE.getClass()));
System.out.println(System.identityHashCode(EnumSystemSpeaker.INSTANCE.getClass()));
}
- 10진수로 된 메모리 주소가 동일하는 것을 확인할 수 있다.
- Enum을 사용할 시 스레드 세이프하고 Serialization을 스스로 해결하며, reflection에서도 안정성을 보장하는 특징을 가지고 있다.
반응형
'Java > 디자인 패턴' 카테고리의 다른 글
[디자인 패턴] 프로토타입 패턴(얕은 복사와 깊은 복사) (0) | 2020.05.10 |
---|---|
[디자인 패턴] 프로토타입 패턴(1) (0) | 2020.05.03 |
[디자인 패턴] 팩토리 메소드 패턴 (0) | 2020.04.28 |
[디자인 패턴] 템플릿 메소드(Template Method) 패턴 (0) | 2020.04.21 |
[디자인 패턴] 어댑터(Adapter) 패턴 (0) | 2020.04.21 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 연관관계
- 정적팩터리메서드
- 이펙티브자바
- junit
- 점층적 생성 패턴
- 자바8
- java8
- try catch finally
- 인프런
- effectivejava
- jdk버전
- 생성자
- ifPresent
- mustache
- 복사 팩토리
- Effective Java
- 빌더 패턴
- springboot
- flatMap
- package-private
- @Lazy
- 이펙티브 자바
- try with resources
- 스프링부트
- java
- JPA
- 팩토리 메소드 패턴
- Spring
- 김영한
- 빈 순환 참조
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함