문제

단일 패턴 은 완전히 지불 구성원의 GoFko 패턴을 예약, 지만,그것은 최근에 보이는 오히려 고아에 의해 개발자 world.나는 아직도 꽤 많이 사용의 싱글,특히 공장 클래스, 고있는 동안 당신은 약간주의에 대한 문제 멀티 스레딩(과 같은 모든 클래스에서 실제로),내가 실패하는 이유 그들은 너무 끔찍합니다.

Stack Overflow 특히 보인다고 추정하는 모든 사람들이 동의 싱글한다는 것이다.왜?

을 지원하십시오 당신의 답변으로"사실,참조,또는 특정 전문성"

도움이 되었습니까?

해결책

Brian Button에서 논문 :

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

  2. 그들은 위반합니다 단일 책임 원칙: 그들이 자신의 창조와 수명주기를 통제한다는 사실 때문에.

  3. 그들은 본질적으로 코드가 단단히 발생합니다 결합. 이것은 많은 경우 시험에서 그들을 어렵게 만듭니다.

  4. 그들은 응용 프로그램의 수명 동안 상태를 운반합니다. 테스트에 대한 또 다른 타격은 테스트를 주문 해야하는 상황으로 끝날 수 있기 때문에 단위 테스트에 큰 도움이되지 않습니다. 왜요? 각 단위 테스트는 다른 단위 테스트와 독립적이어야하기 때문입니다.

다른 팁

싱글 톤은 하나 (그리고 하나만) 문제를 해결합니다.

자원 경쟁.

자원이 있다면

(1) 단일 인스턴스 만 가질 수 있습니다

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

당신은 필요합니다 하나씩 일어나는 것.

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

싱글 톤이 필요한 것은 드 rare니다. 그들이 나쁜 이유는 그들이 글로벌 그리고 그들은 GOF의 전액 지불 회원입니다 디자인 패턴 책.

전 세계가 필요하다고 생각하면 아마도 끔찍한 디자인 실수를하고있을 것입니다.

일부 코딩 코딩은 단지 영광스러운 글로벌로 내려다 본다. 많은 사람들이 미워하는 것과 같은 방식으로 이동 진술은 글로벌. 나는 여러 개발자가 글로벌 그들은 하나를 실패의 입원으로 고려했기 때문입니다. 이상하지만 사실.

실제로 하나씩 일어나는 것 패턴은 개념 툴킷의 유용한 부분 인 프로그래밍 기술 일뿐입니다. 때때로 당신은 그것이 이상적인 솔루션이므로 사용하십시오. 그러나 그것을 사용하여 사용하는 것을 자랑 할 수 있습니다. 디자인 패턴 그것은 단지 그것을 사용하는 것을 거부하는 것만 큼 바보입니다. 글로벌.

Misko Hevery,구글에서는,몇 가지 흥미로운 기사에 정확히 이 주제...

싱글은 병리학적인 거짓말 는 단위 테스트 보여주는 예는 어떻게 싱글이 어려울 수 있습니다 그 종속 체인하고 시작하는 테스트는 응용 프로그램입니다.그것은 상당히 극단적인 예의 남용하지만,그가 만드는 아직도 유효합니다.

싱글은 아무것도보다 더 많은 글로벌 상태입니다.글로벌 상태를 그렇게 귀하의 개체할 수 있는 비밀리에의 보류를 얻을 것을 선언하지 않에서 자신의 Api,고,그 결과로,Singleton 인 Api 으로 병리학적인 거짓말.

어디 모든 싱글 갔 을 만드는 점에 주입 의존성은 그것을 쉽게 인스턴스를 생성자를 필요로 하는 그들을 완화하고 기본 필요한 뒤에,나쁜 글로벌 싱글 비난에서 첫 번째 문서입니다.

나는 사람들이 싱글 톤 패턴의 실제 적용을 모른다는 사실 때문에 혼란이 있다고 생각합니다. 나는 이것을 충분히 강조 할 수 없다. 싱글 톤은 ~ 아니다 글로벌을 포장하는 패턴. 싱글 톤 패턴은이를 보장하기 위해서만 사용해야합니다 주어진 클래스의 하나의 인스턴스 런타임 중에 존재합니다.

