Develop/Design
[Design Pattern] Singleton Pattern
코딩의성지
2023. 1. 28. 00:31
우리는 객체를 하나만 사용하기 위해 Singleton 패턴을 많이 활용한다.
Singleton 을 구현하기 위해 몇가지 방법이 있는데 간단하게 말씀드려보겠다.
public static member
해당 방법은 인스턴스를 초기화 시킨 뒤 고정시켜 사용하는 방법이다. 사용자는 변수에 직접 접근하여 사용하여야 한다.
이렇게 사용하면 의도하지 않은 객체 생성을 막을 수 있다.
public class Member {
public static final Member INSTANCE = new Member();
private Member() {
}
}
private static final field
해당 방법은 getInstance라는 메서드를 통해 instance에 접근하는 방법이다.
인스턴스 변수에 직접 접근하는 방법에 비해 캡슐화가 잘 된 방법이라 객체지향적인 관점에서 더 괜찮은 방법이다.
public class Member {
private static final Member INSTANCE = new Member();
private Member() {
}
public static Member getInstance(){
return INSTANCE;
}
}
lazy 하게 instance 생성
상황에 따라서 lazy 하게 instance를 생성할 수도 있다.
public class Member {
private static Member instance;
private Member() {
}
public static synchronized Member getInstance(){
if(instance == null) {
instance = new Member();
}
return instance;
}
}
조금 더 실무적인 예를 들어 보면 하나 밖에 없는 Connection 을 공유할 때 일정시간 동안 사용하지 않는 경우 이 커넥션을 끊고 반환해버리는 경우가 있는데 이럴경우 instance의 null 여부를 체크해서 lazy 하게 생성해주는 것이다.
Enum Type으로 Singleton Pattern 사용하기
Effective Java에서 권하는 방식인데, 이방식을 사용하면 더 간결하고, 별도의 노력없이 직렬화 할수 있고, 리플렉션 같은 공경에도 안전한 코드를 작성할 수 있다고 한다.
public enum Notice {
INSTANCE;
private String information;
public Notice getInstance() {
return INSTANCE;
}
public String getInformation() {
return information;
}
public void setInformation(String information) {
this.information = information;
}
}
class Main {
public static void main(String args[]) {
Notice notice1 = Notice.INSTANCE.getInstance();
notice1.setInformation("공지사항 입니다.");
Notice notice2 = Notice.INSTANCE;
System.out.println(notice1.getInformation());
System.out.println(notice2.getInformation());
}
}
하지만 사용하기엔 굉장히 부자연스럽고, enum 이 클래스가 아니기에 실제로 사용하기엔 쉽진 않은 방식이라고 생각한다.
반응형