[design-patterns] 싱글 톤이 왜 그렇게 나쁜가요? [닫은]

싱글 톤 패턴 의 완전 최대 유료 회원입니다 GoF의패턴 책 , 그러나 그것은 최근에 오히려 개발자 세계 고아 보인다. 나는 여전히 많은 팩토리 클래스를 사용합니다. 특히 팩토리 클래스 에는 멀티 스레딩 문제에 대해 조심해야하지만 (실제로 다른 클래스와 마찬가지로) 왜 그렇게 끔찍한 지 알 수 없습니다.

스택 오버플로는 특히 모든 사람들이 싱글 톤이 악하다고 동의한다고 가정합니다. 왜?

사실, 참조 또는 특정 전문 지식 “으로 답변을 지원하십시오.



답변

브라이언 버튼에서 번역 :

  1. 그것들은 일반적으로 글로벌 인스턴스로 사용되는데 왜 그렇게 나쁜가? 인터페이스를 통해 노출하는 대신 코드에서 애플리케이션의 종속성을 숨기므로 그것을 피하기 위해 전역으로 무언가를 만드는 것은 코드 냄새 입니다.

  2. 그들은 하나의 책임 원칙을 위반합니다 . 즉, 자신의 생성과 수명주기를 제어한다는 사실 때문입니다.

  3. 이것들은 본질적으로 코드가 밀접하게 결합되도록 합니다. 이로 인해 많은 경우 테스트중인 가짜가 다소 어려워집니다.

  4. 응용 프로그램 수명 동안 상태를 유지합니다. 테스트를 주문 해야하는 상황으로 이어질 수 있으므로 테스트에 대한 또 다른 타격은 단위 테스트에 큰 도움이되지 않습니다. 왜? 각 단위 테스트는 서로 독립적이어야합니다.


답변

싱글 톤은 하나의 문제 만 해결합니다.

리소스 경합.

자원이 있다면

( 1 )은 단일 인스턴스 만 가질 수 있으며

( 2 ) 단일 인스턴스를 관리해야합니다.

싱글 톤 이 필요합니다 .

예가 많지 않습니다. 로그 파일이 큰 파일입니다. 단일 로그 파일 만 포기하고 싶지는 않습니다. 플러시, 동기화 및 올바르게 닫으려고합니다. 이것은 관리해야하는 단일 공유 리소스의 예입니다.

싱글 톤이 필요한 경우는 거의 없습니다. 그들이 나쁜 이유는 그들이 글로벌 한 느낌과 GoF Design Patterns 책 의 전액을 지불했기 때문 입니다.

글로벌이 필요하다고 생각하면 아마도 끔찍한 디자인 실수를 저지른 것일 수 있습니다.


답변

일부 코딩 스 너브 (snob)는 그것들을 단지 영광스러운 세계로 봅니다. 많은 사람들이 goto 선언을 싫어하는 것과 같은 방식 으로 글로벌 사용을 싫어하는 사람들이 있습니다 . 나는 여러 개발자 가 실패를 받아들이는 것을 고려했기 때문에 전 세계 를 피하기 위해 엄청난 길이로 진행하는 것을 보았습니다 . 이상하지만 사실입니다.

실제로 Singleton 패턴은 개념 툴킷의 유용한 부분 인 프로그래밍 기술 일뿐입니다. 때때로 당신은 그것이 이상적인 솔루션임을 알 수 있으므로 그것을 사용하십시오. 그러나 디자인 패턴을 사용하는 것에 대해 자랑 할 수 있도록 그것을 사용하는 것은 단지 글로벌 이기 때문에 디자인 패턴을 사용하는 것을 거부하는 것처럼 바보 입니다.


답변

구글의 Misko Hevery는이 주제에 관한 흥미로운 기사를 가지고 있습니다.

싱글턴은 병리학적인 거짓말 쟁이 거짓말 쟁이싱글 톤이 의존성 체인을 파악하고 응용 프로그램을 시작하거나 테스트하는 것을 어렵게 만드는 방법을 보여주는 단위 테스트 예제를 가지고 있습니다. 그것은 학대에 대한 극단적 인 예이지만, 그가 주장하는 요점은 여전히 ​​유효합니다.

