etc./StackOverFlow

싱글톤 패턴의 단점은 무엇입니까? [닫은]

청렴결백한 만능 재주꾼 2021. 12. 6. 22:01
반응형

질문자 :Community Wiki


싱글톤 패턴 은 GoF패턴 책 에서 완전히 지불된 멤버이지만 최근에는 개발자 세계에서 고아가 된 것 같습니다. 나는 여전히 많은 싱글톤을, 특히 팩토리 클래스 에 사용하고, 멀티스레딩 문제(실제로 모든 클래스와 마찬가지로)에 대해 약간 주의해야 하지만, 왜 그렇게 끔찍한지 알 수 없습니다.

스택 오버플로는 특히 모든 사람이 싱글톤이 나쁘다는 데 동의한다고 가정하는 것 같습니다. 왜요?

"사실, 참조 또는 특정 전문 지식 "으로 귀하의 답변을 뒷받침하십시오.



브라이언 버튼에서 의역:

  1. 일반적으로 전역 인스턴스로 사용됩니다. 왜 그렇게 나쁜가요? 인터페이스를 통해 노출하는 대신 코드에서 응용 프로그램의 종속성을 숨기기 때문입니다. 전달을 피하기 위해 무언가를 전역적으로 만드는 것은 코드 냄새 입니다.

  2. 그들은 자신의 생성과 수명 주기를 통제한다는 사실 때문에 단일 책임 원칙을 위반합니다.

  3. 그것들은 본질적으로 코드가 밀접하게 결합되도록 합니다. 이것은 많은 경우에 테스트 중인 그것들을 속이는 것을 어렵게 만듭니다.

  4. 그들은 애플리케이션의 수명 동안 상태를 전달합니다. 테스트를 주문해야 하는 상황으로 끝날 수 있기 때문에 테스트에 대한 또 다른 히트는 단위 테스트에 대해 큰 아니오입니다. 왜요? 각 단위 테스트는 서로 독립적이어야 하기 때문입니다.


Community Wiki

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

리소스 경합.

당신이 어떤 자원을 가지고 있다면

( 1 ) 하나의 인스턴스만 가질 수 있으며,

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

싱글톤 이 필요합니다.

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

싱글톤이 필요한 경우는 드뭅니다. 그들이 나쁜 이유는 그들이 글로벌한 느낌이 들고 GoF Design Patterns 책의 완전 유료 회원이기 때문입니다.

글로벌이 필요하다고 생각할 때 아마도 끔찍한 설계 실수를 하고 있는 것입니다.


Community Wiki

일부 코딩 속물들은 그들을 그저 영광스러운 전 세계인으로 얕잡아 봅니다. 많은 사람들이 goto 문을 싫어하는 것처럼 global 을 사용한다는 아이디어를 싫어하는 사람들도 있습니다. 나는 몇몇 개발자들이 실패를 인정하는 것으로 사용하는 것을 고려했기 때문에 글로벌 을 피하기 위해 엄청난 노력을 기울이는 것을 보았습니다. 이상하지만 사실입니다.

실제로 싱글톤 패턴은 개념 툴킷의 유용한 부분인 프로그래밍 기술일 뿐입니다. 때때로 이것이 이상적인 솔루션임을 알게 될 수 있으므로 사용하십시오. 그러나 디자인 패턴 사용에 대해 자랑할 수 있도록 사용하는 것은 전역 적이기 때문에 사용을 거부하는 것만큼이나 어리석은 일입니다.


Community Wiki

Google의 Misko Hevery는 정확히 이 주제에 대한 몇 가지 흥미로운 기사를 가지고 있습니다.

Singletons are Pathological Liars 에는 싱글톤이 종속성 체인을 파악하고 애플리케이션을 시작하거나 테스트하는 것을 어렵게 만드는 방법을 보여주는 단위 테스트 예제가 있습니다. 이것은 학대의 상당히 극단적인 예이지만 그가 주장하는 요점은 여전히 유효합니다.

싱글톤은 전역 상태에 지나지 않습니다. 전역 상태를 사용하면 개체가 API에 선언되지 않은 것을 은밀하게 보유할 수 있으며 결과적으로 Singleton은 API를 병적인 거짓말쟁이로 만듭니다.

Where have all Singletons Gone 은 종속성 주입을 통해 인스턴스를 필요로 하는 생성자에 쉽게 가져올 수 있게 했으며, 이는 첫 번째 기사에서 언급한 나쁜 전역 Singleton 뒤에 숨겨진 필요성을 완화한다는 점을 보여줍니다.


