출처 : 디자인 패턴에 뛰어들기 - 알렉산더 슈베츠 도서
싱글턴
클래스에 인스턴스가 하나만 있도록 하면서 이 인스턴스에 대한 전역 접근(액세스) 지점을 제공하는 생성 디자인패턴이다.
문제
싱글턴 패턴은 한 번에 두 가지의 문제를 동시에 해결함으로써 단일 책임 원칙을 위반한다.
- 1. 클래스에 인스턴스가 하나만 있도록 한다.
- 클래스의 인스턴스를 제어하는 가장 일반적인 이유는 공유 리소스(예: 데이터베이스 또는 파일)에 대한 접근을 제어하기 위해서이다.
- 객체를 생성하고 나면, 같은 객체를 계속 사용할 수 있다.
클라이언트들은 항상 같은 객체와 작업하고 있다는 사실을 인식조차 못 할 수 있다.
- 2. 전역 접근 지점을 제공한다.
- 필요한 객체에 쉽게 접근할 수 있지만, 이로 인해 다른 코드가 객체를 덮어쓸 수 있어 충돌 가능성이 있다.
- 싱글턴 패턴은 이러한 문제를 방지할 수 있다.
- 코드를 모듈화하여 문제 해결 코드를 한 곳에 집중시킬 수 있다.
최근에는 싱글턴 패턴이 일부 문제만 해결해도 사용될 수 있습니다.
해결책
싱글턴 구현은 일반적으로 다음 두 가지 단계로 이루어진다.
- 클래스의 생성자를 비공개로 설정하여 외부에서 인스턴스를 생성할 수 없게 한다.
- 정적 메서드를 사용하여 객체를 생성하고 이를 저장한 후, 해당 객체를 반환하도록 한다.
- 이렇게 하면 항상 동일한 객체가 반환된다.
- 이렇게 하면 항상 동일한 객체가 반환된다.
실제상황 적용
정부는 싱글턴 패턴의 좋은 예입니다.
국가는 하나의 공식 정부만 가질 수 있으며, 'X의 정부'라는 용어는 해당 정부의 책임자들을 식별하는 글로벌 접근 지점이다.
구조
- 싱글턴 클래스는 getInstance라는 정적 메서드를 선언하여 자체 클래스의 동일 인스턴스를 반환한다.
- 이 메서드를 통해 클라이언트는 싱글턴 객체에 접근할 수 있다.
- 이 메서드를 통해 클라이언트는 싱글턴 객체에 접근할 수 있다.
의사코드
- 해당 예시는 데이터베이스 연결 클래스는 싱글턴 역할을 한다.
- 공개 생성자가 없으므로 getInstance 메서드를 통해 객체를 가져올 수 있다.
- 이 메서드는 초기에 객체를 생성하고 이후 호출에서는 캐시된 객체를 반환한다.
- 이 메서드는 초기에 객체를 생성하고 이후 호출에서는 캐시된 객체를 반환한다.
‘// 데이터베이스 클래스는 클라이언트들이 프로그램 전체에서 데이터베이스 연결의 같은
// 인스턴스에 접근할 수 있도록 해주는 `getInstance`(인스턴스 가져오기) 메서드를
// 정의합니다.
class Database is
// 싱글턴 인스턴스를 저장하기 위한 필드는 정적으로 선언되어야 합니다.
private static field instance: Database
// 싱글턴의 생성자는 `new` 연산자를 사용한 직접 생성 호출들을 방지하기 위해
// 항상 비공개여야 합니다.
private constructor Database() is
// 데이터베이스 서버에 대한 실제 연결과 같은 일부 초기화 코드.
// 싱글턴 인스턴스로의 접근을 제어하는 정적 메서드.
public static method getInstance() is
if (Database.instance == null) then
acquireThreadLock() and then
// 이 스레드가 잠금 해제를 기다리는 동안 인스턴스가 다른
// 스레드에 의해 초기화되지 않았는지 확인하세요.
if (Database.instance == null) then
Database.instance = new Database()
return Database.instance
// 마지막으로 모든 싱글턴은 해당 로직의 인스턴스에서 실행할 수 있는
// 비즈니스 로직을 정의해야 합니다.
public method query(sql) is
// 예를 들어 앱의 모든 데이터베이스 쿼리들은 이 메서드를 거칩니다.
// 따라서 여기에 스로틀링 또는 캐싱 논리를 배치할 수 있습니다.
// …
class Application is
method main() is
Database foo = Database.getInstance()
foo.query("SELECT ...")
// …
Database bar = Database.getInstance()
bar.query("SELECT ...")
// 변수 `bar`는 변수 `foo`와 같은 객체를 포함할 것입니다.
적용
싱글턴 패턴은 프로그램의 클래스에서 클라이언트가 공유해야 하는 단일 인스턴스만 필요할 때 사용된다.
- 예를 들어 데이터베이스 객체와 같은 경우이다.
- 이 패턴은 클래스의 다른 인스턴스 생성 방법을 비활성화하고, getInstance 메서드를 통해 항상 동일한 인스턴스를 반환한다.
- 이 패턴은 클래스의 다른 인스턴스 생성 방법을 비활성화하고, getInstance 메서드를 통해 항상 동일한 인스턴스를 반환한다.
- 예를 들어 데이터베이스 객체와 같은 경우이다.
전역 변수를 엄격히 제어하고 싶을 때 싱글턴 패턴을 사용할 수 있다.
- 싱글턴 패턴은 전역 변수와 달리 오직 하나의 인스턴스만을 보장한다.
- 이 인스턴스는 프로그램 전체에서 유일무이하게 사용된다.
구현 방법
1. 클래스에 비공개 정적 필드를 추가하여 싱글턴 인스턴스를 저장하세요.
2. 공개된 정적 생성 메서드를 선언하여 싱글턴 인스턴스를 가져오세요.
*3. 정적 메서드 내에서 '지연된 초기화'를 구현하세요. *
이 방식은 첫 호출 시 객체를 생성하고 이후 호출에서는 캐시된 객체를 반환한다.
4. 클래스의 생성자를 비공개로 만들어 직접적인 인스턴스화를 막으세요.
5. 클라이언트 코드에서 직접 생성자 호출을 getInstance 메서드 호출로 대체하세요.
장단점
장점
- 클래스가 하나의 인스턴스만을 갖는다는 점을 확신할 수 있다.
- 전역 접근 지점을 제공하여 어디서든 해당 인스턴스에 접근할 수 있다.
- 싱글턴 객체는 처음 요청될 때만 초기화되므로 자원 절약 효과를 가져올 수 있다.
단점
- 단일 책임 원칙을 위반할 가능성이 있다.
- 한 클래스가 여러 역할을 동시에 수행하려고 할 때 발생할 수 있습니다.
- 싱글턴 패턴은 의도하지 않은 디자인을 가리킬 수 있다.
- 컴포넌트들이 서로 강하게 의존하는 상황을 만들 수 있습니다.
- 다중 스레드 환경에서 싱글턴 객체를 여러 번 생성하지 않도록 특별한 처리가 필요하다.
- 동기화 문제를 해결하지 않으면 안전하지 않을 수 있습니다.
- 싱글턴 객체를 테스트하기 어려울 수 있다.
- 특히, 싱글턴 클래스의 생성자가 비공개이고 정적 메서드를 오버라이드하기 어려운 경우가 있습니다.
- 특히, 싱글턴 클래스의 생성자가 비공개이고 정적 메서드를 오버라이드하기 어려운 경우가 있습니다.
다른 패턴과의 관계
퍼사드 패턴의 클래스는 종종 싱글턴으로 변환될 수 있다.
- 하나의 인스턴스만 필요한 경우에 퍼사드를 싱글턴으로 구현할 수 있습니다.
- 하나의 인스턴스만 필요한 경우에 퍼사드를 싱글턴으로 구현할 수 있습니다.
플라이웨이트 패턴은 여러 인스턴스를 가질 수 있지만 공유 상태를 관리할 때 단일 인스턴스를 사용할 수 있는 경우가 있다.
- 싱글턴은 항상 하나의 인스턴스만을 가지지만, 플라이웨이트는 여러 상태를 공유할 수 있는 여러 인스턴스를 포함할 수 있다.
- 싱글턴은 항상 하나의 인스턴스만을 가지지만, 플라이웨이트는 여러 상태를 공유할 수 있는 여러 인스턴스를 포함할 수 있다.
추상 팩토리, 빌더, 프로토타입 등의 패턴들도 싱글턴으로 구현할 수 있다.
- 필요한 경우 단일 인스턴스의 생성과 관리를 위해 이러한 패턴들을 활용할 수 있습니다.
- 필요한 경우 단일 인스턴스의 생성과 관리를 위해 이러한 패턴들을 활용할 수 있습니다.
'Self-Dev > Design Patterns R&D' 카테고리의 다른 글
[19] 디자인 패턴 목록 - 구조 패턴 - 브릿지 패턴(Bridge Pattern) (0) | 2024.06.28 |
---|---|
[18] 디자인 패턴 목록 - 구조 패턴 - 어댑터(Adapter, Wrapper) (0) | 2024.06.27 |
[16] 디자인 패턴 목록 - 생성 디자인 패턴 - 프로토타입 패턴(Prototype, Clone Pattern) (0) | 2024.06.20 |
[15] 디자인 패턴 목록 - 생성 디자인 패턴 - 빌더 패턴(Builder Pattern) (0) | 2024.06.20 |
[14] 디자인 패턴 목록 - 생성 디자인 패턴 - 추상 팩토리 메서드(Abstract Factory) (0) | 2024.06.19 |