사람들은 싱글 톤이 글로벌에 그것을 사용하고 있기 때문에 악하다고 생각합니다. 이 혼란 때문에 싱글 톤이 내려다 보는 것입니다. 싱글 톤과 글로벌을 혼동하지 마십시오. 의도 된 목적에 사용된다면 싱글 톤 패턴으로부터 극도의 혜택을 얻게됩니다.

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

주목해야 할 사항, 싱글 톤을 사용한다면 직접 액세스하기보다는 필요한 사람에게 전달하십시오 ... 그렇지 않으면 싱글 톤이하는 일을 여러 가지 방법으로 선택하면 각 클래스가 싱글 톤에 직접 액세스하는 경우 종속성을 포함함에 따라 변경하기가 오히려 어렵습니다.

그래서 기본적으로:

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

대신 :

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

나는 이런 종류의 패턴이 호출된다고 생각합니다 의존성 주입 일반적으로 좋은 것으로 간주됩니다.

다른 패턴처럼 ... 그것에 대해 생각하고 주어진 상황에서의 사용이 부적절한 지 여부를 고려하십시오 ... 규칙은 일반적으로 파손되도록 만들어지고, 그리고 패턴 생각없이 Willy Nilly를 적용해서는 안됩니다.

싱글 톤 패턴은 그 자체로 문제가되지 않습니다. 문제는 패턴이 종종 OO 개념을 견고하지 않고 객체 지향 도구로 소프트웨어를 개발하는 사람들이 종종 사용한다는 것입니다. 이 맥락에서 싱글 톤이 소개되면 모든 작은 용도로 도우미 방법을 포함하는 관리 할 수없는 클래스로 성장하는 경향이 있습니다.

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

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

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

정적 방법을 사용하여 싱글 톤이 구현됩니다. 정적 방법은 단위 테스트를 수행하는 사람들이 조롱하거나 스텁을 할 수 없기 때문에 피합니다. 이 사이트의 대부분의 사람들은 단위 테스트의 큰 지지자입니다. 그들을 피하기 위해 일반적으로 가장 많이 받아 들여지는 협약은 제어의 역전 무늬.

싱글 톤도 나쁘다 클러스터링. 그렇다면 더 이상 응용 프로그램에 "정확히 하나의 싱글 톤"이 없기 때문입니다.

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

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

따라서 응용 프로그램에 단 하나의 싱글 톤 만 존재하고 모든 데이터베이스 가이 하나를 통과합니다. SingletonDao. 이제 생산 환경이 다음과 같습니다.Single Singleton

지금까지 모든 것이 괜찮습니다.

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

Many singletons

이상하게 들리지만 이제 응용 프로그램에 많은 싱글 톤이 있습니다. 그것이 바로 싱글 톤이되어서는 안되는 것입니다. 이 예에서 볼 수 있듯이 데이터베이스에 동기화 된 호출을 원한다면 특히 나쁩니다.

물론 이것은 싱글 톤의 나쁜 사용의 예입니다. 그러나이 예제의 메시지는 다음과 같습니다. 특히 클러스터링과 관련하여 응용 프로그램에 싱글 톤의 인스턴스가 정확히 하나 있다는 것을 의존 할 수 없습니다.

  1. 전역 변수로 쉽게 (AB) 사용됩니다.
  2. 싱글 톤에 의존하는 클래스는 단위로 단위 테스트하기가 비교적 어렵습니다.

독점은 독서적이지 않거나 돌연변이가없는 상태를 가진 악마와 싱글 톤입니다.

읽고 나서 싱글 톤은 병리학 적 거짓말 쟁이입니다 제안 된 바와 같이 제이슨의 대답 나는 가장 잘 제시된 예를 제공하는이 작은 멍청이를 발견했습니다. 어떻게 싱글 톤은 종종 오용됩니다.

글로벌은 다음과 같이 나쁘다.

  • ㅏ. 네임 스페이스 충돌을 일으 킵니다
  • 비. 그것은 무의미한 방식으로 국가를 노출시킵니다