Community Wiki

사람들이 Singleton 패턴의 실제 적용을 모른다는 사실에서 혼란이 발생했다고 생각합니다. 나는 이것을 충분히 강조할 수 없다. 싱글톤은 전역을 감싸는 패턴 이 아닙니다. 싱글톤 패턴은 런타임 동안 주어진 클래스의 단 하나의 인스턴스만 존재하도록 보장하는 데에만 사용해야 합니다.

사람들은 Singleton을 전역에 사용하기 때문에 Singleton이 나쁘다고 생각합니다. Singleton이 무시되는 것은 이러한 혼란 때문입니다. 싱글톤과 전역을 혼동하지 마십시오. 의도한 용도로 사용하면 싱글톤 패턴에서 극도의 이점을 얻을 수 있습니다.


Community Wiki

싱글톤의 다소 나쁜 점은 싱글톤을 쉽게 확장할 수 없다는 것입니다. 동작을 변경하려면 기본적으로 일종의 데코레이터 패턴 이나 그런 것을 구축해야 합니다. 또한 언젠가 한 가지 일을 여러 가지 방법으로 수행하려는 경우 코드를 배치하는 방법에 따라 변경하는 것이 다소 고통스러울 수 있습니다.

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

그래서 기본적으로:

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

보다는:

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

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

어떤 패턴이든 마찬가지지만... 주어진 상황에서 사용하는 것이 부적절한지 생각해보고... 규칙은 일반적으로 어긋나도록 만들어져 있으며, 아무 생각 없이 패턴 을 함부로 적용해서는 안 됩니다.


Community Wiki

싱글톤 패턴 자체는 문제가 되지 않습니다. 문제는 객체 지향 도구로 소프트웨어를 개발하는 사람들이 객체 지향 개념에 대한 확실한 이해 없이 패턴을 사용하는 경우가 많다는 것입니다. 이 컨텍스트에서 싱글톤이 도입되면 거의 사용되지 않는 도우미 메서드를 포함하는 관리할 수 없는 클래스로 성장하는 경향이 있습니다.

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

가비지 수집 환경에서 싱글톤은 메모리 관리와 관련하여 빠르게 문제가 될 수 있습니다.

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


Community Wiki

싱글톤은 정적 메서드를 사용하여 구현됩니다. 정적 메서드는 조롱하거나 스텁할 수 없기 때문에 단위 테스트를 수행하는 사람들이 피합니다. 이 사이트의 대부분의 사람들은 단위 테스트의 열렬한 지지자입니다. 이를 피하기 위해 일반적으로 가장 많이 받아 들여지는 규칙 은 제어 패턴의 역전을 사용하는 것입니다.


Community Wiki

클러스터링과 관련하여 싱글톤도 좋지 않습니다. 그러면 애플리케이션에 "정확히 하나의 싱글톤"이 더 이상 없기 때문입니다.

