반응형
해당 글에서는 싱글턴 패턴(Signleton Pattern)에 대해서 이해를 돕기 위해서 공유하기 위한 목적으로 작성한 글입니다.
1) 디자인 패턴(Design Pattern)
💡 디자인 패턴(Design Pattern)
- 소프트웨어에서 특정 문제를 해결하기 위해 개발된 재사용성이 가능한 솔루션을 의미합니다.
- 디자인 패턴을 통해 재사용성, 유지 보수성, 확장성을 향상하는데 도움이 됩니다
[ 더 알아보기 ]
💡 디자인 패턴의 종류
1️⃣ 생성 패턴 (Creational Patterns)
- 객체의 인스턴스화 과정을 추상화하고, 객체를 생성하는 방법을 다양화하는 패턴입니다. 이에는 Singleton, Factory Method, Abstract Factory 등이 포함됩니다.
2️⃣ 구조 패턴 (Structural Patterns)
- 클래스와 객체를 조합하여 더 큰 구조를 만드는 패턴입니다. 이에는 Adapter, Decorator, Composite 등이 포함됩니다.
3️⃣ 행위 패턴 (Behavioral Patterns)
- 객체 간의 통신과 협력을 다루는 패턴입니다. 이에는 Observer, Strategy, Template Method 등이 포함됩니다.
💡 [참고] 생성 패턴 중 Builder 패턴에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
2) 싱글턴 패턴 (Signleton Pattern)
💡 싱글턴 패턴(Signleton Pattern)
- 소프트웨어 디자인 패턴 중 하나로 클래스의 ‘인스턴스(Instance)가 오직 하나만 생성’되도록 보장하는 패턴으로 ‘전역 변수를 사용하지 않고도 단일 인스턴스에 접근’ 할 수 있도록 합니다.
- 애플리케이션이 실행될 때 ‘최초 한 번만 메모리를 할당’하고 여러 차례 호출이 되더라도 실제로 생성되는 객체는 하나이고 최초 생성된 이후 호출된 생성자는 최초 생성한 객체를 리턴합니다.
- 이를 통해 여러 곳에서 공유하여 사용할 수 있으므로 메모리 절약 및 자원 관리 등의 장점을 얻을 수 있습니다.
- 또한 이를 통해 생성된 리소스에 대한 중복 액세스를 피하고 객체 간의 일관성을 유지하기 위해 사용되며 주로 로깅, 드라이버 개체, 캐싱 및 스레드 풀, 데이터베이스 연결에 사용됩니다.
[ 더 알아보기 ]
💡 싱글턴 패턴의 사용예시
1️⃣ 데이터베이스 연결
- 데이터베이스 연결은 일반적으로 오버헤드가 큰 작업이므로, 매번 연결 객체를 새로 생성하는 것은 비효율적입니다. 이런 경우 싱글턴 패턴을 사용하여 하나의 연결 객체를 생성하고, 다른 클래스에서 이 객체를 공유하여 사용할 수 있습니다.
- 여러 객체가 공유하는 단일 DB 연결은 모든 객체에 대해 별도의 DB 연결을 생성하는 데 비용이 많이 들 수 있습니다. 그렇기에 단일 인스턴스를 사용하는 싱글턴 패턴을 이용합니다.
2️⃣ 로깅 시스템
- 애플리케이션 전반에서 로그를 기록하고 관리하기 위해 사용되는데, 이때 싱글턴 패턴을 사용하면 여러 곳에서 동시에 로깅 시스템에 접근하여 로그를 기록할 수 있습니다. 이를테면, 여러 스레드에서 동시에 로그를 작성하더라도 싱글턴 패턴을 사용하면 하나의 로깅 인스턴스를 통해 동시에 로그를 기록할 수 있습니다.
1. 싱글턴 패턴 (Signleton Pattern) 특징
특징 | 설명 |
인스턴스의 유일성 보장 | 싱글턴 패턴은 클래스의 인스턴스가 오직 하나만 생성되도록 보장합니다. 이를 통해 메모리 낭비를 방지하고, 여러 곳에서 일관된 방식으로 인스턴스에 접근할 수 있습니다. |
안전한 인스턴스 생성 | 다중 스레드 환경에서 싱글턴 패턴을 사용하면 인스턴스 생성이 안전하게 이루어집니다. 여러 스레드에서 동시에 인스턴스를 생성하려는 경우, 동기화 메커니즘을 사용하여 하나의 인스턴스만 생성되도록 보장할 수 있습니다. |
전역적인 접근성 | 싱글턴 패턴을 사용하면 어디서든 쉽게 인스턴스에 접근할 수 있습니다. 전역 변수로 선언될 수 있어 다른 객체들이 인스턴스에 접근할 수 있고, 필요한 경우 인스턴스를 공유하여 사용할 수 있습니다. |
[ 더 알아보기 ]
💡 비즈니스 로직에서 싱글턴 패턴이 사용되는 경우
1️⃣ 공유 리소스에 대한 접근 제한
- 여러 스레드 또는 다른 객체가 동시에 공유 리소스에 접근해야 할 때, 싱글턴 패턴을 사용하여 하나의 인스턴스를 공유하여 동시에 접근할 수 있습니다. 이를테면, 데이터베이스 연결, 로깅 기능 등이 있습니다.
2️⃣ 상태 유지
- 어떤 객체의 상태를 유지해야 하는 경우, 싱글턴 패턴을 사용하여 하나의 인스턴스를 생성하고 상태를 공유할 수 있습니다. 이를테면, 애플리케이션 설정 정보, 캐시 등이 있습니다.
3️⃣ 리소스 절약
- 객체 생성과 소멸에 대한 오버헤드가 큰 경우, 싱글턴 패턴을 사용하여 하나의 인스턴스를 생성하고 재사용함으로써 리소스를 절약할 수 있습니다. 이를테면, 스레드 풀, 프린터 스풀링 등이 있습니다.
2. 싱글턴 패턴 (Signleton Pattern) 동작 과정
💡 싱글턴 패턴 (Signleton Pattern) 동작 과정
- 아래의 그림은 설명을 위해 작성한 그림입니다. Singleton Class와 Test Class1, Test Class2의 3개의 클래스가 존재한다고 가정합니다.
- Singleton Class 내에서는 Client A, B, C라는 메서드가 존재하고, Singleton Object라는 인스턴스를 구성하였습니다.
- Test Class 내에서는 이 Singleton Class의 인스턴스를 가져와서 Client A, B, C에 접근이 가능합니다.
💡 해당 과정을 통해 static method를 호출하여 '하나의 인스턴스'를 생성하여 메서드에 접근할 수 있습니다.
💡 동작 과정에 대한 예시
1. 클래스의 변수를 선언하는데 내부적으로 접근이 가능하며 클래스 내부에서만 공유가 가능하도록 변수를 구성하였습니다.
2. 외부 클래스에서 해당 클래스의 인스턴스화를 방지하기 위해 빈 형태의 생성자를 구성하였습니다.
3. 외부에서 접근이 가능하며 구성된 인스턴스를 의미합니다.
4-1, 4-2, 4-3 클래스 내에서 구성한 메서드입니다.
package com.adjh.multiflexapi.modules.practies.singleton;
/**
* 싱글턴 패턴을 연습하기 위한 모듈
*/
public class SingletonBasic {
// 1. 내부적만 접근이 가능한 변수를 구성
private static final SingletonBasic instance = new SingletonBasic();
// 2. 외부에서 인스턴스화를 방지하기 위해 생성자 구성.
private SingletonBasic() {
//
}
// 3. 구성된 인스턴스를 호출 할 수 있는 메서드
public static SingletonBasic getInstance() {
return instance;
}
// 4-1. Client A Method
public void clientA() {
System.out.println("[+] Client A 메서드입니다.");
}
// 4-2. Client B Method
public void clientB() {
System.out.println("[+] Client B 메서드입니다.");
}
// 4-3. Client C Method
public void clientC() {
System.out.println("[+] Client C 메서드입니다.");
}
}
💡 호출 부분 예시
- 해당 예시에서는 싱글턴 패턴으로 구성한 클래스를 외부 클래스에서 호출하는 방법입니다.
- Singleton 클래스를 인스턴스화하는데, getInstance()를 통해 단일 인스턴스를 반환하도록 하였습니다.
- 반환받은 인스턴스에서 .clientA(), .clientB(), .clientC() 함수를 호출합니다.
SingletonBasic singletonBasic = SingletonBasic.getInstance();
singletonBasic.clientA(); // [+] Client A 메서드입니다.
singletonBasic.clientB(); // [+] Client B 메서드입니다.
singletonBasic.clientC(); // [+] Client C 메서드입니다.
[ 더 알아보기 ]
💡private static
- 클래스 내부에서만 접근 가능하고, 클래스의 모든 인스턴스가 공유하는 변수로 사용됩니다.
3. 싱글턴 패턴 (Signleton Pattern)과 일반 형태와 비교
💡 싱글턴 패턴 (Signleton Pattern)과 일반 패턴 비교
- 일반 메서드는 싱글턴 패턴과 비교하면 일반 메서드에서는 중복된 리소스가 발생할 수 있습니다.
💡 일반 클래스인 MyClass는 각각 독립적인 속성을 가지는 인스턴스를 생성합니다.
- instance1과 instance2는 서로 다른 이름을 가지고 있으며, 각각의 printName() 메서드를 호출하면 해당 인스턴스의 이름을 출력합니다.
💡 싱글턴 패턴인 SingletonClass는 인스턴스가 오직 하나만 생성되도록 보장합니다.
- getInstance() 메서드를 통해 싱글턴 클래스의 인스턴스를 반환하게 됩니다.
- 이렇게 반환된 인스턴스는 모든 인스턴스가 동일한 속성을 공유하게 됩니다. 따라서 singletonInstance1과 singletonInstance2는 동일한 인스턴스를 참조하고 있으므로, 두 인스턴스가 같은지 비교하면 true를 반환합니다.
// =============================================== 일반 클래스 ===============================================
public class MyClass {
private String name;
public MyClass(String name) {
this.name = name;
}
// 인스턴스의 이름 출력
public void printName() {
System.out.println(this.name);
}
}
// 일반 클래스의 인스턴스 생성
MyClass instance1 = new MyClass("Instance 1");
MyClass instance2 = new MyClass("Instance 2");
// 각 인스턴스의 독립적인 속성 출력
instance1.printName(); // Output: Instance 1
instance2.printName(); // Output: Instance 2
// =============================================== 싱글턴 패턴 ===============================================
public class SingletonClass {
private static SingletonClass _instance;
private SingletonClass() {}
// 싱글턴 클래스의 인스턴스 반환
public static SingletonClass getInstance() {
if (_instance == null) {
_instance = new SingletonClass();
}
return _instance;
}
}
// 싱글턴 클래스의 인스턴스 생성
SingletonClass singletonInstance1 = SingletonClass.getInstance();
SingletonClass singletonInstance2 = SingletonClass.getInstance();
// 모든 인스턴스가 동일한 속성을 공유
System.out.println(singletonInstance1 == singletonInstance2); // Output: true
4. 싱글턴 패턴 (Signleton Pattern)의 문제점
💡 싱글턴 패턴 (Signleton Pattern)의 문제점
문제점 | 설명 |
전역 상태(높은 의존성) | 싱글턴은 전역 상태를 사용하므로 객체의 상태 변경이 전역적인 영향을 미칩니다. 이는 코드의 의존성을 높이고 테스트 및 유지보수를 어렵게 만듭니다. |
멀티스레드 환경 | 멀티스레드 환경에서 싱글턴을 사용할 경우 동시에 여러 스레드가 인스턴스를 생성하려고 할 수 있습니다. 이로 인해 인스턴스가 여러 개 생성될 수 있으며, 싱글턴의 의도와 다른 동작을 할 수 있습니다. 이를 해결하기 위해서는 동기화 메커니즘을 사용해야 합니다. |
유연성 부족 | 싱글턴은 하나의 인스턴스만 생성되므로, 다른 타입의 인스턴스로 교체하기가 어렵습니다. 이는 특히 테스트나 확장성을 고려할 때 문제가 될 수 있습니다. |
3) 싱글턴 패턴 (Signleton Pattern) 종류
0. 요약
싱글턴 종류 | 설명 |
지연 초기화(Lazy Initialization) | 객체가 처음으로 접근될 때만 초기화되는 방식입니다. |
이른 초기화(Eager Initialization) | 객체가 생성되자마자 즉시 초기화되는 방식입니다. |
쓰레드 안전 지연 초기화(Thread safe Lazy initialization) | 다중 스레드 환경에서 경합 조건을 방지하여 지연 초기화를 쓰레드 안전하게 보장하는 방식입니다. |
정적 블록 초기화(Static block initialization) | 정적 블록 코드 내에서 해당 객체를 초기화하는 방식입니다. |
더블 체크 락킹(DCL: Double-Checked Locking) | 더블 체크 락킹을 사용하여 성능을 최적화하고 쓰레드 안전한 지연 초기화 메커니즘을 제공하는 방식입니다. |
빌 퓨 솔루션(Bill Pugh Solution) | 쓰레드 안전한 방식으로 지연 초기화를 달성하기 위해 정적 내부 도우미 클래스를 활용하는 방식입니다. |
Enum 활용방식 | 열거형을 사용하여 싱글톤 인스턴스를 정의하는 방식입니다. |
💡 싱글턴 패턴의 종류별 변화
➡️ 이른 초기화 → (개선) → 정적 블록 초기화
➡️ 지연 초기화 방식 → (개선) → 스레드 안전 지연 초기화
➡️ 스레드 안전 지연 초기화 → (멀티스레드 환경) → 더블 체크 락킹
➡️ 지연 초기화 방식 + 스레드 안전 지연 초기화 = 빌 퓨 솔루션
➡️ 최종 간략 방식 → Enum 활용방식
1. 지연 초기화 방식 (Lazy Initialization)
💡 지연 초기화 방식 (Lazy Initialization)
- 인스턴스가 클래스가 로드되는 시점이 아닌 사용자가 사용하기 전까지 생성을 지연하는 방법을 의미합니다.
- 이를 통해 자원의 낭비를 방지하고 필요한 시점에 인스턴스를 생성할 수 있습니다.
💡 지연 초기화 방식 (Lazy Initialization) 동작 방식
1. 처음으로 싱글턴 클래스를 참조할 때, 인스턴스가 생성되지 않은 경우에만 인스턴스를 생성합니다.
2. 인스턴스가 생성되면, 이후에는 생성된 인스턴스를 반환합니다.
3. getInstance() 메서드를 호출할 때, 인스턴스가 생성되지 않은 경우에만 인스턴스를 생성하고 반환합니다.
💡 이를 통해 필요한 시점에 인스턴스를 생성하며, 자원의 효율성을 높일 수 있습니다.
public class Singleton {
private static Singleton instance;
private Singleton() {
// Private constructor to prevent instantiation from outside
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
💡 지연 초기화 방식 (Lazy Initialization)에 대한 문제점
1. 동기화 문제
- 멀티스레드 환경에서는 동기화 문제가 발생할 수 있으므로 안전하지 않을 수 있습니다.
2. 초기화 시간
- 이른 초기화에 비해 상대적으로 초기화 시간이 오래 걸릴 수 있습니다.
3. 메모리 사용량
- 사용하기 직전에 사용되기에 메모리 사용량이 증가할 수 있습니다.
2. 이른 초기화 방식(Eager Initialization)
💡 이른 초기화 방식(Eager Initialization)
- 인스턴스를 필요한 시점과 상관없이 ‘클래스가 로드될 때 인스턴스를 생성’하는 방법을 의미합니다.
- Lazy Initialization의 동기화 문제를 회피할 수 있지만, 애플리케이션이 시작될 때부터 인스턴스가 생성되므로 자원의 낭비가 발생할 수 있습니다.
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// Private constructor to prevent instantiation from outside
}
public static Singleton getInstance() {
return instance;
}
}
💡 이른 초기화 방식(Eager Initialization)에 대한 문제점
1. 애플리케이션에서 인스턴스를 사용하지 않더라도 인스턴스가 생성이 되는 문제가 있습니다.
2. 코드에 대한 예외 처리가 없는 문제점이 있습니다.
3. 스레드 안전 지연 초기화(Thread safe Lazy initialization)
💡 스레드 안전 지연 초기화(Thread safe Lazy initialization)
- Lazy Initialization 방식을 개선한 방식으로 ‘멀티 스레드 환경에서 안전하게 인스턴스를 생성’할 수 있도록 구성한 방법을 의미합니다.
- 다중 스레드 환경에서는 두 개 이상의 스레드가 동시에 인스턴스를 생성하려고 할 수 있기 때문에 인스턴스 생성 메서드에 동기화(synchronization)를 적용하여 한 번에 한 스레드만 인스턴스를 생성하도록 합니다.
public class Singleton {
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
[ 더 알아보기 ]
💡 synchronized
- Java에서 멀티스레드 환경에서의 동기화를 달성하기 위해 사용됩니다. 또한 이를 사용하면 여러 스레드가 동일한 객체 또는 메서드를 동시에 액세스 하지 못하도록 할 수 있습니다.
- 이를 통해 스레드 간의 충돌이나 경쟁 조건을 방지하고 데이터 일관성을 유지할 수 있습니다.
- Synchronized 키워드는 객체나 메서드의 선언부에 추가됩니다.
- 예를 들어 한 스레드가 해당 변수의 접근 중인 동안 다른 스레드가 접근하지 못하도록 할 수 있습니다.
💡 스레드 안전 지연 초기화(Thread safe Lazy initialization) 문제점
1. 동시에 여러 스레드가 초기화를 수행할 경우 경합 상태 (race condition)가 발생할 수 있습니다.
2. 여러 스레드가 동시에 초기화 코드를 실행하면서 원치 않은 결과를 가져올 수 있음을 의미합니다.
3. 스레드 안전 지연 초기화는 매번 인스턴스를 생성할 때마다 초기화 코드를 실행하게 됩니다. 이는 성능 저하를 초래할 수 있습니다.
4. 코드의 복잡성을 증가시킬 수 있습니다. 동기화와 관련된 추가적인 코드를 작성해야 하며, 이는 가독성과 유지보수성을 저하시킬 수 있습니다.
4. 정적 블록 초기화 (Static block initialization)
💡 정적 블록 초기화 (Static block initialization)
- 이른 초기화(Eager Initialization) 방식과 유사하지만 클래스가 로딩될 때 생성되지 않고 ‘정적 블록(static block) 내에서 생성되고 예외 처리가 가능한 방법’을 의미합니다.
- 클래스의 정적 블록은 클래스가 로드될 때 실행되는 특별한 블록으로 클래스 변수의 초기화나 다른 초기화 작업을 수행하는 데 사용합니다.
💡 정적 블록 초기화 (Static block initialization) 동작방식
1. static 블록을 사용하여 Singleton 클래스의 인스턴스를 초기화합니다.
2. static 블록은 클래스가 로드될 때 실행되므로, Singleton 클래스가 사용되기 전에 한 번만 실행되고 인스턴스가 생성됩니다.
public class StaticBlockSingleton {
private static StaticBlockSingleton instance;
private StaticBlockSingleton(){}
//static block initialization for exception handling
static{
try{
instance = new StaticBlockSingleton();
}catch(Exception e){
throw new RuntimeException("Exception occured in creating singleton instance");
}
}
public static StaticBlockSingleton getInstance(){
return instance;
}
}
💡 정적 블록 초기화 (Static block initialization)의 문제점
1. 순서 의존성 문제
- 클래스 내에 여러 개의 정적 블록이 있을 경우, 이들의 실행 순서가 중요합니다. 만약 순서를 잘못 설정하거나 의존성이 있는 경우, 예상치 못한 동작이 발생할 수 있습니다.
2. 예외 처리 문제
- 정적 블록은 예외를 던질 수 있습니다. 예외가 발생하면 클래스의 초기화가 완료되지 않아, 해당 클래스를 사용할 수 없는 상태가 됩니다.
3. 가독성과 유지 보수 문제
- 정적 블록은 클래스의 초기화 과정을 복잡하게 만들 수 있습니다. 코드가 길어지고 가독성이 떨어지며, 유지 보수가 어려워질 수 있습니다.
5. 더블 체크 락킹(DCL: Double-Checked Locking)
💡 더블 체크 락킹(Double-Checked Locking)
- 멀티스레드 환경에서 Lazy Initialization을 구현하기 위한 동기화 메커니즘 중 하나로 두 번 검사를 수행하여 인스턴스의 생성 여부를 확인합니다.
- 첫 번째 검사는 동기화 블록에 진입하기 전에 수행되며, 인스턴스가 이미 생성되어 있는지 확인합니다.
- 두 번째 검사는 동기화 블록 내부에서 수행되며, 인스턴스가 아직 생성되지 않은 경우에만 인스턴스를 생성합니다.
💡 더블 체크 락킹(Double-Checked Locking) 동작방식
1. 첫 번째 검사와 두 번째 검사를 수행하는 블록 내부에 synchronized 키워드를 사용합니다
2. 인스턴스가 이미 생성되었는지 확인하기 위해 동기화 블록에 진입하기 전에 수행
3. 동기화 블록 내부에서 인스턴스를 생성
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
[ 더 알아보기 ]
💡volatile
- 모든 스레드가 해당 변수에 대한 작업을 메인 메모리에서 직접 수행하게 됩니다. 이는 변수의 값을 읽고 쓸 때 CPU 캐시를 거치지 않고 항상 메인 메모리를 통해 이루어진다는 것을 의미합니다.
- volatile 변수를 사용하면 스레드 간의 데이터 동기화가 보장됩니다. 한 스레드에서 변수의 값을 변경하면, 다른 스레드에서는 변경된 값을 즉시 읽을 수 있습니다. 이는 스레드 간의 데이터 일관성을 유지하기 위해 매우 중요합니다.
💡 더블 체크 락킹(Double-Checked Locking) 문제점
1. 스레드 안전성 문제
- 초기화되지 않은 객체에 동시에 접근할 수 있는 상황이 발생할 수 있습니다. 이로 인해 예상치 못한 동작이 발생할 수 있습니다.
2. 메모리 가시성 문제
- 객체가 생성되기 전에 다른 스레드에서 접근할 수 있는 경우, 초기화되지 않은 객체에 접근할 수 있습니다. 이는 예기치 않은 결과를 초래할 수 있습니다.
3. 코드 복잡성 문제
6. 빌 퓨 솔루션(Bill Pugh Solution)
💡 빌 퓨 솔루션(Bill Pugh Solution)
- 스레드 안정성(thread-safety)과 지연 초기화(lazy initialization)를 보장하는 Singleton 객체를 생성하는 데 사용됩니다.
- 이 방법은 내부 정적 클래스를 사용하여 Singleton 인스턴스를 생성하고, 이를 외부에서 접근할 수 있는 public 메서드를 통해 제공합니다.
- 이 방식은 다중 스레드 환경에서 안전하고 성능이 우수한 Singleton 객체를 생성하는 데 도움이 됩니다
public class Singleton {
private Singleton() {
// private constructor to prevent instantiation
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
💡 빌 퓨 솔루션(Bill Pugh Solution) 문제점
1. 클래스 복잡성
- 빌 퓨 솔루션은 내부적으로 정적 중첩 클래스를 사용하여 스레드 안전성을 보장합니다. 이로 인해 클래스의 구조가 복잡해지고, 코드 가독성이 떨어질 수 있습니다.
2. 초기화 시간
- 빌 퓨 솔루션은 초기화되지 않은 객체에만 동기화를 적용하기 때문에, 초기화되지 않은 객체에 접근하는 시간이 더 오래 걸릴 수 있습니다.
3. 내부 클래스 사용
- 빌 퓨 솔루션은 내부적으로 정적 중첩 클래스를 사용하여 스레드 안전성을 보장합니다. 이는 클래스의 구조를 더 복잡하게 만들고, 유지 보수를 어렵게 할 수 있습니다.
7. Enum 활용방식
💡 Enum 활용방식
- 스레드 안정성과 직렬화(serialization) 문제를 자동으로 처리하며, 코드가 간결하고 명확하게 사용할 수 있는 방식입니다.
- enum 내부에 인스턴스를 정의하고 해당 인스턴스를 사용하여 싱글턴 객체에 접근합니다.
- enum은 JVM에서 싱글턴을 보장하므로 다중 스레드 환경에서 안전하게 사용할 수 있습니다.
💡 Enum 동작 방식 : 생성
1. Singleton.INSTANCE을 통해 싱글턴 객체에 접근할 수 있습니다.
2. enum은 JVM에서 보장되는 유일한 인스턴스를 제공하므로, 스레드 안전성과 직렬화 문제를 걱정하지 않고 싱글턴 객체를 사용할 수 있습니다.
public enum Singleton {
INSTANCE; // 싱글턴 객체를 의미합니다.
// 필요한 멤버 변수와 메서드를 선언할 수 있습니다.
public void performOperation() {
// 싱글턴 객체의 동작을 정의합니다.
}
}
💡 Enum 동작 방식 : 호출
// Singleton 인스턴스의 performOperation() 메서드를 호출합니다.
Singleton.INSTANCE.performOperation();
[ 더 알아보기 ]
💡Enum
- Java에서 열거형 상수를 정의하고 사용하기 위한 특별한 데이터 타입입니다.
- 열거형 상수는 특정한 값을 가지는 고유한 상수로 정의되며, enum은 이러한 상수 집합을 나타내는 데 사용됩니다.
💡 Enum 활용방식 문제점
1. enum을 이용한 패턴은 상속을 지원하지 않으므로, 다른 클래스를 상속하는 경우에는 사용할 수 없습니다.
참고사이트
오늘도 감사합니다. 😀
반응형
'Java > 아키텍처 & 디자인 패턴' 카테고리의 다른 글
[Java/디자인 패턴] 메서드 체이닝(Method Chaining), 플루언트 인터페이스(Fluent Interface), 빌더 패턴(Builder Pattern) (0) | 2024.03.04 |
---|---|
[Java] 람다식(Lambda Expression), 함수형 인터페이스(Functional Interface) 이해하기 (1) | 2023.12.05 |
[Java] Spring Framework 주요 특징 이해하기 : DI, IoC, POJO, AOP (1) | 2023.10.28 |
[Java] MacOS 환경에서 Java JDK 설정 및 변경하기 : homebrew, 다운로드 파일 (2) | 2023.06.28 |
[Java] Gradle 버전 확인 및 변경 방법 (2) | 2023.06.27 |