정적 메서드 대신 싱글 톤을 사용하는 이유는 무엇입니까?


93

헬퍼 / 유틸리티 클래스에 대한 다음과 같은 간단한 질문에 대한 좋은 답변을 찾지 못했습니다.

정적 메서드를 사용하는 대신 싱글 톤 (상태 비 저장)을 만드는 이유는 무엇입니까?

개체에 상태가없는 경우 개체 인스턴스가 필요한 이유는 무엇입니까?



우리는 자바, 링크에 대한 2 개의 다른 대답이 다를 수 있으므로 langages하지만, 덕분에 대해 이야기하기 때문에 생각하지 마십시오 용어 "monostate"들어 본 적이
세바스티앙 Lorber에게

답변:


79

종종 싱글 톤은 애플리케이션에 일종의 전역 상태 를 도입하는 데 사용됩니다 . (정직하게 말하면 실제로 필요한 것보다 더 자주 있지만, 그것은 다른 시간에 대한 주제입니다.)

그러나 상태 비 저장 싱글 톤도 유용 할 수 있는 몇 가지 코너 케이스 가 있습니다.

  • 가까운 장래에 주와 함께 확장 할 것으로 예상합니다.
  • 특정 기술적 인 이유로 개체 인스턴스 가 필요합니다 . 예 : C # 또는 Java 문에 대한 동기화 개체 .
    locksynchronized
  • 상속이 필요합니다. 즉, 동일한 인터페이스를 사용하지만 다른 구현을 사용하여 싱글 톤을 다른 싱글 톤으로 쉽게 대체 할 수 있기를 원합니다.
    예 : Toolkit.getDefaultToolkit()Java 의 메소드는 정확한 유형이 시스템에 따라 달라지는 싱글 톤을 반환합니다.
  • 센티넬 값에 대한 참조 동등성 을 원합니다 . 예 : C #에서.
    DBNull.Value

27
IMHO 싱글 톤이 글로벌 상태를 소개하는 데 오용 되지만 +1을 사용 하겠습니다. 싱글 톤의 목적은 객체를 전역 적으로 사용할 수 있도록하는 것이 아니라 객체가 한 번만 인스턴스화되도록하는 것입니다. 전역 개체는 필요한 악입니다. 실제로 필요한 경우가 아니라면 일반적으로 SomeSingleton.getInstance (). someMethod ()와 함께 높은 결합으로 이어 지므로 사용하지 마십시오. :)
back2dos 2010 년

여러 렌더링 인스턴스 대신 하나의 렌더링 인스턴스 만 원하는 게임이나 한 번에 하나의 연결 만있을 수있는 보안 채널을 설정하는 네트워크 파이핑 클래스에서 유용 할 수 있습니다.
Tschallacka

2
"쉽게 싱글 톤 교체"부분은 내 관점에서 가장 중요한 포인트입니다. 나머지는 정적 클래스 구현에 매우 가깝습니다.
Teoman shipahi

1
싱글 톤은 합계 / 제품 유형 등에 대한 유용한 비 Null 센티널 값입니다. 예를 들어, 옵션 유형의 경우 없음 / 없음 값이거나 컬렉션 유형의 경우 비어있는 값입니다. 참조 동등성이 필요한 모든 것이기 때문에 빠른 None / Empty 테스트를 보너스로 얻을 수 있습니다.
itsbruce

@itsbruce : 귀하의 예제는 단일 항목이 아닙니다. 빈 목록은 List 클래스의 유일한 가능한 인스턴스가 아니며 None 값이 Option 클래스의 유일한 가능한 인스턴스가 아닙니다. 그러나 센티넬 값 싱글 톤 인 예가 있으며 내 대답에 하나를 추가 할 자유를 얻었습니다. 입력 해 주셔서 감사합니다!
Heinzi

37

정적 메서드 클래스 대신에 Stateless 싱글 톤이 사용되는 경우, 즉 Dependency Injection 의 경우를 볼 수 있습니다 .

직접 사용하는 유틸리티 함수의 도우미 클래스가있는 경우 숨겨진 종속성이 생성됩니다. 누가 또는 어디서 사용할 수 있는지 제어 할 수 없습니다. 상태 비 저장 싱글 톤 인스턴스를 통해 동일한 도우미 클래스를 주입하면 사용 위치와 방법을 제어하고 필요할 때 대체 / 모의 작업 등을 수행 할 수 있습니다.

싱글 톤 인스턴스로 만드는 것은 단순히 필요한 것보다 더 많은 유형의 객체를 할당하지 않도록 보장합니다 (하나만 필요하기 때문에).


1
"누가 또는 어디서 사용할 수 있는지에 대한 통제권이 없습니다." 왜 누군가 그것을 필요로합니까?
hagrawal 2015-07-16

