
새로 시작한 cs 스터디에서 첫 주제(나에게)가 주어졌다..! 일요일까지 공부 후 디스코드에 올리면 된다고 한다.
목차(?) 로는
- 싱글톤 패턴이란? - 간단한 정의/왜 사용하는지
- 싱글톤 패턴의 장단점
- 싱글톤 패턴만들기 - 기본적인 싱글톤 패턴 예제(코드/언어무관)
- 간단한 사용 예
로 구분되어 있다.
열심히 공부해보자..!!😶🌫️
해당 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 패턴.
싱글톤 패턴(Singleton Pattern)은 소프트웨어 디자인 패턴 중 하나로, 객체의 인스턴스가 오직 하나만 생성되는 패턴을 의미한다.
생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 return한다. 쉽게 비유하자면, 커피숍에 하나의 커피 머신만 있고, 여러 손님이 주문해도 항상 그 하나의 커피머신에서 커피가 나온다는 것!
싱글톤 패턴의 사용 이유는 여러 가지가 있는데, 여러 가지를 찾아봤을데 다들 중요하게 말하는 건 메모리 낭비 방지이다.
예를 들어, 10번의 호출이 있을 때마다 계속 객체가 생성되고 소멸된다면 메모리 낭비 문제가 생길 것이다. 그러나 싱글톤 패턴은 오직 하나의 객체를 공유하기 때문에 메모리 낭비가 확실히 줄어드는 것!!이다.
그 외의 이유는 gpt에게 물어보니
으로 정리해줬다. 나만의 방식으로 해석하자면 오직 하나의 인스턴스를 사용하니까 메모리 누수 적고, 코드가 단순하고, 상태 관리에 편리하다!! 이다.
싱클톤 패턴의 단점 역시 여러 가지가 있다.
싱글톤은 전역 상태를 유지하기 때문에 다른 부분에서 예상치 못한 종속성을 만들 수도 있고, 객체 간의 결합도를 높일 수도 있다. 이 때문에 코드가 복잡해지는 단점이 있다.
첫번째는, 테스트의 어려움이다. 한 인스턴스를 공유하고 있기 때문에 테스트가 수행되려면 각각의 테스트가 격리되어야 해서 매번 인스턴스의 상태를 초기화시켜줘야 한다. 그렇지 않으면 이전 테스트의 영향을 받아 예상치 못한 결과가 나올 수 있다.
두번째는, 의존성의 증가다. 싱글톤은 전역 상태를 유지하므로 다른 객체들이 이를 의존할 때 의존성이 증가할 수 있다. 그래서 객체들 간의 결합도를 높이고 유연성을 감소시킬 수 있다.
세번째는, 멀티스레드 환경에서 여러 스레드가 동시에 접근하게 되면 안정성 문제가 발생할 수 있다. 동기화 메커니즘을 사용할 수 있으나 성능 저하가 될 수 있다.
public class Singleton {
// 싱글톤 인스턴스를 전역변수로 선언
private static Singleton instance;
// private 생성자를 사용하여 외부에서의 호출 막기
private Singleton() {}
// getInstance()로 접근
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public void doSomething() {
System.out.println("싱글톤 움직이다..");
}
}
public class Main {
public static void main(String[] args) {
// Singleton 인스턴스 호출
Singleton singleton = Singleton.getInstance();
// 인스턴스 사용
singleton.doSomething();
}
}
난 사실 아직도 용어들에 익숙하지 않아서 나만의 방법으로 쉽게 설명하자면 이렇다.
단 하나의 자동차가 만들어져서 다른 곳에서 그 자동차를 가져와 다른 사용자들이 여러 번 사용하는 것.
하나의 인스턴스만 필요한 경우에 유용하게 사용되는 데, 로그 관리/데이터베이스 연결/설정 관리/캐시 관리 등과 같은 상황에서 많이 사용한다고 한다.
import java.util.Date;
public class LogManager {
// 싱글톤 인스턴스를 저장할 정적 변수
private static LogManager instance;
// private 생성자를 이용하여 외부에서의 인스턴스 생성 방지
private LogManager() {}
// 싱글톤 인스턴스를 반환하는 정적 메서드
public static LogManager getInstance() {
// 인스턴스가 아직 생성되지 않은 경우에만 생성
if (instance == null) {
instance = new LogManager();
}
return instance;
}
// 로그를 기록하는 메서드
public void log(String message) {
// 현재 시간과 메시지를 로그 형식에 맞춰 출력
System.out.println(new Date() + ": " + message);
}
}
// 테스트를 위한 클래스
public class OtherClass{
// 로그 관리자 인스턴스 가져오기
LogManager logManager = LogManager.getInstance();
// 로그 기록
logManager.log("잘 움직이냐~.");
logManager.log("두번째도?");
}
로그 관리를 예를 들면 이렇게 코드를 작성 후 로그가 필요한 부분에서 호출해 다양하게 사용할 수 있다.
아직 공부 중이어서 틀린 내용이나 잘못 이해한 부분이 있을 수 있는데, 그럴 때는 댓글 남겨주세요~!!😊