싱글톤 패턴은 디자인 패턴 중 하나로, 특정 클래스의 인스턴스가 전체 시스템에서 오직 '한 개'만 생성되도록 보장하는 것을 목적으로 한다. 이 패턴을 사용하면 전역 변수를 사용하지 않고도 특정 클래스의 인스턴스에 대한 전역 접근이 가능하며, 이를 통해 코드의 유연성과 유지 보수성을 높일 수 있다. 예를 들어 로깅 라이브러리를 구현할 때, 여러 곳에서 로그를 출력하게 된다고 해보자. 이때 각각의 로그 출력 메서드마다 로깅 객체를 생성된다면 시스템 리소스의 낭비가 발생할 수 있다. 따라서, singleton 패턴을 사용하여 로깅 객체를 전체 시스템에서 한 번만 생성하도록 보장할 수 있다.
다음은 Java로 나타낸 싱글톤 패턴의 예제 코드다.
public class Logger {
// 인스턴스 변수
private static Logger instance = null;
// 생성자를 private로 만들어 다른 클래스에서 인스턴스 생성을 막는다.
private Logger() {}
// getInstance() 메소드를 통해 전역적으로 유일한 인스턴스를 반환한다.
public staitc Logger getInstance() {
if(instance == null) {
instance = new Logger();
}
return instance;
}
// 로그를 출력하는 메소드
public void log(String message){
System.out.println(message);
}
}
// Logger 인스턴스를 가져와서 로그를 출력한다.
Logger logger = Logger.getInstance();
logger.log("Hello, world!");
위 예시에서, Logger 클래스는 생성자를 private으로 만들어 다른 클래스에서 인스턴스를 생성할 수 없도록 했다. 대신, getInstance() 메서드를 통해 전역적으로 유일한 인스턴스를 반환하도록 했다. 이렇게 함으로써, Logger 클래스의 인스턴스는 오직 한 개만 생성될 수 있도록 보장할 수 있다. 위의 코드에서 Logger 클래스의 인스턴스를 가져와서 로그를 출력하게 되는데, 이때 getInstance() 메서드를 사용해 전역적으로 유일한 인스턴스를 가져오도록 했다. 따라서, Logger 클래스의 인스턴스는 오직 한 개만 생성되며, 로그를 출력하는 코드에서는 이를 공유하여 사용할 수 있다.
Singleton 패턴의 장점은 다음과 같다,.
1. 전역적인 인스턴스
singleton 패턴은 전역적으로 하나의 인스턴스만을 유지하므로, 모든 코드에서 해당 인스턴스에 대해 접근할 수 있다.
2. 리소스 절약
객체를 여러 번 생성하지 않으므로, 시스템 자원을 절약할 수 있다.
3. 데이터 공유
하나의 인스턴스를 공유하기 때문에, 데이터를 공유하거나 데이터를 수정하기 용이하다.
Singleton 패턴의 단점은 다음과 같다.
1. 테스트가 어려움
전역적인 인스턴스를 사용하므로, 테스트할때 다른 인스턴스를 사용할 수 없어 테스트가 어려울 수 있다.
2. 결합도 증가
다른 객체와의 결합도가 높아지므로, 유지보수가 어려워질 수 있다.
3. 멀티스레딩 이슈
싱글톤 패턴을 사용할 때, 멀티스레드 환경에서 동시에 인스턴스를 생성하려는 이슈가 발생할 수 있다.
그럼 Singleton 패턴을 언제 사용하는 것이 좋을지에 대해 알아본다면 다음이 있다.
1. 전역적으로 사용되는 객체
어떤 객체가 전체 시스템에서 단 하나만 존재해야할 때 사용한다.
2. 자원의 낭비를 방지해야 할 때
객체를 여러 개 생성할 필요가 없으므로, 시스템 자원의 낭비를 방지하기 위해 싱글톤 패턴을 사용한다.
3. 공유 자원
싱글톤 패턴을 사용하여 전역적으로 인스턴스를 공유할 수 있다. 예를 들어, 로깅이나 설정 정보를 공유하는 경우에 사용하기 적합하다.
4. 동일한 객체의 상태를 유지할 때
싱글톤 패턴을 사용해 하나의 인스턴스를 사용하면, 해당 객체의 상태를 유지할 수 있다.
Singleton 패턴은 다음과 같은 특징을 가지고 있다.
- 클래스 내부에서 인스턴스를 생성하고, 외부에서 직접 생성할 수 없도록 생성자를 private으로 선언한다.
- 유일한 인스턴스에 접근하기 위한 public static 메서드를 제공한다.
- 인스턴스가 이미 생성되어 있으면 해당 인스턴스를 반환하고, 생성되어 있지 않으면 인스턴스를 생성한 후 반환한다.
다음은 TypeScript를 사용한 싱글톤 패턴 예제 코드다.
class Singleton {
private static instance: Singleton;
// 생성자를 private으로 선언해 외부에서 인스턴스 생성을 막는다.
private constructor() {}
// 인스턴스를 반환하는 메서드를 static으로 선언하여 전역적으로 접근할 수 있게한다.
public static getInstance(): Singleton {
if(!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
public doSomething(): void {
console.log("Singleton instance is doing something...");
}
}
// Singleton 클래스의 인스턴스를 생성할 수 없다.
// const instance = new Singleton(); // Error: 'constructor' is private.
// Singleton 클래스의 인스턴스는 getInstance 메서드를 통해서만 생성한다.
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
instance1.doSomething(); // "Singleton instance is doing something..."
instance2.doSOmething(); // "Singleton instance is doing something..."
위 코드에서 Singleton 클래스를 정의하고, private 생성자를 선언해 외부에서 인스턴스 생성을 막는다. 인스턴스를 반환하는 getInstance 메서드를 static으로 선언해 전역적으로 접근할 수 있도록 한다. 이때, 인스턴스가 생성되어 있지 않은 경우에만 인스턴스를 생성하고 반환하게 한다.
실제로 인스턴스를 사용할 때에는 getInstance 메서드를 호출해 인스턴스를 생성하고, 반환된 인스턴스에서 메서드를 호출한다. 인스턴스는 한 번 생성되면 전역적으로 유지되므로, 여러 곳에서 같은 인스턴스를 사용할 수 있다.
'개발지식' 카테고리의 다른 글
Entity, Repository 개념 & 프론트엔드에 적용하기 (0) | 2023.04.05 |
---|---|
[WEB] 쿠키(Cookie)와 세션(Session) 개념 익히기 (0) | 2020.12.08 |