싱글 톤은 글로벌 상태에 지나지 않습니다. 전역 상태를 사용하면 객체가 API에 선언되지 않은 것을 비밀리에 보유 할 수 있으므로 싱글 톤은 API를 병리학적인 거짓말 쟁이로 만듭니다.

모든 Singletons Gone 이 의존성 주입을 통해 인스턴스를 필요로하는 생성자에게 인스턴스를 쉽게 가져올 수있게되었으므로 첫 번째 기사에서 언급 한 나쁜 글로벌 Singleton의 근본적인 요구를 완화 할 수있었습니다.


답변

혼동은 사람들이 싱글 톤 패턴의 실제 적용을 알지 못하기 때문에 발생한다고 생각합니다. 나는 이것을 충분히 강조 할 수 없다. 싱글 톤은 글로벌을 감싸는 패턴 이 아닙니다 . 단일 클래스 패턴은 런타임 동안 주어진 클래스의 인스턴스가 하나만 존재 하도록 보장하기 위해 사용해야합니다 .

사람들은 싱글 톤을 글로벌에 사용하기 때문에 싱글 톤이 악하다고 생각합니다. 이 혼동으로 인해 싱글 톤을 내려다 보았습니다. 싱글 톤과 글로벌을 혼동하지 마십시오. 원래 목적에 맞게 사용하면 싱글 톤 패턴의 이점을 최대한 활용할 수 있습니다.


답변

싱글 톤에 대한 한 가지 나쁜 점은 싱글 톤을 매우 쉽게 확장 할 수 없다는 것입니다. 기본적으로 어떤 종류의 데코레이터 패턴 이나 그 동작을 변경하려면 그러한 것을 만들어야합니다. 또한 언젠가 여러 가지 방법으로 하나의 작업을 수행하려는 경우 코드 레이아웃에 따라 변경하기가 다소 어려울 수 있습니다.

한 가지 주목할 점은 싱글 톤을 사용하는 경우 직접 액세스하지 않고 필요한 사람에게 전달하려고 시도하는 것입니다. 그렇지 않으면 싱글 톤이 수행하는 작업을 여러 방법으로 수행하기로 선택한 경우에는 다음과 같이됩니다. 각 클래스가 싱글 톤에 직접 액세스하는 경우 종속성을 포함하므로 변경하기가 다소 어렵습니다.

그래서 기본적으로:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

오히려

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

이런 종류의 패턴을 의존성 주입 이라고합니다. 하며 일반적으로 좋은 것으로 간주됩니다.

그러나 어떤 패턴과 마찬가지로 … 그것에 대해 생각하고 주어진 상황에서의 사용이 부적절한 지 아닌지 고려하십시오 … 규칙은 일반적으로 깨지도록 만들어지며, 생각없이 패턴 을 적용 할 수 없습니다.


답변

싱글 톤 패턴 자체는 문제가되지 않습니다. 문제는 패턴이 OO 개념을 제대로 파악하지 않고도 객체 지향 도구로 소프트웨어를 개발하는 사람들이 종종 사용한다는 것입니다. 이 문맥에서 싱글 톤이 소개 될 때, 그들은 거의 사용하지 않는 헬퍼 메소드를 포함하는 관리 할 수없는 클래스로 성장하는 경향이 있습니다.

싱글 톤은 테스트 관점에서도 문제가됩니다. 그들은 고립 된 단위 테스트를 작성하기 어렵게 만드는 경향이 있습니다. 제어 역전 (IoC) 및 의존성 주입 은 단위 테스트에 적합한 객체 지향 방식으로이 문제를 극복하기위한 패턴입니다.

A의 쓰레기 수집 환경 싱글 빠르게 메모리 관리와 관련하여 문제가 될 수 있습니다.

싱글 톤이 병목 현상이 될 수있는 멀티 스레드 시나리오와 동기화 문제도 있습니다.