자바 - 싱글톤 패턴(Singleton Pattern)
<목차>
• 디자인 패턴(Design Pattern)
먼저 싱글톤 패턴이란 디자인 패턴의 종류 중 하나다.
디자인 패턴이란 소프트웨어 개발에서 발생하는 문제들을 해결하기 위해 고안된 재사용 가능한 해결책들의 모음이다.
각 패턴은 개발자들이 검증되고 테스트된 설계 아이디어를 공유하여 효율적이고 구조적으로 좋은 개발을 돕기 위해 만들어졌다. 자바에서 사용되는 대표적인 패턴으로 몇 개 정도를 정리하면 다음과 같다.
• 디자인 패턴의 종류
1. 싱글톤(Singleton) 패턴
단 하나의 인스턴스만 생성하고, 이를 전역적으로 사용할 수 있도록 하는 패턴이다.
클래스의 생성자를 Private로 선언하여 외부에서 직접 인스턴스를 생성할 수 없게 하고, Static 메서드를 통해 유일한 인스턴스에 접근할 수 있도록 해준다. 결과 여러 곳에서 동일한 인스턴스를 사용할 수 있게 된다.
2. 팩토리(Factory) 패턴
객체 생성을 캡슐화하여 클라이언트 코드로부터 객체 생성 로직을 분리하는 패턴이다.
팩토리 클래스는 객체를 생성하는 인터페이스를 제공하고, 클라이언트는 팩토리 클래스를 통해 객체를 생성한다.
이를 통해 클라이언트는 구체적인 객체 생성 방식을 알 필요 없이 객체를 생성할 수 있다.
3. 어댑터(Adapter) 패턴
호환되지 않는 인터페이스를 갖는 두 개의 클래스를 연결해 주는 패턴이다.
어댑터 클래스는 클라이언트가 기대하는 인터페이스를 제공하고, 이를 통해 호환되지 않는 클래스를 사용 가능하게 해 준다. 즉, 기존의 클래스를 수정하지 않고도 사용 가능하게 해 준다.
4. 옵저버(Observer) 패턴
옵저버 패턴은 객체 간의 일대다(1:N) 종속 관계를 정의하는 패턴이다.
주체 객체(Subject)와 여러 개의 옵저버 객체(Observer)로 구성된다.
주체 객체의 상태가 변경되면 등록된 모든 옵저버에게 알림이 전달되고, 옵저버는 주체 객체의 상태 변경을 감지하여 필요한 작업을 수행한다. 이를 통해 객체 간의 느슨한 결합을 실현할 수 있다.
즉, 객체의 변화가 생기면 이를 알리고 필요한 행동을 하는 것이 주된 활동이다.
5. 전략(Strategy) 패턴
전략 패턴은 알고리즘을 동적으로 교체할 수 있도록 하는 패턴이다.
여러 개의 알고리즘을 캡슐화하고, 이를 상호 교환 가능한 형태로 만든다.
클라이언트는 인터페이스를 통해 알고리즘을 사용하고, 실행 지점에 원하는 전략을 선택할 수 있다.
이외에도 디자인 패턴은 많이 존재한다. (정보처리기사 관련 공부를 하면 필수 내용이다.)
각 패턴은 특정한 문제 상황에 적합하게 사용하여 코드의 유지 보수성, 재사용성, 확정성 등을 향상해야 한다.
하지만 과도하게 사용하면 오히려 코드를 복잡하게 만들어 스파게티 코드를 만들어 낼 수 있다.
• 싱글톤 패턴의 예시
여기서 싱글톤 패턴은 저번 게시물에서 다룬 정적 메서드와 밀접한 관련이 있다.
https://bluenoa.tistory.com/73#text3
자바 - Static(정적 메서드와 변수)
Static이란? Static 변수 Static 메서드 • Static이란? java에서 static은 특정 클래스의 멤버 변수 또는 메서드에 대한 키워드로 해당 키워드를 사용하여 선언된 변수나 메서드는 해당 클래스의 인스턴스
bluenoa.tistory.com
싱글톤 패턴은 위에서도 언급했듯이 단 하나의 인스턴스만 생성하고, 이를 전역적으로 접근할 수 있도록 하는 패턴이다.
또, 클래스의 생성자를 Private로 지정하기 때문에 이를 숙지해야 한다.
<예시1 - 예시 참고 : 점프 투 자바>
public Singleton {
private Singleton() {
}
}
// 클래스를 통해 생성할 수 있는 객체는 하나
// 그러나 해당 예시에서는 new를 통해서 여러 개의 객체를 만드는 형태이므로 성립 불가
public class exam {
public static void main(String[] args) {
Singleton singleton = new Singleton(); // 오류 발생
}
}
private를 통해 생성을 했기 때문에 다른 클래스에서 새로운 객체를 생성할 수 없다.
<예시2>
public class Singleton {
private static Singleton var; // 'var'라는 인스턴스 생성
private Singleton() {
// private 키워드를 통해 외부에서는 인스턴스 생성을 방지한다.
System.out.println("정상적으로 성공!");
}
public static Singleton getInstance() {
if (var == null) {
var = new Singleton();
}
return var;
// 인스턴스가 존재하지 않는다면 생성하여 반환
// 사실 특정 기능을 여기에 이어서 작성해도 된다.
// 그저 다른 클래스에서 수행되는 것을 예시로 작성하고 싶었다.
}
}
class Example {
public static void main(String[] args){
Singleton singleton = Singleton.getInstance(); // 인스턴스를 생성하는 클래스 실행
}
}
처음 실행 시 var라는 인스턴스가 없기 때문에 getInstance에서 new Singleton()을 통해서 새롭게 생성 후 반환이 된다.
참고로 'private static Singleton var;'에서 static 정적 변수로 생성되었기 때문에 매번 실행해도 새로 만들어지는 것이 아니라 기존의 것을 계속 사용한다.
만약 Singleton singleton2 = Singleton.getInstace(); 문구를 하나 더 추가하고
System.out.println(singleton = singleton2)라는 문구를 Example 클래스에 작성하면 'true'라는 답이 나온다.
이는 정적 변수를 통해 정의되었기 때문에 첫 번째 실행과 두 번째 실행 모두 같은 var 인스턴스라는 것이다.