싱글 톤에 관해서는

  • ㅏ. 명백한 OO를 부르는 방법은 갈등을 방지하므로 a. 문제가 아닙니다
  • 비. 주가없는 싱글 톤은 (공장과 같은) 문제가되지 않습니다. State를 가진 싱글 톤은 다시 두 가지 범주로 떨어질 수 있습니다. 두 가지 범주는 불변이거나 한 번 쓰고 많은 것을 읽고 (구성/속성 파일) 읽습니다. 이것들은 나쁘지 않습니다. 일종의 참조 홀더 인 Mutable Singletons는 당신이 말하는 것입니다.

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

이것이 독점에 어떻게 적용됩니까?

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

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

지금은 그렇지 않은 사람을 위해 진짜 독점을 연주 한이 표준은 기껏해야 이상적입니다. 독점의 패배는 삼키기가 어렵습니다. 독점은 돈에 관한 것이기 때문에, 당신이 잃어버린 경우 나머지 플레이어가 게임을 끝내는 것을 지켜봐야하며, 손실은 일반적으로 신속하고 분쇄됩니다. 따라서, 규칙은 일반적으로 다른 시점에서 비틀어지면서 다른 플레이어들의 자기 이익을 위해 다른 사람들을 희생시키면서 이익을 제공합니다.

그래서 당신은 친구 Bob, Joe 및 Ed와 독점을하고 있습니다. 당신은 신속하게 제국을 구축하고 기하 급수적으로 시장 점유율을 소비합니다. 상대방이 약해지고 피 냄새가 나기 시작합니다 (비 유적으로). 당신의 친구 밥은 자신의 모든 돈을 가능한 한 많은 저가의 속성으로 gridlocking에 넣었지만 그의 예상대로 높은 투자 수익을받지는 않습니다. 불운의 뇌졸중으로 밥은 보드 워크에 착륙하여 게임에서 절제됩니다.

이제 게임은 친절한 주사위를 롤링하는 것에서부터 진지한 사업으로갑니다. 밥은 실패의 예를 만들어 냈으며 Joe와 Ed는 '그 사람'처럼 끝나기를 원하지 않습니다. 그래서, 당신을 대표하는 선수가되는 것은 갑자기 적이되었습니다. Joe와 Ed는 테이블 중 거래, 뒤에서 자금 주사, 과소 평가 된 집 웨이핑을 시작하며 일반적으로 그들 중 하나가 정상에 올라갈 때까지 플레이어로 당신을 약화시키는 모든 것을 연습하기 시작합니다.

그런 다음 그들 중 하나가 승리하는 대신 프로세스가 시작됩니다. 갑자기, 유한 한 규칙 세트가 움직이는 목표가되고 게임은 생존자 이후로 모든 고급 리얼리티 TV 쇼의 기초를 구성하는 사회적 상호 작용 유형으로 변성됩니다. 왜, 규칙이 바뀌고 있고 그들이 어떻게/왜 대표 해야하는지에 대한 합의가 없기 때문에, 더 중요한 것은 결정을 내리는 사람이 없다. 그 시점에서 게임의 모든 플레이어는 자신의 규칙을 만들고 있으며 두 명의 선수가 너무 피곤하여 천천히 포기할 때까지 혼돈이 계속됩니다.

따라서 게임에 대한 룰북이 싱글 톤을 정확하게 대표한다면 독점 룰북은 남용의 예가됩니다.

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

돌연변이 가능한 싱글 톤이 존재하는 모든 스레드 안전성 및 동기화 문제와는 별도로 ... 하나의 데이터 세트가 있다면, 여러 다른 소스에 의해 동시에 읽히거나 조작 될 수 있으며 응용 프로그램 실행의 수명 동안 존재합니다. 물러서서 "여기에 올바른 유형의 데이터 구조를 사용하고 있습니까?"라고 물어보기 좋은시기 일 것입니다.