다음 상황을 고려하십시오. 개발자로서 데이터베이스에 액세스하는 웹 응용 프로그램을 만들어야 합니다. 동시 데이터베이스 호출이 서로 충돌하지 않도록 하려면 스레드 저장 SingletonDao 를 만듭니다.

 public class SingletonDao { // songleton's static variable and getInstance() method etc. omitted public void writeXYZ(...){ synchronized(...){ // some database writing operations... } } }

따라서 애플리케이션에는 단 하나의 싱글톤만 존재하고 모든 데이터베이스는 이 하나의 SingletonDao 만 통과한다고 확신합니다. 이제 프로덕션 환경은 다음과 같습니다.싱글 싱글톤

지금까지는 모든 것이 정상입니다.

이제 클러스터에서 웹 애플리케이션의 여러 인스턴스를 설정하려는 경우를 고려하십시오. 이제 갑자기 다음과 같은 것이 있습니다.

많은 싱글톤

이상하게 들리지만 이제 애플리케이션에 많은 싱글톤이 있습니다 . 그리고 그것이 바로 싱글톤이 해서는 안 되는 것입니다. 많은 객체를 가집니다. 이 예에서 볼 수 있듯이 데이터베이스에 대한 동기화된 호출을 수행하려는 경우 특히 나쁩니다.

물론 이것은 싱글톤을 잘못 사용한 예입니다. 그러나 이 예제의 메시지는 다음과 같습니다. 특히 클러스터링과 관련하여 애플리케이션에 싱글톤의 인스턴스가 정확히 하나만 있다고 믿을 수는 없습니다.


Community Wiki

  1. 전역 변수로 쉽게 (ab) 사용됩니다.
  2. 싱글톤에 의존하는 클래스는 독립적으로 단위 테스트하기가 상대적으로 더 어렵습니다.

Community Wiki

독점은 악마이고 읽기 전용/가변 상태가 아닌 싱글톤은 '실제' 문제입니다...

Singletons are Pathological Liars is Pathological Liars as jason's answer을 읽은 후 싱글톤이 자주 오용 되는 방법에 대한 가장 좋은 예시를 제공하는 이 작은 이야기를 접했습니다.

글로벌이 나쁜 이유는 다음과 같습니다.

  • NS. 네임스페이스 충돌을 일으킵니다.
  • NS. 부당한 방식으로 국가를 노출시킨다.

싱글톤의 경우

  • NS. 명시적인 OO 호출 방식은 충돌을 방지하므로 a를 가리킵니다. 문제가 아니다
  • NS. 상태가 없는 싱글톤은 (팩토리와 같이) 문제가 되지 않습니다. 상태가 있는 싱글톤은 다시 두 가지 범주에 속할 수 있습니다. 즉, 변경할 수 없거나 한 번 쓰고 많이 읽습니다(구성/속성 파일). 이것들은 나쁘지 않습니다. 일종의 참조 홀더인 변경 가능한 싱글톤이 당신이 말하는 것들입니다.

마지막 진술에서 그는 블로그의 '싱글톤은 거짓말쟁이'라는 개념을 언급하고 있습니다.

이것이 모노폴리에 어떻게 적용됩니까?

독점 게임을 시작하려면 먼저:

  • 모든 사람이 같은 페이지에 있도록 규칙을 먼저 설정합니다.
  • 모든 사람은 게임이 시작될 때 평등하게 시작됩니다.
  • 혼동을 피하기 위해 한 세트의 규칙만 제시됩니다.
  • 게임 내내 규칙을 변경할 수 없습니다.

이제 실제로 독점을 해보지 않은 사람에게는 이러한 표준이 기껏해야 이상적입니다. 독점의 패배는 삼키기 어렵습니다. 독점은 돈에 관한 것입니다. 패배하면 나머지 플레이어가 게임을 끝내는 것을 힘들게 지켜봐야 하고, 일반적으로 손실은 신속하고 압도적입니다. 따라서 규칙은 일반적으로 일부 플레이어의 이익을 위해 다른 플레이어를 희생시키면서 어느 시점에서 왜곡됩니다.

그래서 당신은 친구 Bob, Joe, Ed와 독점 게임을 하고 있습니다. 당신은 빠르게 제국을 건설하고 기하급수적인 속도로 시장 점유율을 소비하고 있습니다. 당신의 상대는 약해지고 당신은 (비유적으로) 피 냄새가 나기 시작합니다. 당신의 친구 밥은 가능한 한 많은 가치가 낮은 부동산을 교착 상태에 빠뜨리는 데 모든 돈을 투자했지만 그가 기대했던 방식으로 높은 투자 수익을 얻지 못하고 있습니다. Bob은 불운의 획으로 당신의 Boardwalk에 도착하고 게임에서 제외됩니다.

이제 게임은 우호적인 주사위 던지기에서 진지한 비즈니스로 바뀝니다. 밥은 실패의 본보기가 되었고 조와 에드는 '저 사람'처럼 되는 것을 원하지 않습니다. 그래서 선두주자가 되어 갑자기 적이 됩니다. Joe와 Ed는 테이블 아래 거래, 뒤에서 돈 주입, 저평가된 하우스 스와핑 및 일반적으로 플레이어 중 하나가 정상에 오를 때까지 플레이어를 약화시키는 모든 것을 연습하기 시작합니다.

그런 다음 그들 중 하나가 승리하는 대신 프로세스가 처음부터 다시 시작됩니다. 갑자기, 한정된 규칙 세트가 움직이는 표적이 되고 게임은 Survivor 이후의 모든 높은 등급의 리얼리티 TV 쇼의 기초를 구성하는 유형의 사회적 상호 작용으로 퇴화합니다. 왜요? 규칙이 바뀌고 규칙이 어떻게/왜/무엇을 나타내야 하는지에 대한 합의가 없고 더 중요한 것은 결정을 내리는 사람이 아무도 없기 때문입니다. 그 시점에서 게임의 모든 플레이어는 자신의 규칙을 만들고 두 플레이어가 너무 지쳐서 속임수를 따라가고 천천히 포기할 때까지 혼란이 계속됩니다.

따라서 게임의 룰북이 싱글톤을 정확하게 표현했다면 독점 룰북은 남용의 예가 될 것입니다.

이것은 프로그래밍에 어떻게 적용됩니까?

변경 가능한 싱글톤이 존재하는 모든 명백한 스레드 안전 및 동기화 문제를 제외하고... 데이터 세트가 하나 있는 경우 여러 다른 소스에서 동시에 읽고 조작할 수 있고 애플리케이션 실행 수명 동안 존재합니다. 한 걸음 물러서서 "여기서 올바른 유형의 데이터 구조를 사용하고 있습니까?"라고 물어보는 것이 좋을 것입니다.

개인적으로 저는 프로그래머가 싱글톤을 응용 프로그램 내에서 일종의 꼬인 스레드 간 데이터베이스 저장소로 사용하여 싱글톤을 남용하는 것을 보았습니다. 코드에서 직접 작업한 결과, 속도가 느리고(스레드로부터 안전하도록 하는 데 필요한 모든 스레드 잠금 때문에) 작업해야 하는 악몽(동기화 버그의 예측할 수 없고/간헐적인 특성 때문에) 및 '생산' 조건에서 테스트하는 것은 거의 불가능합니다. 물론 시스템은 성능 문제 중 일부를 극복하기 위해 폴링/시그널링을 사용하여 개발할 수 있었지만 테스트 문제를 해결하지 못했고 '실제' 데이터베이스가 훨씬 더 강력한 시스템에서 이미 동일한 기능을 수행할 수 있는데 왜 귀찮게 합니까? /확장 가능한 방식.

싱글톤은 싱글톤이 제공하는 것이 필요한 경우 에만 옵션입니다. 개체의 쓰기 전용 읽기 전용 인스턴스입니다. 동일한 규칙이 개체의 속성/구성원에도 계단식으로 적용되어야 합니다.


Community Wiki

싱글톤은 단일 인스턴스에 관한 것이 아닙니다!

다른 답변과 달리 Singleton의 문제점에 대해 이야기하고 싶지는 않지만 올바르게 사용할 때 얼마나 강력하고 멋진지 보여드리고자 합니다!

  • 문제점 : 싱글톤은 멀티스레딩 환경에서 문제가 될 수 있습니다.
    솔루션 : 단일 스레드 부트스트랩 프로세스를 사용하여 싱글톤의 모든 종속성을 초기화합니다.
  • 문제점 : 싱글톤을 조롱하기 어렵다.
    솔루션 : 조롱에 메소드 팩토리 패턴 사용

MyModel 을 상속하는 TestMyModel 클래스에 MyModel을 매핑할 수 있습니다. MyModel 이 주입될 TestMyModel instread가 표시됩니다. - 문제점 : 싱글톤은 폐기되지 않기 때문에 메모리 누수가 발생할 수 있습니다.
해결책 : 글쎄, 그것들을 처분하십시오! 앱에서 콜백을 구현하여 싱글톤을 적절하게 삭제하고 연결된 모든 데이터를 제거하고 마지막으로 팩토리에서 제거해야 합니다.

제목에서 언급했듯이 싱글톤은 단일 인스턴스에 관한 것이 아닙니다.

  • 싱글톤은 가독성을 향상시킵니다 . 클래스를 보고 어떤 싱글톤이 주입되었는지 확인하여 종속성이 무엇인지 파악할 수 있습니다.
  • Singleton은 유지 관리를 향상시킵니다 . 일단 일부 singleton 주입을 삭제한 클래스에서 종속성을 제거하면 종속성을 이동시킨 다른 클래스의 큰 링크를 편집할 필요가 없습니다(이것은 나에게 냄새나는 코드입니다 @Jim Burger )
  • Singleton은 메모리와 성능을 향상시킵니다 . 응용 프로그램에서 어떤 일이 발생하고 전달하는 데 긴 콜백 체인이 소요되면 메모리와 성능을 낭비하게 됩니다. 불필요한 지역 변수 할당을 피함으로써).

