안녕하세요
팀의 소스코드에서 싱글톤을 사용하는 것을 본 이후로 싱글톤 패턴에 대해서 공부해봐야지라는 생각을 했습니다. 하지만 막상 어떨 때 어떻게 써야 할지 몰라서 공부를 못하고 있다가 이번에 싱글톤 패턴을 쓰기 좋은 기회가 온 것 같아 공부해 사용해보려고 합니다.
그래서 이번 글에서는 객체지향의 디자인 패턴중싱글톤 패턴에 대해서 알아보도록 하겠습니다.
싱글톤 패턴
싱글톤 패턴은 인스턴스가 프로그램에서 하나만 생성되고, 어디서든 인스턴스에 접근할 수 있도록 하는 패턴입니다.
아래의 코드를 통해 이해해보도록 하겠습니다.
public class Singleton {
private static Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (Singleton.instance == null) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
일단 싱글톤의 특징은 private 생성자를 가진다는 것과 인스턴스, 인스턴스에 접근하는 메서드(getInstance()) 가 static 으로 선언되었다는 점입니다.
getInstance() 메소드가 실행되면 인스턴스가 존재하는지 확인한 후 없다면 생성자를 통해 할당하고 인스턴스를 반환합니다.
public class Singleton {
private static Singleton instance;
private int count;
private Singleton() { }
public static Singleton getInstance() {
if (Singleton.instance == null) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
public void printCount() {
System.out.println(count);
}
public void increaseCount() {
this.count += 1;
}
}
public class Main {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton.increaseCount();
singleton.printCount();
Singleton singleton2 = Singleton.getInstance();
singleton2.printCount();
}
}
위의 코드는 멤버 변수로 count를 가지고 count를 출력하고, 증가시키는 메소드를 가집니다.
메인에서 singleton 이라는 인스턴스를 가져온 후 증가시키고 출력합니다. singleton2 라는 인스턴스를 가져온 후 출력한다면 결과 값은 결국 각각 1, 1 이 찍히게 됩니다.
멀티 쓰레드
위의 코드는 멀티 쓰레드 환경에서 문제점이 발생합니다.
멀티 쓰레드일 경우 위의 인스턴스가 생성되었는지 확인하는 부분이 동시에 처리되어 여러 가지 인스턴스가 만들어질 수 도 있고, 멤버 변수의 값이 다른 프로세스에서 처리한다면 값이 일관되지 않을 수 있습니다. 이를 해결하기 위한 방법은 두 가지가 있습니다.
정적 변수에 바로 인스턴스를 만들어 초기화하는 방법
public class Singleton {
private static Singleton instance = new Singleton();
private int count;
private Singleton() { }
public static Singleton getInstance() {
return Singleton.instance;
}
public void printCount() {
System.out.println(count);
}
public void increaseCount() {
this.count += 1;
}
}
위와 같은 방법으로 처음부터 인스턴스를 초기화합니다. 이 방법으로 인스턴스가 여러 가지 만들어지는 문제는 해결할 수 있습니다.
하지만 이 방법으로는 값을 일관시킬 수는 없습니다. 값을 일관시키기 위해서는 _synchronized _ 라는 키워드를 통해 값을 변형하는 메서드에 동기화하는 방법이 있습니다. 이에 관련된 내용은 아래 참고 문서를 확인하시면 더 자세하게 확인할 수 있습니다. 저는 DBCP와 비슷하게 구현할 목적으로 인스턴스의 상태를 변화시키지 않습니다. 그러므로 동기화하는 방법은 더 자세히 알아보도록 하겠습니다.
참고 문서
https://gmlwjd9405.github.io/2018/07/06/singleton-pattern.html
'개발 > 객체지향' 카테고리의 다른 글
어댑터 패턴 (Adapter Pattern) (0) | 2021.04.05 |
---|---|
빌더 패턴 (Builder Pattern) (0) | 2021.03.29 |
객체지향 SOLID 원칙 (2) | 2021.03.27 |