개인적으로, 나는 프로그래머가 응용 프로그램 내에서 어떤 종류의 꼬인 크로스 스레드 데이터베이스 스토어로 사용하여 싱글 톤을 남용하는 것을 보았습니다. 코드를 직접 작업 한 결과, (스레드 안전을 만드는 데 필요한 모든 스레드 잠금 장치로 인해) (예측할 수없는/간헐적 인 특성 때문에), (스레드 안전을 만들기 위해 필요한 모든 스레드 잠금 장치 때문에) 느리게 진행되었음을 증명할 수 있습니다. '생산'조건에서 테스트하기가 거의 불가능합니다. 물론, 일부 성능 문제를 극복하기 위해 폴링/신호를 사용하여 시스템을 개발할 수 있었지만 테스트 문제를 해결하지 못하고 '실제'데이터베이스가 훨씬 더 강력하게 동일한 기능을 이미 달성 할 수있을 때 귀찮게하는 이유 /확장 가능한 방식.

싱글 톤은 싱글 톤이 제공하는 것이 필요한 경우 옵션입니다. 객체의 쓰기 읽기 전용 인스턴스. 동일한 규칙은 물체의 속성/멤버에 대해서도 계단식을해야합니다.

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

다른 답변과 달리 나는 싱글 톤에 무엇이 잘못되었는지에 대해 이야기하고 싶지 않지만 올바르게 사용했을 때 얼마나 강력하고 멋진지를 보여줍니다!

  • 문제: 싱글 톤은 멀티 스레딩 환경에서 도전이 될 수 있습니다
    해결책: 단일 스레드 부트 스트랩 프로세스를 사용하여 싱글 톤의 모든 종속성을 초기화하십시오.
  • 문제: 싱글 톤을 조롱하기가 어렵습니다.
    해결책: 방법을 사용하십시오 공장 조롱을위한 패턴
    MyModel myModel = Factory.inject(MyModel.class); 당신은 매핑 할 수 있습니다 MyModel 에게 TestMyModel 언제 어디서나 물려받는 클래스 MyModel 당신이 얻을 것입니다 TestMyModel 령법.
  • 문제: 싱글 톤은 아무런 처분을하지 않았을 때 기억력을 유발할 수 있습니다.
    해결책: 글쎄, 그들을 처분하십시오! 앱에서 콜백을 구현하여 싱글 톤을 올바르게 폐기하면 링크 된 데이터를 제거하고 마지막으로 공장에서 제거해야합니다.

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

  • 싱글 톤은 가독성을 향상시킵니다: 수업을보고 어떤 싱글 톤이 주입되어 어떤 종속성이 무엇인지 알아낼 수 있습니다.
  • 싱글 톤은 유지 보수를 향상시킵니다: 수업에서 종속성을 제거한 후 방금 싱글 톤 주입을 삭제 한 경우, 방금 의존성을 옮긴 다른 클래스의 큰 링크를 편집 할 필요가 없습니다 (이것은 나를위한 냄새 나는 코드입니다. @jim 버거)
  • 싱글 톤은 메모리와 성능을 향상시킵니다: 애플리케이션에서 어떤 일이 발생하고 전달하는 데 긴 콜백 체인이 필요하면, 싱글 톤을 사용하여 중간 맨을 자르고 성능과 메모리 사용량을 향상 시켜서 기억과 성능을 낭비하고 있습니다 (불필요한 로컬 변수를 피함으로써 성능 및 메모리 사용을 향상시킵니다. 할당).

나는 방법에 대한 답변 싱글은 나쁜 것은,항상"그들은 바로".많은 기본 구성 요소의 언어는 싱글(classes,functions,네임스페이스는 심지어 사업자),으로 구성 요소의 다른 측면에서 컴퓨팅(localhost,기본 경로,가상 파일시스템,etc.), 그것은 우연이 아니다.는 동안 그들은 문제가 발생하고 좌절 시간에서,그들은 또한 많은 것들을 만들 작품프............

두 개의 가장 큰 나사 업을 나는 볼 수 있다:처럼 처리하는 글로벌 및 실패의 단일 폐쇄입니다.