Community Wiki

Wikipedia Singleton_pattern 참조

또한 클래스의 단독 인스턴스가 실제로 필요하지 않은 상황에서 불필요한 제한을 도입하여 과도하게 사용된다고 느끼는 일부 사람들에 의해 안티 패턴으로 간주됩니다.[1][2][3][4]

참조(기사의 관련 참조만)

  1. ↑ 알렉스 밀러. 내가 싫어하는 패턴 #1: 싱글톤 , 2007년 7월
  2. ↑ 스콧 덴스모어. 싱글톤이 나쁜 이유 , 2004년 5월
  3. ↑ 스티브 예게. 바보로 간주되는 싱글톤 , 2004년 9월
  4. ^ JB Rainsberger, IBM.싱글톤을 현명하게 사용하십시오 , 2001년 7월

Community Wiki

Singleton이 얼마나 나쁜지에 대한 나의 대답은 항상 "그들은 올바르게 하기가 어렵다"입니다. 언어의 기본 구성 요소 중 많은 부분이 싱글톤(클래스, 함수, 네임스페이스 및 연산자)이며 컴퓨팅의 다른 측면(localhost, 기본 경로, 가상 파일 시스템 등)의 구성 요소와 마찬가지로 우연이 아닙니다. 그것들은 때때로 문제와 좌절을 야기하지만, 또한 많은 일이 훨씬 더 잘 작동하도록 만들 수 있습니다.