1
목적을 테스트 @hagrawal, 당신은 그것을 조롱 할 수 있어야한다
Jemshit Iskenderov을

15

실제로 여기에 언급되지 않은 또 다른 대답을 찾았습니다. 정적 메서드는 테스트하기가 더 어렵습니다.

대부분의 테스트 프레임 워크는 인스턴스 메서드를 모의하는 데 훌륭하게 작동하지만 대부분은 정적 메서드의 모의를 적절한 방식으로 처리하지 않습니다.


2
그러나 Powermock 그렇게 할 수있을 것 같다
세바스티앙 Lorber에게

6

대부분의 프로그래밍 언어에서 클래스는 많은 유형 시스템을 피합니다. 정적 메서드와 변수가있는 클래스는 객체이지만 인터페이스를 구현하거나 다른 클래스를 확장 할 수없는 경우가 많습니다. 따라서 다른 유형의 하위 유형이 될 수 없기 때문에 다형성 방식으로 사용할 수 없습니다. 당신이 인터페이스가있는 경우 예를 들어, IFooable다른 클래스의 여러 방법 서명에 필요한, 클래스 객체 StaticFoo대신에 사용할 수없는 IFooable반면, FooSingleton.getInstance()캔 (가정 FooSingleton구현을 IFooable).

Heinzi의 답변에 대해 언급했듯이 싱글 톤은 인스턴스화를 제어하는 ​​패턴입니다. 이는 작성자에게 인스턴스에 대한 더 많은 제어 권한 을 부여하는로 대체 new Class()되며 Class.getInstance(), Class불필요한 인스턴스 생성을 방지하는 데 사용할 수 있습니다. 싱글 톤은 팩토리 패턴의 매우 특별한 경우이므로 그렇게 처리해야합니다. 일반적으로 사용하면 글로벌 레지스트리를 사용하면 안되는 경우가 많기 때문에 글로벌 레지스트리의 특수한 경우가됩니다.

전역 도우미 함수를 제공하려는 경우 정적 메서드가 제대로 작동합니다. 클래스는 클래스가 아니라 네임 스페이스 역할을합니다. 높은 응집력을 유지하지 않으면 가장 이상한 결합 문제로 끝날 수 있습니다.

greetz
back2dos


4

어느 것을 사용하는 것 사이에는 상충 관계가 있습니다. 싱글 톤은 상태를 가질 수도 있고 없을 수도 있으며 객체를 참조합니다. 상태를 유지하지 않고 전역 액세스에만 사용되는 경우 이러한 메서드가 더 빠르기 때문에 정적이 더 좋습니다. 그러나 객체와 OOP 개념 (상속 다형성)을 활용하려면 싱글 톤이 더 좋습니다.

예를 들어 보자 : java.lang.Runtime은 java의 싱글 톤 클래스입니다. 이 클래스는 각 JVM에 대해 다른 구현을 허용합니다. 구현은 JVM 당 단일입니다. 이 클래스가 정적이라면 JVM을 기반으로 다른 구현을 전달할 수 없습니다.

이 링크가 정말 유용하다는 것을 알았습니다. http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html ?

도움이 되었기를 바랍니다 !!


이 답변은 실제 세계에 구체적인 예를 포함하는 데 좋습니다.
systemovich 2016

2

나를 위해 "객체 상태는 싱글 톤을 사용하고, 함수는 정적 방법을 사용하고 싶다"

그것은 당신이 원하는 것에 달려 있습니다. 객체 상태 (예 : null, 대신 Null 상태와 같은 다형성 또는 기본 상태) 를 원할 때마다 싱글 톤이 적절한 선택이지만 함수가 필요할 때 정적 메서드가 사용됩니다 (입력을 수신 한 다음 출력을 반환).

싱글 톤 케이스를 권장합니다. 인스턴스화 된 후에는 항상 동일한 상태 여야합니다. 복제 할 수없고 설정할 값을받지 않아야합니다 (파일의 정적 구성 (예 : Java의 속성 파일) 제외 ).

추신 :이 둘 사이의 성능은 밀리 초 단위로 다르므로 먼저 아키텍처에 집중하십시오 .


1

Singleton은 무국적자가 아니며 글로벌 상태를 유지합니다.

Singleton을 사용할 수있는 몇 가지 이유는 다음과 같습니다.

  • 메모리 누수를 방지하려면
  • 응용 프로그램의 모든 모듈에 대해 동일한 상태 제공 (예 : 데이터베이스 연결)

이 모든 클래스의 속성을 공유하지 않는 경우 ... 나는 알고 있지만 실제로 싱글은 더 많거나 적은 상태 비 저장 될 수있다
세바스티앙 Lorber에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.