정적 클래스와 싱글톤 패턴 사이에 실제(즉, 실제적인) 차이점은 무엇입니까?
둘 다 인스턴스화 없이 호출할 수 있으며 둘 다 하나의 "인스턴스"만 제공하며 둘 다 스레드로부터 안전하지 않습니다. 다른 차이점이 있습니까?
질문자 :Jorge Córdoba
정적 클래스와 싱글톤 패턴 사이에 실제(즉, 실제적인) 차이점은 무엇입니까?
둘 다 인스턴스화 없이 호출할 수 있으며 둘 다 하나의 "인스턴스"만 제공하며 둘 다 스레드로부터 안전하지 않습니다. 다른 차이점이 있습니까?
싱글톤이나 정적 메서드가 스레드로부터 안전하지 않다고 말하는 이유는 무엇입니까? 일반적으로 둘 다 스레드로부터 안전하도록 구현 되어야 합니다.
싱글톤과 정적 메서드 묶음의 가장 큰 차이점은 싱글톤이 인터페이스를 구현할 수 있다는 것입니다(또는 내 경험상 덜 일반적이지만 유용한 기본 클래스에서 파생됨). " 구현.
진정한 대답은 여기 다른 포럼의 Jon Skeet입니다.
싱글톤은 생성된 단일 인스턴스에 대한 액세스를 허용합니다. 해당 인스턴스(또는 오히려 해당 인스턴스에 대한 참조)는 다른 메소드에 매개변수로 전달되고 일반 객체로 처리될 수 있습니다.
정적 클래스는 정적 메서드만 허용합니다.
interface
를 구현할 수 있지만 클래스의 정적 메서드(예: C# static class
)는 구현할 수 없습니다.싱글톤 패턴은 정적 클래스에 비해 몇 가지 장점이 있습니다. 첫째, 싱글톤은 클래스를 확장하고 인터페이스를 구현할 수 있지만 정적 클래스는 할 수 없습니다(클래스를 확장할 수 있지만 인스턴스 멤버를 상속하지 않음). 싱글톤은 느리게 또는 비동기적으로 초기화될 수 있지만 정적 클래스는 일반적으로 처음 로드될 때 초기화되어 잠재적인 클래스 로더 문제가 발생할 수 있습니다. 그러나 가장 중요한 이점은 사용자가 인스턴스가 하나만 있다고 가정하지 않고도 싱글톤을 다형성으로 처리할 수 있다는 것입니다.
static
클래스는 상태가 필요한 것이 아닙니다. Math
(또는 프로젝트의 Utils
와 같은 여러 기능을 함께 사용하는 데 유용합니다. 따라서 클래스 이름은 우리가 함수를 찾을 수 있는 단서를 제공할 뿐 그 이상은 아닙니다.
Singleton
은 내가 가장 좋아하는 패턴이며 단일 지점에서 무언가를 관리하는 데 사용합니다. static
클래스보다 유연하고 상태를 유지할 수 있습니다. 인터페이스를 구현하고 다른 클래스에서 상속하며 상속을 허용할 수 있습니다.
static
및 singleton
선택에 대한 내 규칙 :
함께 유지해야 하는 많은 기능이 있는 경우 static
이 선택됩니다. 일부 리소스에 대한 단일 액세스가 필요한 다른 모든 것은 singleton
으로 구현될 수 있습니다.
정적 클래스:-
정적 클래스의 인스턴스를 만들 수 없습니다.
클래스를 포함하는 프로그램이나 네임스페이스가 로드될 때 .NET Framework CLR(공용 언어 런타임)에 의해 자동으로 로드됩니다.
메서드에 정적 클래스를 전달할 수 없습니다.
C#에서는 Static 클래스를 다른 Static 클래스로 상속할 수 없습니다.
모든 정적 메서드가 있는 클래스입니다.
더 나은 성능(정적 메서드는 컴파일 시간에 결합됨)
하나씩 일어나는 것:-
개체의 인스턴스를 하나 만들고 다시 사용할 수 있습니다.
Singleton 인스턴스는 사용자가 요청할 때 처음 생성됩니다.
싱글톤 클래스의 객체를 생성하여 메소드에 전달할 수 있습니다.
Singleton 클래스는 상속에 대한 제한을 말하지 않습니다.
싱글톤 클래스의 객체는 처분할 수 있지만 정적 클래스는 처분할 수 없습니다.
메서드를 재정의할 수 있습니다.
필요할 때 지연 로드할 수 있습니다(정적 클래스는 항상 로드됨).
인터페이스를 구현할 수 있습니다(정적 클래스는 인터페이스를 구현할 수 없음).
정적 클래스는 "함수"가 더 나은 단어인 정적 메서드만 있는 클래스입니다. 정적 클래스에 구현된 디자인 스타일은 순전히 절차적입니다.
반면에 싱글톤은 객체지향 디자인 특유의 패턴입니다. 이것은 객체의 인스턴스(다형성과 같은 모든 가능성이 내재되어 있음)이며 전체 수명 동안 해당 특정 역할의 인스턴스가 하나만 있음을 보장하는 생성 절차가 있습니다.
싱글톤 패턴에서는 파생된 유형의 인스턴스로 싱글톤을 만들 수 있지만 정적 클래스에서는 그렇게 할 수 없습니다.
빠른 예:
if( useD3D ) IRenderer::instance = new D3DRenderer else IRenderer::instance = new OpenGLRenderer
Jon Skeet의 답변 을 확장하려면
싱글톤과 정적 메서드 묶음의 가장 큰 차이점은 싱글톤이 인터페이스를 구현할 수 있다는 것입니다(또는 덜 일반적인 IME이지만 유용한 기본 클래스에서 파생됨). 따라서 싱글톤을 "그냥 또 다른" 구현인 것처럼 전달할 수 있습니다.
싱글톤은 클래스를 단위 테스트할 때 작업하기가 더 쉽습니다. 싱글톤을 매개변수(생성자, 설정자 또는 메서드)로 전달할 때마다 싱글톤의 모의 또는 스텁 버전을 대신 대체할 수 있습니다.
다음은 좋은 기사입니다. http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
메서드를 재정의할 수 없지만 메서드 숨기기를 사용할 수 있습니다. ( 자바에서 메소드 숨김이란? JavaDoc 설명도 헷갈린다 )
public class Animal { public static void foo() { System.out.println("Animal"); } } public class Cat extends Animal { public static void foo() { // hides Animal.foo() System.out.println("Cat"); } }
요약하면, 저는 util 메서드를 유지하기 위해 정적 클래스만 사용하고 다른 모든 것에 Singleton을 사용합니다.
편집
정적 클래스도 지연 로드됩니다. @jmoreno 감사합니다( 정적 클래스 초기화는 언제 하나요? )
정적 클래스에 대한 메서드 숨김. @MaxPeng 감사합니다.
싱글톤의 또 다른 장점은 쉽게 직렬화할 수 있다는 것입니다. 이는 디스크에 상태를 저장하거나 원격으로 보내야 하는 경우 필요할 수 있습니다.
나는 훌륭한 객체지향 이론가는 아니지만, 내가 아는 바에 따르면 정적 클래스에 싱글톤에 비해 부족한 객체 객체 기능은 다형성뿐이라고 생각합니다. 그러나 필요하지 않은 경우 정적 클래스를 사용하면 물론 상속(인터페이스 구현에 대해 확실하지 않음)과 데이터 및 함수 캡슐화를 가질 수 있습니다.
"정적 클래스에 구현된 디자인 스타일은 순전히 절차적"이라는 모렌딜의 의견이 틀릴 수도 있지만 동의하지 않습니다. 정적 메서드에서는 단일 인스턴스 멤버에 액세스하는 싱글톤 메서드와 정확히 동일한 정적 멤버에 액세스할 수 있습니다.
편집하다:
저는 실제로 Static 클래스가 프로그램 시작* 시 인스턴스화 되고 프로그램의 전체 수명 기간 동안 지속되는 반면, 싱글톤은 특정 시점에서 명시적으로 인스턴스화되고 파괴될 수도 있다는 또 다른 차이점이 있다고 생각합니다.
* 또는 언어에 따라 처음 사용할 때 인스턴스화될 수 있다고 생각합니다.
Jon의 요점을 설명하기 위해 Logger가 정적 클래스인 경우 아래에 표시된 작업을 수행할 수 없습니다. SomeClass
ILogger
구현의 인스턴스가 생성자에 전달될 것으로 예상합니다.
의존성 주입이 가능하려면 싱글톤 클래스가 중요합니다.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { var someClass = new SomeClass(Logger.GetLogger()); } } public class SomeClass { public SomeClass(ILogger MyLogger) { } } public class Logger : ILogger { private static Logger _logger; private Logger() { } public static Logger GetLogger() { if (_logger==null) { _logger = new Logger(); } return _logger; } public void Log() { } } public interface ILogger { void Log(); } }
싱글톤은 인스턴스화되지만 클라이언트 코드에서 간접적으로 한 번만 생성되는 일반 클래스입니다. 정적 클래스는 인스턴스화되지 않습니다. 내가 아는 한 정적 메서드(정적 클래스에는 정적 메서드가 있어야 함)가 비정적 메서드보다 빠릅니다.
편집하다:
FxCop 성능 규칙 설명: "인스턴스 데이터에 액세스하지 않거나 인스턴스 메서드를 호출하지 않는 메서드는 정적(VB에서 공유)으로 표시될 수 있습니다. 그렇게 한 후 컴파일러는 이러한 멤버에 가상이 아닌 호출 사이트를 내보내어 확인을 방지합니다. "현재 개체 포인터를 보장하는 각 호출에 대한 런타임은 null이 아닙니다. 이로 인해 성능에 민감한 코드에 대해 측정 가능한 성능 향상이 발생할 수 있습니다. 어떤 경우에는 현재 개체 인스턴스에 액세스하지 못하는 것이 정확성 문제를 나타냅니다."
이것이 정적 클래스의 정적 메서드에도 적용되는지 실제로는 모르겠습니다.
Singleton은 인스턴스화되며 인스턴스화 된 인스턴스가 하나만 있으므로 Singleton의 단일 입니다.
정적 클래스는 자신 이외의 다른 것으로 인스턴스화할 수 없습니다.
주요 차이점은 다음과 같습니다.
싱글톤은 테스트 관점에서 더 나은 접근 방식입니다. 정적 클래스와 달리 싱글톤은 인터페이스를 구현할 수 있으며 모의 인스턴스를 사용하여 주입할 수 있습니다.
아래 예에서 이를 설명하겠습니다. getPrice() 메서드를 사용하는 isGoodPrice() 메서드가 있고 getPrice()를 단일 메서드로 구현한다고 가정합니다.
getPrice 기능을 제공하는 싱글톤:
public class SupportedVersionSingelton { private static ICalculator instance = null; private SupportedVersionSingelton(){ } public static ICalculator getInstance(){ if(instance == null){ instance = new SupportedVersionSingelton(); } return instance; } @Override public int getPrice() { // calculate price logic here return 0; } }
getPrice 사용:
public class Advisor { public boolean isGoodDeal(){ boolean isGoodDeal = false; ICalculator supportedVersion = SupportedVersionSingelton.getInstance(); int price = supportedVersion.getPrice(); // logic to determine if price is a good deal. if(price < 5){ isGoodDeal = true; } return isGoodDeal; } } In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by: Make your singleton implement an interface and inject it. public interface ICalculator { int getPrice(); }
최종 싱글톤 구현:
public class SupportedVersionSingelton implements ICalculator { private static ICalculator instance = null; private SupportedVersionSingelton(){ } public static ICalculator getInstance(){ if(instance == null){ instance = new SupportedVersionSingelton(); } return instance; } @Override public int getPrice() { return 0; } // for testing purpose public static void setInstance(ICalculator mockObject){ if(instance != null ){ instance = mockObject; }
테스트 클래스:
public class TestCalculation { class SupportedVersionDouble implements ICalculator{ @Override public int getPrice() { return 1; } } @Before public void setUp() throws Exception { ICalculator supportedVersionDouble = new SupportedVersionDouble(); SupportedVersionSingelton.setInstance(supportedVersionDouble); } @Test public void test() { Advisor advidor = new Advisor(); boolean isGoodDeal = advidor.isGoodDeal(); Assert.assertEquals(isGoodDeal, true); } }
getPrice()를 구현하기 위해 정적 메서드를 사용하는 대안을 취하는 경우 모의 getPrice()가 어려웠습니다. power mock으로 static을 mock 할 수 있지만 모든 제품에서 사용할 수 있는 것은 아닙니다.
JDK에는 싱글톤 및 정적 예제가 모두 있습니다. 한편으로 java.lang.Math
는 정적 메서드가 있는 최종 클래스이고 다른 한편으로는 java.lang.Runtime
이 싱글톤 클래스입니다.
싱글톤의 장점
싱글톤 패턴보다 상태를 유지해야 하는 경우 정적 클래스보다 더 나은 선택입니다. 정적 클래스에서 상태를 유지하면 버그가 발생하고, 특히 동시 환경에서 여러 스레드에 의한 적절한 동기화 병렬 수정 없이 경합 상태가 발생할 수 있기 때문입니다.
싱글톤 클래스는 객체가 무거우면 지연 로드될 수 있지만 정적 클래스는 그런 장점이 없고 항상 빠르게 로드됩니다.
싱글톤을 사용하면 상속 및 다형성을 사용하여 기본 클래스를 확장하고 인터페이스를 구현하며 다양한 구현을 제공할 수 있습니다.
Java의 정적 메서드는 재정의할 수 없으므로 유연성이 떨어집니다. 반면에 싱글톤 클래스에 정의된 메서드를 확장하여 재정의할 수 있습니다.
정적 클래스의 단점
정적 클래스의 장점
각각에 대한 자세한 설명이 너무 장황하여 좋은 기사에 대한 링크를 걸어 놓았습니다. - Singleton에 대해 알고 싶은 모든 것
나는 이 정의에 동의합니다.
"단일 "이라는 단어는 응용 프로그램 수명 주기 전반에 걸쳐 단일 개체를 의미하므로 범위는 응용 프로그램 수준에 있습니다.
정적 에는 개체 포인터가 없으므로 범위는 앱 도메인 수준입니다.
또한 둘 다 스레드로부터 안전하도록 구현되어야 합니다.
다음과 같은 흥미로운 다른 차이점을 찾을 수 있습니다. 싱글톤 패턴 대 정적 클래스
한 가지 주목할만한 차이점은 Singleton과 함께 제공되는 다른 인스턴스화입니다.
정적 클래스를 사용하면 CLR에 의해 생성되며 우리는 이를 제어할 수 없습니다. 싱글톤을 사용하면 액세스를 시도한 첫 번째 인스턴스에서 개체가 인스턴스화됩니다.
많은 경우에 이 둘은 실질적인 차이가 없습니다. 특히 싱글톤 인스턴스가 변경되지 않거나 구성 유지와 같이 매우 느리게 변경되는 경우 특히 그렇습니다.
가장 큰 차이점은 싱글톤이 특수 정적 전용 Java 클래스에 반대되는 일반 Java Bean이라는 것입니다. 이 때문에 더 많은 상황에서 싱글톤이 허용됩니다. 사실 이것은 기본 Spring Framework의 인스턴스화 전략입니다. 소비자는 그것이 전달되는 싱글톤이라는 것을 모를 수도 있고 알지 못할 수도 있습니다. 그냥 일반 자바 빈처럼 취급합니다. 요구 사항이 변경되고 싱글톤이 대신 프로토타입이 되어야 하는 경우 Spring에서 자주 볼 수 있듯이 소비자에 대한 코드 변경 없이 완전히 원활하게 수행될 수 있습니다.
다른 누군가는 이전에 정적 클래스가 java.lang.Math와 같이 순전히 절차적이어야 한다고 언급했습니다. 내 생각에 그러한 클래스는 절대 전달되어서는 안 되며 속성으로 static final 이외의 다른 것을 보유해서는 안 됩니다. 다른 모든 것에는 훨씬 더 유연하고 유지 관리하기 쉽기 때문에 싱글톤을 사용하세요.
우리는 백엔드에 연결하는 DB 프레임워크를 가지고 있습니다. 여러 사용자에 걸친 Dirty 읽기를 방지하기 위해 싱글톤 패턴을 사용하여 언제든지 단일 인스턴스를 사용할 수 있도록 했습니다.
C#에서 정적 클래스는 인터페이스를 구현할 수 없습니다. 단일 인스턴스 클래스가 비즈니스 계약 또는 IoC 목적을 위해 인터페이스를 구현해야 할 때 정적 클래스 없이 Singleton 패턴을 사용하는 곳입니다.
Singleton은 상태 비저장 시나리오에서 상태를 유지하는 방법을 제공합니다.
도움이 되기를 바랍니다.
내가 쓴 기사에서 싱글톤이 정적 클래스보다 훨씬 나은 이유에 대한 내 관점을 설명했습니다.
NS. 직렬화 - 정적 멤버는 클래스에 속하므로 직렬화할 수 없습니다.
NS. 생성자를 비공개로 만들었지만 정적 멤버 변수는 여전히 하위 클래스로 전달됩니다.
씨. 모든 것이 클래스 로드 시에만 로드되므로 지연 초기화를 수행할 수 없습니다.
클라이언트 관점에서 정적 동작은 클라이언트에 알려져 있지만 싱글톤 동작은 클라이언트에서 숨겨져 완료될 수 있습니다. 클라이언트는 그가 계속해서 가지고 놀고 있는 단 하나의 인스턴스가 있다는 것을 결코 알지 못할 수도 있습니다.
나는 다음을 읽고 그것이 의미가 있다고 생각합니다.
비즈니스 돌보기
가장 중요한 객체지향 규칙 중 하나는 객체가 자신을 책임진다는 것을 기억하십시오. 즉, 클래스의 수명 주기에 관한 문제는 정적 등과 같은 언어 구성에 위임되지 않고 클래스에서 처리되어야 함을 의미합니다.
책 Objected-Oriented Thought Process 4th Ed.
싱글톤 클래스의 객체를 생성하여 메소드에 전달할 수 있습니다.
Singleton 클래스는 상속에 대한 제한이 없습니다.
정적 클래스의 개체는 삭제할 수 없지만 단일 클래스는 처리할 수 있습니다.
java.lang.Runtime
과 같은 애플리케이션 수명 주기 동안 객체(하나의 인스턴스만)를 제공합니다.
java.lang.Math
와 같은 정적 메소드만 제공하지만
Java의 정적 메서드는 재정의할 수 없지만 Singleton 클래스에 정의된 메서드는 이를 확장하여 재정의할 수 있습니다.
Singleton 클래스는 상속 및 다형성을 통해 기본 클래스를 확장하고 인터페이스를 구현하며 다양한 구현을 제공할 수 있습니다. 정적이 아닌 반면.
예를 들어 java.lang.Runtime
은 Java의 싱글톤 클래스이며 getRuntime()
메소드를 호출하면 현재 Java 애플리케이션과 연관된 런타임 오브젝트를 리턴하지만 JVM당 하나의 인스턴스만 보장합니다.
단일 정적 클래스 인스턴스(즉, 정적 또는 전역 변수인 클래스의 단일 인스턴스)와 힙에 있는 클래스 인스턴스에 대한 단일 정적 포인터 사이에는 큰 차이가 있습니다.
애플리케이션이 종료되면 정적 클래스 인스턴스의 소멸자가 호출됩니다. 즉, 해당 정적 인스턴스를 싱글톤으로 사용한 경우 싱글톤이 제대로 작동하지 않습니다. 예를 들어 다른 스레드에서 해당 싱글톤을 사용하는 코드가 여전히 실행 중인 경우 해당 코드가 충돌할 수 있습니다.
출처 : http:www.stackoverflow.com/questions/519520/difference-between-static-class-and-singleton-pattern
Python virtualenv를 종료/종료/비활성화하는 방법 (0) | 2021.12.24 |
---|---|
다른 폴더에서 파일 가져오기 (0) | 2021.12.24 |
Git의 마스터 브랜치를 다른 브랜치에서 완전히 바꾸는 방법은 무엇입니까? [복제하다] (0) | 2021.12.21 |
Java는 기본 매개변수 값을 지원합니까? (0) | 2021.12.21 |
이미지를 업로드하기 전에 미리보기 (0) | 2021.12.21 |