내가 보는 두 가지 가장 큰 문제는 전역으로 취급하고 Singleton 클로저를 정의하지 못하는 것입니다.

모든 사람들은 Singleton을 전역으로 이야기합니다. 기본적으로 그렇습니다. 그러나 글로벌의 나쁜 점 중 많은 부분(슬프게도 전부는 아님)은 본질적으로 글로벌한 것이 아니라 그것을 사용하는 방식에서 비롯됩니다. 싱글톤도 마찬가지입니다. 실제로 "단일 인스턴스"가 "전 세계적으로 액세스 가능"을 의미할 필요가 없기 때문에 더 그렇습니다. 그것은 더 자연스러운 부산물이며 우리가 알고 있는 모든 나쁜 것이 그것에서 비롯된다는 것을 감안할 때 글로벌 접근성을 이용하기 위해 그렇게 서두르지 않아야 합니다. 프로그래머가 Singleton을 보면 항상 인스턴스 메서드를 통해 직접 액세스하는 것 같습니다. 대신 다른 개체와 마찬가지로 해당 개체로 이동해야 합니다. 대부분의 코드는 싱글톤(느슨한 결합, 맞죠?)을 다루고 있다는 사실조차 인식하지 않아야 합니다. 전체 코드처럼 약간의 코드만 개체에 액세스하면 많은 피해가 취소됩니다. 인스턴스 기능에 대한 액세스를 제한하여 적용하는 것이 좋습니다.

Singleton 컨텍스트도 정말 중요합니다. Singleton의 정의적인 특징은 "단 하나"가 있다는 것입니다. 그러나 진실은 일종의 컨텍스트/네임스페이스 내에서 "단 하나"라는 것입니다. 일반적으로 스레드, 프로세스, IP 주소 또는 클러스터당 하나이지만 프로세서, 머신, 언어 네임스페이스/클래스 로더/무엇이든, 서브넷, 인터넷 등에 하나씩 있을 수도 있습니다.