모두에 대해 이야기하는 단일의 전역이기 때문에,그들은 기본적으로있다.그러나,많은(는 슬프게도,모든지 않)의 불량에 global 오지에서 본질적으로는 세계지만,당신이 그것을 사용하는 방법이다.한 Singleton.실제로 그는"하나의 인스턴스는"정말 필요가 없이 의미하는"전 세계적으로 액세스 할 수 있도록".그것은 더 많은 자연적인 부산물,그리고 주어진 모든 나쁜 것을 우리는 알아에서 온 그것은 우리 안에서 서둘러를 악용하는 글로벌 접근성이다.면 프로그래머시하는 단일 그들은 항상 그것을 직접 액세스를 통해 해당 인스턴스 방법입니다.대신에,당신은 그것을 탐색하는 것처럼 다른 객체입니다.대부분의 코드는지도 알고 있어야 그것을 다루는 단일(느슨한 연결을,오른쪽?).는 경우에 단지 작은 비트의 코드에 액세스하는 개체는 다음과 같 그것은 세계의 많은 해에는 취소 할 수 있습니다.추천 적용에 대한 액세스를 제한하여 인스턴스 기능이다.

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

다른,더 적은 일반적인 실수를 무시하는 것입니다 단일 라이프 스타일입니다.그냥 하나만 있기 때문에 없는 것을 의미하는 단일은 일부 전능"항상했다고 항상 될 것입니다"며,그것은 일반적으로 바람직한(체 없이 시작과 끝을 위반하는 모든 종류의 유용한 가정에서 코드 및 사용될 수 있어야에서만 가장 절망적인 상황.

는 경우에 당신은 그들을 피하기 위해 실수,Singleton 할 수 있는 피타 비,그것은 준비가 많이 볼 수있는 최악의 문제가 크게 줄어듭니다.상상 Java 단일은 명시적으로 정의된 한 번 클래스 로더(는 것을 의미는 그것을 필요로 스레드에 안전 정책의)에 정의 생성과 제거 방법 및 수명주기를 지시하는 경우 그들이 어떻게 호출되고,그의 인스턴스""방법은 패키지 보호 그래서 그것은 일반적으로 액세스를 통해 다른 비 글로벌다.아직은 잠재적 문제의 근원이지만,확실히 훨씬 적은 문제입니다.

슬프게도,가르치기보다는 좋은 예는 어떻게 싱글.우리가 가르치는 나쁜 사례,하자 프로그래머들이 그들을 사용하는 동안,그 다음 그들에게 그들은 나쁜 디자인 패턴입니다.

Wikipedia Singleton_pattern을 참조하십시오

또한 일부 사람들은 과도하게 사용된다고 생각하는 일부 사람들에 의한 반란으로 간주되며, 클래스의 유일한 사례가 실제로 필요하지 않은 상황에서 불필요한 한계를 도입합니다. [1] [2] [3] [4

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

  1. ^ 알렉스 밀러. 내가 싫어하는 패턴 #1 : 싱글 톤, 2007 년 7 월
  2. ^ Scott Densmore. 싱글 톤이 악한 이유, 2004 년 5 월
  3. ^ Steve Yegge. 싱글 톤은 바보라고 생각했습니다, 2004 년 9 월
  4. ^ JB Rainsberger, IBM. 싱글 톤을 현명하게 사용하십시오, 2001 년 7 월

싱글 톤 자체가 나쁘지는 않지만 GOF 디자인 패턴은입니다. 유일하게 유효한 유일한 주장은 GOF 설계 패턴이 테스트와 관련하여 자체적으로 빌려주지 않는다는 것입니다. 특히 테스트가 병렬로 실행되는 경우.

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

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

  2. 싱글 톤이 스레드 안전인지 확인하십시오. 그것은 주어진 것입니다.

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

  4. 싱글 톤을 주어진 객체로 전달 해야하는 응용 프로그램 런타임 동안 해당 객체를 구축하고 클래스 공장이 싱글 톤 인스턴스를 필요한 클래스에 전달하도록하는 클래스 공장을 사용하십시오.

  5. 테스트하는 동안 결정 론적 행동을 보장하기 위해 싱글 톤 클래스를 실제 클래스 자체 또는 행동을 구현하고 필요한 클래스와대로 전달하는 스터브/모의로 별도의 인스턴스로 싱글 톤 클래스를 만듭니다. 테스트 중에 해당 객체를 생성하는 클래스 요소를 사용하여 테스트 중 싱글 톤이 필요한 단일 글로벌 인스턴스를 통과하므로 목적을 물리칩니다.

우리는 솔루션에서 싱글 톤을 사용하여 병렬 테스트 실행 스트림에서 결정 론적 행동을 보장하는 많은 성공을 거두었습니다.

빈스 허 스턴 이러한 기준이 있으며,이 기준은 나에게 합리적으로 보입니다.

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

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

단일 인스턴스의 소유권이 초기화가 언제 및 어떻게 발생하고 글로벌 액세스가 문제가되지 않는 경우, 싱글 톤은 충분히 흥미롭지 않습니다.

받아 들여진 답변에서 4 점을 다루고 싶습니다. 누군가 내가 왜 내가 틀렸는지 설명 할 수 있기를 바랍니다.

  1. 코드의 종속성을 숨기는 이유는 무엇입니까? 이미 수십 개의 숨겨진 종속성 (C 런타임 호출, OS API 호출, 글로벌 기능 호출)이 있으며 싱글 톤 종속성은 쉽게 찾을 수 있습니다 (indess ()).

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

    싱글 톤을 피하기 위해 콜 스택에서 10 개의 기능을 통해 객체를 전달하는 경우 그렇게 큰가요?

  2. 단일 책임 원칙 : 나는 이것이 약간 모호하며 책임에 대한 정의에 달려 있다고 생각합니다. 관련 질문은 왜 이것을 추가합니까? 특정한 클래스 문제에 대한 "책임"?

  3. 수업에 물체를 전달하는 이유는 왜 수업 내에서 해당 객체를 싱글 톤으로 사용하는 것보다 더 단단히 결합됩니까?

  4. 주가 얼마나 오래 지속되는지 왜 변합니까? 싱글 톤은 수동으로 생성되거나 파괴 될 수 있으므로 컨트롤이 여전히 존재하므로 수명이 아닌 객체의 수명과 동일하게 수명을 만들 수 있습니다.

단위 테스트와 관련하여 :

  • 모든 클래스가 단위 테스트 일 필요는 없습니다
  • 단위 테스트 해야하는 모든 클래스는 싱글 톤의 구현을 변경 해야하는 것은 아닙니다.
  • 만약 그들이 하다 단위 테스트가 필요하고 구현을 변경해야합니다. 단일 톤 사용에서 의존성 주입을 통해 싱글 톤을 전달하도록 클래스를 쉽게 변경할 수 있습니다.

나는 선/사악한 주장에 대해 언급하지 않겠지 만 그 이후로 그것들을 사용하지 않았습니다. 함께왔다. 사용 의존성 주입 Singleton, Servicelocators 및 공장에 대한 요구 사항을 거의 제거했습니다. 나는 이것이 내가하는 작업 유형 (Java 기반 웹 응용 프로그램)에 대해 훨씬 생산적이고 깨끗한 환경이라고 생각합니다.

진정으로 단일 인 모델의 일부 측면에 사용되고 있다고 가정하면 패턴에 본질적으로 잘못된 것은 없습니다.

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

싱글 톤은 순수한 관점에서 나쁘다.

유명한 관점에서 싱글 톤은 시간과 복잡성을 개발하는 트레이드 오프입니다.

당신이 당신의 응용 프로그램이 그렇게 많이 바뀌지 않을 것이라는 것을 알고 있다면 그들은 함께 가기에 괜찮습니다. 요구 사항이 예상치 못한 방식으로 변경되면 (대부분의 경우 괜찮 으면) 상황을 리팩터링해야 할 수도 있습니다.

싱글 톤도 때때로 복잡합니다 단위 테스트.

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

싱글 톤의 나쁜 부분은 일반적으로 사용자입니다 (또는 싱글 톤을 부적절하게 사용하여 설계되지 않은 일에 대해 말해야합니다). 가장 큰 범죄자는 싱글 톤을 가짜 글로벌 변수로 사용하는 것입니다.

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

싱글 톤은 그들에서 일반 물체로 이동하기가 매우 어렵습니다.

또한, 비 스레드-안전 싱글 톤을 쓰는 것은 너무 쉽습니다.

싱글 톤을 사용하지 않고 필요한 모든 유틸리티 객체를 기능에서 기능으로 전달해야합니다. 다음과 같이 모든 것을 도우미 물체로 감싸면 단순화 할 수 있습니다.

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

싱글 톤의 문제는 범위가 증가하는 문제이므로 커플 링. 단일 인스턴스에 액세스 할 필요가있는 상황이 있다는 것을 부인할 수 없으며 다른 방법으로 달성 할 수 있습니다.

나는 이제 주위를 디자인하는 것을 선호합니다 제어의 역전 (IOC) 컨테이너 및 생명 시간을 컨테이너로 제어 할 수 있도록합니다. 이것은 단일 인스턴스가 있다는 사실을 알지 못하는 인스턴스에 의존하는 클래스의 이점을 제공합니다. 싱글 톤의 수명은 미래에 변경 될 수 있습니다. 내가 최근에 만난 그러한 예는 단일 나사산에서 멀티 스레드로 쉽게 조정하는 것이 었습니다.

fwiw, 단위 테스트를 시도 할 때 PIA 인 경우 디버그, 버그 수정 또는 향상을 시도 할 때 PIA로갑니다.

Chris Reath 의이 주제에 관한 최근 기사 의견없이 코딩.

참고 : 주석없이 코딩하는 것은 더 이상 유효하지 않습니다. 그러나 링크 된 기사는 다른 사용자가 복제했습니다.

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

아직 아무도 말하지 않은 싱글 톤에 대한 또 하나의 것이 있습니다.

대부분의 경우 "Singletonity"는 인터페이스의 특성보다는 일부 클래스에 대한 구현의 세부 사항입니다. 제어 컨테이너의 역전은 클래스 사용자 로부터이 특성을 숨길 수 있습니다. 수업을 싱글 톤으로 표시하면됩니다 ( @Singleton 예를 들어 자바로 주석) 나는 나머지를 할 것이다. 액세스는 이미 IOCC가 관리하기 때문에 싱글 톤 인스턴스에 대한 글로벌 액세스를 제공 할 필요가 없습니다. 따라서 IOC 싱글 톤에는 아무런 문제가 없습니다.

IOC 싱글 톤과 반대되는 GOF 싱글 톤은 getInstance () 방법을 통해 인터페이스에 "싱글 톤"을 노출시켜 위에서 언급 한 모든 것을 고통스럽게해야합니다.

싱글 톤은 나쁘지 않습니다. 전 세계적으로 독특하지 않은 전 세계적으로 독특한 것을 만들 때만 나쁘다.

그러나 "애플리케이션 스코프 서비스"(구성 요소 상호 작용을하는 메시징 시스템에 대한 생각) - "SendMessage (...)"메소드가있는 "MessageQueue" - 클래스를 요구합니다.

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

MessageQueue.Current.SendMessage (New MailArriedMessage (...));

그리고 물론 :

MessageQueue.current.registerReceiver (this);

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

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

그것들은 기본적으로 객체 지향 글로벌 변수이기 때문에 일반적으로 클래스를 필요로하지 않도록 수업을 설계 할 수 있습니다.

패턴 나온 경우 여러 사람(또는 팀)에 도착과 유사하거나 동일한 솔루션이 있습니다.많은 사람들이 아직도 사용하여 싱글에서는 원래 양식을 사용하거나 템플릿 공장(좋은 토론에서 Alexandrescu 의 현대적인 C++디자인).동시성과 관리에 어려움이의 수명은 개체는 주요 장애물,전 쉽게 관리하며 당신은 제안한다.

다음과 같은 모든 선택,단일의 공평한 분배 ups and downs.나는 생각한 그들은 사용할 수 있습니다에서는 절도,특히 남아 있는 개체 응용 프로그램을 수명이 있습니다.사실은 그들이 닮(및 아마)globals 가 아마 설정하자.

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

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

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

싱글 톤이 테스트에서 원인이되는 문제는 하드 코딩 된 단일 사용법 사례/환경의 증상입니다. 테스트 스위트와 많은 테스트는 각각의 개인이며 싱글 톤 하드 코딩과 호환되지 않는 분리 된 것을 분리합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top