덜 일반적인 다른 실수는 싱글톤 라이프스타일을 무시하는 것입니다. 단 하나만 있다고 해서 Singleton이 "항상 그랬고 항상 그럴 것"이라고 해서 전능한 것도 아니며 일반적으로 바람직하지도 않습니다(시작과 끝이 없는 객체는 코드에서 모든 종류의 유용한 가정을 위반하므로 가장 절망적인 상황에서.

이러한 실수를 피한다면 Singleton은 여전히 PITA가 될 수 있지만 최악의 문제가 많이 완화되는 것을 볼 준비가 되어 있습니다. 클래스로더당 한 번으로 명시적으로 정의된(즉, 스레드 안전 정책이 필요함을 의미함) 생성 및 소멸 메서드가 정의되고 호출 시기와 방법, 그리고 "인스턴스" 메서드가 패키지 보호를 사용하므로 일반적으로 다른 비전역 개체를 통해 액세스할 수 있습니다. 여전히 잠재적인 문제의 원인이지만 확실히 문제는 훨씬 적습니다.

슬프게도 Singleton을 수행하는 방법에 대한 좋은 예를 가르치는 것보다. 우리는 나쁜 예를 가르치고, 프로그래머가 잠시 동안 그것을 사용하지 못하게 한 다음 그것들이 나쁜 디자인 패턴이라고 말합니다.


Community Wiki

싱글톤 자체가 나쁜 것이 아니라 GoF 디자인 패턴이 나쁜 것입니다. 유효한 유일한 주장은 GoF 디자인 패턴이 테스트와 관련하여 특히 테스트가 병렬로 실행되는 경우 적합하지 않다는 것입니다.

코드에서 다음 수단을 적용하는 한 클래스의 단일 인스턴스를 사용하는 것은 유효한 구성입니다.

  1. 싱글톤으로 사용할 클래스가 인터페이스를 구현하는지 확인하십시오. 이를 통해 동일한 인터페이스를 사용하여 스텁 또는 목을 구현할 수 있습니다.

  2. Singleton이 스레드로부터 안전한지 확인하십시오. 그것은 주어진 것입니다.

  3. 싱글톤은 본질적으로 단순해야 하며 지나치게 복잡하지 않아야 합니다.

  4. 주어진 객체에 싱글톤을 전달해야 하는 애플리케이션 런타임 동안 해당 객체를 빌드하는 클래스 팩토리를 사용하고 클래스 팩토리가 싱글톤 인스턴스를 필요로 하는 클래스에 전달하도록 합니다.

  5. 테스트하는 동안 그리고 결정적인 동작을 보장하기 위해 싱글톤 클래스를 실제 클래스 자체 또는 동작을 구현하는 스텁/모의로 별도의 인스턴스로 생성하고 이를 필요로 하는 클래스에 있는 그대로 전달합니다. 테스트 중에 싱글톤을 필요로 하는 테스트 대상 개체를 생성하는 클래스 요소를 사용하지 마십시오. 그 개체의 단일 전역 인스턴스를 통과하므로 목적을 달성하지 못합니다.

병렬 테스트 실행 스트림에서 결정적 동작을 보장하는 테스트 가능한 많은 성공으로 우리 솔루션에 싱글톤을 사용했습니다.


Community Wiki

Vince Huston 은 다음과 같은 기준을 가지고 있으며 이는 나에게 합리적으로 보입니다.

싱글톤은 다음 세 가지 기준이 모두 충족되는 경우에만 고려되어야 합니다.

  • 단일 인스턴스의 소유권을 합리적으로 할당할 수 없음
  • 지연 초기화가 바람직합니다.
  • 전역 액세스는 달리 제공되지 않습니다.

단일 인스턴스의 소유권, 초기화가 발생하는 시기와 방법, 전역 액세스가 문제가 아닌 경우 Singleton은 충분히 흥미롭지 않습니다.


Community Wiki

수락 된 답변의 4 가지 요점을 해결하고 싶습니다. 누군가 내가 왜 틀렸는지 설명 할 수 있기를 바랍니다.

  1. 코드에서 종속성을 숨기는 것이 왜 나쁜가요? 이미 수십 개의 숨겨진 종속성(C 런타임 호출, OS API 호출, 전역 함수 호출)이 있으며 싱글톤 종속성은 쉽게 찾을 수 있습니다(instance() 검색).

    "전 세계적으로 전달하지 않기 위해 무언가를 만드는 것은 코드 냄새입니다." 싱글톤 코드 냄새가 나는 것을 피하기 위해 무언가를 전달하지 않는 이유는 무엇입니까?

    싱글톤을 피하기 위해 호출 스택의 10개 함수를 통해 개체를 전달하는 경우 그렇게 좋은가요?

  2. 단일 책임 원칙: 이것은 다소 모호하고 책임의 정의에 따라 다르다고 생각합니다. 관련 질문은 이 특정 "책임"을 클래스에 추가하는 것이 왜 중요합니까?

  3. 객체를 클래스에 전달하면 클래스 내에서 해당 객체를 싱글톤으로 사용하는 것보다 더 밀접하게 결합되는 이유는 무엇입니까?

  4. 상태가 지속되는 기간이 변경되는 이유는 무엇입니까? 싱글톤은 수동으로 생성하거나 파괴할 수 있으므로 컨트롤은 여전히 존재하며 싱글톤이 아닌 객체의 수명과 동일하게 수명을 만들 수 있습니다.

단위 테스트에 관하여:

  • 모든 클래스가 단위 테스트를 수행할 필요는 없습니다.
  • 단위 테스트가 필요한 모든 클래스가 싱글톤 구현을 변경할 필요는 없습니다.
  • 그들은 단위 테스트 및 구현을 변경해야 할 필요가 있다면, 그것은 의존성 주입을 통해 전달 된 싱글을 필요로 싱글 톤을 사용하는 클래스를 쉽게 변경할 수 있습니다.

Community Wiki

싱글톤은 순수주의적 관점에서 나쁘다.

실용적인 관점 에서 싱글톤은 개발 시간 대 복잡성의 절충점 입니다.

당신의 응용 프로그램이 그렇게 많이 변경되지 않을 것이라는 것을 안다면 그것들을 사용해도 괜찮습니다. 요구 사항이 예상치 못한 방식으로 변경되는 경우(대부분의 경우 꽤 괜찮음) 리팩토링해야 할 수도 있습니다.

싱글톤은 때때로 단위 테스트를 복잡하게 만듭니다.


Community Wiki

패턴이 완전히 단일한 모델의 일부 측면에 사용된다고 가정하면 패턴에 본질적으로 잘못된 것은 없습니다.

나는 반발이 과도하게 사용되기 때문에 발생한다고 생각합니다. 이는 차례로 이해하고 구현하기 가장 쉬운 패턴이라는 사실 때문입니다.


Community Wiki

나는 선/악 논쟁에 대해 논평하지 않을 것이지만, 나는 Spring 이 나온 이후로 그것들을 사용하지 않았다. 의존성 주입 을 사용하면 싱글톤, 서비스 로케이터 및 팩토리에 대한 요구 사항이 거의 제거되었습니다. 적어도 내가 하는 작업 유형(Java 기반 웹 응용 프로그램)에 대해서는 이것이 훨씬 더 생산적이고 깨끗한 환경입니다.


Community Wiki

싱글톤은 패턴이며 다른 도구와 마찬가지로 사용하거나 남용할 수 있습니다.

싱글톤의 나쁜 부분은 일반적으로 사용자입니다. 가장 큰 위반은 싱글톤을 가짜 전역 변수로 사용하는 것입니다.


Community Wiki

싱글톤(예: 로거 또는 데이터베이스 연결)을 사용하여 코드를 작성하고 나중에 하나 이상의 로그 또는 둘 이상의 데이터베이스가 필요하다는 것을 발견하면 문제가 발생합니다.

싱글톤을 사용하면 일반 개체로 이동하기가 매우 어렵습니다.

또한 스레드로부터 안전하지 않은 싱글톤을 작성하는 것은 너무 쉽습니다.

싱글톤을 사용하는 대신 함수에서 함수로 필요한 모든 유틸리티 개체를 전달해야 합니다. 다음과 같이 모든 항목을 도우미 개체로 래핑하면 단순화할 수 있습니다.

 void some_class::some_function(parameters, service_provider& srv) { srv.get<error_logger>().log("Hi there!"); this->another_function(some_other_parameters, srv); }

Community Wiki

싱글톤의 문제는 범위가 증가하고 따라서 커플링 이 문제입니다. 단일 인스턴스에 대한 액세스가 필요하고 다른 방법으로 수행할 수 있는 상황이 있음을 부인할 수 없습니다.

이제 IoC(inversion of control ) 컨테이너를 중심으로 디자인하고 컨테이너에서 수명을 제어할 수 있도록 하는 것을 선호합니다. 이것은 단일 인스턴스가 있다는 사실을 인식하지 못하도록 인스턴스에 의존하는 클래스의 이점을 제공합니다. 싱글톤의 수명은 미래에 변경될 수 있습니다. 최근에 만난 그러한 예는 단일 스레드에서 다중 스레드로 쉽게 조정되었습니다.

FWIW, 단위 테스트를 시도할 때 PIA이면 디버그, 버그 수정 또는 향상을 시도할 때 PIA가 됩니다.


Community Wiki

Coding Without Comments의 Chris Reath가 이 주제에 대한 최근 기사.

참고: 주석 없는 코딩은 더 이상 유효하지 않습니다. 그러나 링크되는 기사는 다른 사용자에 의해 복제되었습니다.

http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx


Community Wiki

싱글톤은 나쁘지 않습니다. 전 세계적으로 고유하지 않은 것을 전 세계적으로 고유하게 만들 때만 나쁩니다.

그러나 "응용 프로그램 범위 서비스"(구성 요소를 상호 작용하게 하는 메시징 시스템에 대해 생각해 보세요)가 있습니다. 이것은 "SendMessage(...)" 메서드가 있는 클래스인 "MessageQueue"인 싱글톤을 호출합니다.

그런 다음 모든 곳에서 다음을 수행할 수 있습니다.

MessageQueue.Current.SendMessage(새로운 MailArrivedMessage(...));

물론 다음을 수행하십시오.

MessageQueue.Current.RegisterReceiver(이);

IMessageReceiver를 구현하는 클래스에서.


Community Wiki

너무 많은 사람들이 스레드로부터 안전하지 않은 객체를 싱글톤 패턴에 넣습니다. DataContext가 스레드로부터 안전하지 않고 순전히 작업 단위 개체라는 사실에도 불구하고 싱글톤 패턴으로 수행되는 DataContext( LINQ to SQL )의 예를 보았습니다.


Community Wiki

아직 아무도 말하지 않은 싱글톤에 대해 한 가지 더 있습니다.

대부분의 경우 "단일성"은 인터페이스의 특성이라기보다는 일부 클래스에 대한 구현의 세부사항입니다. Inversion of Control Container는 이 특성을 클래스 사용자에게 숨길 수 있습니다. 클래스를 싱글톤으로 표시하기만 하면 됩니다(예: Java의 @Singleton 나머지는 IoCC가 할 것입니다. IoCC에서 이미 액세스를 관리하므로 싱글톤 인스턴스에 대한 전역 액세스를 제공할 필요가 없습니다. 따라서 IoC 싱글톤에는 아무런 문제가 없습니다.

IoC Singleton과 반대되는 GoF Singleton은 getInstance() 메서드를 통해 인터페이스에서 "singletonity"를 노출해야 하므로 위에서 말한 모든 문제를 겪게 됩니다.


Community Wiki

싱글톤 은 적절 하고 최소한으로 사용한다면 악 이 아닙니다 . 어느 시점에서 싱글톤의 요구를 대체하는 다른 좋은 디자인 패턴이 많이 있습니다(또한 최상의 결과를 제공함). 그러나 일부 프로그래머는 이러한 좋은 패턴을 인식하지 못하고 싱글톤을 악으로 만드는 모든 경우에 싱글톤을 사용합니다.


Community Wiki

첫째, 클래스와 협력자는 종속에 초점을 맞추기보다 먼저 의도한 목적을 수행해야 합니다. 수명 주기 관리(인스턴스가 생성되고 범위를 벗어날 때)는 클래스 책임의 일부가 되어서는 안 됩니다. 이에 대해 허용되는 모범 사례는 종속성 주입을 사용하여 종속성을 관리하기 위해 새 구성 요소를 만들거나 구성하는 것입니다.

종종 소프트웨어가 더 복잡해지면 상태가 다른 Singleton 클래스의 여러 독립 인스턴스를 갖는 것이 합리적입니다. 이러한 경우에는 단순히 싱글톤을 잡기 위해 코드를 커밋하는 것은 잘못된 것입니다. Singleton.getInstance() 사용하는 것은 작고 단순한 시스템에 적합할 수 있지만 동일한 클래스의 다른 인스턴스가 필요할 때 작동/확장되지 않습니다.

어떤 클래스도 싱글톤으로 생각해서는 안 되며, 오히려 그 용도나 종속 항목을 구성하는 데 사용되는 방식에 대한 응용 프로그램이어야 합니다. 빠르고 불쾌한 경우 이것은 중요하지 않습니다. 루크 하드 코딩은 파일 경로가 중요하지 않다고 말하지만 더 큰 응용 프로그램의 경우 이러한 종속성을 제거하고 DI를 사용하여 보다 적절한 방식으로 관리해야 합니다.

테스트에서 싱글톤이 유발하는 문제는 하드 코딩된 단일 사용 사례/환경의 증상입니다. 테스트 스위트와 많은 테스트는 각각 개별적이며 싱글톤 하드 코딩과 호환되지 않는 별도의 항목입니다.


Community Wiki

기본적으로 객체 지향 전역 변수이기 때문에 일반적으로 클래스가 필요하지 않은 방식으로 클래스를 설계할 수 있습니다.


Community Wiki

출처 : http:www.stackoverflow.com/questions/137975/what-are-drawbacks-or-disadvantages-of-singleton-pattern

반응형