Welcher reale (d. H. Praktische) Unterschied besteht zwischen einer statischen Klasse und einem Singleton-Muster?
Beide können ohne Instanziierung aufgerufen werden, beide stellen nur eine "Instanz" bereit und keine von beiden ist threadsicher. Gibt es noch einen anderen Unterschied?
Was lässt Sie sagen, dass entweder eine Singleton- oder eine statische Methode nicht threadsicher ist? Normalerweise werden beide sollte thread-sicher implementiert.
Der große Unterschied zwischen einem Singleton und einer Reihe von statischen Methoden besteht darin, dass Singletons Schnittstellen implementieren können (oder von nützlichen Basisklassen abgeleitet sind, obwohl dies meiner Erfahrung nach weniger häufig ist), sodass Sie den Singleton so weitergeben können, als ob es "nur eine andere" wäre " Implementierung.
Die wahre Antwort ist von Jon Skeet, in einem anderen Forum hier .
Ein Singleton ermöglicht den Zugriff auf eine einzelne erstellte Instanz. Diese Instanz (oder vielmehr ein Verweis auf diese Instanz) kann als Parameter an andere Methoden übergeben und als normales Objekt behandelt werden.
Eine statische Klasse erlaubt nur statische Methoden.
interface
mit einer Singleton-Klasse implementieren, die statischen Methoden einer Klasse (oder beispielsweise eine C # static class
) jedoch nicht.Das Singleton-Muster bietet gegenüber statischen Klassen mehrere Vorteile. Erstens kann ein Singleton Klassen erweitern und Schnittstellen implementieren, während eine statische Klasse dies nicht kann (sie kann Klassen erweitern, erbt jedoch nicht ihre Instanzmitglieder). Ein Singleton kann träge oder asynchron initialisiert werden, während eine statische Klasse im Allgemeinen beim ersten Laden initialisiert wird, was zu potenziellen Problemen beim Laden von Klassen führt. Der wichtigste Vorteil ist jedoch, dass Singletons polymorph gehandhabt werden können, ohne dass die Benutzer davon ausgehen müssen, dass es nur eine Instanz gibt.
static
Klassen sind nichts für Dinge, die einen Status benötigen. Dies ist nützlich, um eine Reihe von Funktionen zusammenzustellen, z. B. Math
(oder Utils
in Projekten). Der Klassenname gibt uns also nur einen Hinweis, wo wir die Funktionen finden und nicht mehr.
Singleton
ist mein Lieblingsmuster und ich verwende es, um etwas an einem einzigen Punkt zu verwalten. Es ist flexibler als static
Klassen und kann seinen Status beibehalten. Es kann Schnittstellen implementieren, von anderen Klassen erben und Vererbung zulassen.
Meine Regel für die Auswahl zwischen static
und singleton
:
Wenn es eine Reihe von Funktionen gibt, die zusammengehalten werden sollen, ist static
die Wahl. Alles andere, das einen einzelnen Zugriff auf einige Ressourcen benötigt, könnte als singleton
implementiert werden.
Statische Klasse: -
Sie können die Instanz der statischen Klasse nicht erstellen.
Wird automatisch von der Common Language Runtime (CLR) von .NET Framework geladen, wenn das Programm oder der Namespace, der die Klasse enthält, geladen wird.
Statische Klasse kann keinen Konstruktor haben.
Die statische Klasse kann nicht an method übergeben werden.
Wir können die statische Klasse nicht an eine andere statische Klasse in C # vererben.
Eine Klasse mit allen statischen Methoden.
Bessere Leistung (statische Methoden sind an die Kompilierungszeit gebunden)
Singleton: -
Sie können eine Instanz des Objekts erstellen und wiederverwenden.
Die Singleton-Instanz wird zum ersten Mal erstellt, wenn der Benutzer dies anfordert.
Singleton-Klasse kann Konstruktor haben.
Sie können das Objekt der Singleton-Klasse erstellen und an die Methode übergeben.
Die Singleton-Klasse enthält keine Einschränkung der Vererbung.
Wir können die Objekte einer Singleton-Klasse aber nicht einer statischen Klasse ablegen.
Methoden können überschrieben werden.
Kann bei Bedarf faul geladen werden (statische Klassen werden immer geladen).
Wir können Interface implementieren (statische Klasse kann Interface nicht implementieren).
Eine statische Klasse hat nur statische Methoden, für die ein besseres Wort "Funktionen" wäre. Der in einer statischen Klasse verkörperte Designstil ist rein prozedural.
Singleton ist andererseits ein Muster, das für OO -Design spezifisch ist. Es ist eine Instanz eines Objekts (mit allen damit verbundenen Möglichkeiten, wie zum Beispiel dem Polymorphismus), mit einer Erstellungsprozedur, die sicherstellt, dass es während seiner gesamten Lebensdauer immer nur eine Instanz dieser bestimmten Rolle gibt.
In einem Singleton-Muster können Sie den Singleton als Instanz eines abgeleiteten Typs erstellen. Dies ist mit einer statischen Klasse nicht möglich.
Kurzes Beispiel:
if( useD3D )
IRenderer::instance = new D3DRenderer
else
IRenderer::instance = new OpenGLRenderer
Weiter zu Jon Skeets Antwort
Der große Unterschied zwischen einem Singleton und einer Reihe von statischen Methoden besteht darin, dass Singletons Interfaces implementieren können (oder von nützlichen Basisklassen abgeleitet sind, obwohl dies im IME weniger häufig vorkommt).
Singletons sind einfacher zu handhaben, wenn Sie eine Klasse als Unit testen. Übergeben Sie Singletons als Parameter (Konstruktoren, Setter oder Methoden), können Sie stattdessen eine verspottete oder gestoppelte Version des Singletons ersetzen.
Ein weiterer Vorteil eines Singletons besteht darin, dass es einfach serialisiert werden kann. Dies kann erforderlich sein, wenn Sie den Status auf einer Disc speichern oder von einem Remotestandort aus senden möchten.
Hier ist ein guter Artikel: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-Java.html
methoden können nicht überschrieben, aber das Ausblenden von Methoden verwendet werden. ( Was ist eine Methode, die sich in Java versteckt? Sogar die JavaDoc-Erklärung ist verwirrend )
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");
}
}
Zusammenfassend würde ich statische Klassen nur zum Speichern von util-Methoden und Singleton für alles andere verwenden.
Bearbeitungen
statische Klassen werden ebenfalls faul geladen. Thanks @jmoreno ( Wann findet die statische Klasseninitialisierung statt? )
methode, die sich für statische Klassen versteckt. Vielen Dank @MaxPeng.
Ich bin kein großer OO Theoretiker, aber meines Wissens ist das einzige OO Merkmal, das statischen Klassen im Vergleich zu Singletons fehlt, Polymorphismus. Aber wenn Sie es nicht brauchen, können Sie mit einer statischen Klasse natürlich Vererbung (nicht sicher über die Schnittstellenimplementierung) und Daten- und Funktionskapselung haben.
Der Kommentar von Morendil: "Der in einer statischen Klasse verkörperte Designstil ist rein prozedural." Ich kann mich irren, aber ich bin anderer Meinung. In statischen Methoden können Sie auf statische Member zugreifen, die genau den Singleton-Methoden entsprechen, die auf ihre einzelnen Instanzmember zugreifen.
bearbeiten:
Ich denke jetzt tatsächlich, dass ein weiterer Unterschied darin besteht, dass eine statische Klasse instanziiert beim Programmstart * ist und die gesamte Lebensdauer des Programms durchläuft, während ein Singleton explizit bei instanziiert wird Irgendwann und kann auch zerstört werden.
* oder es kann beim ersten Gebrauch instanziiert werden, abhängig von der Sprache, denke ich.
Um Jons Punkt zu veranschaulichen, ist das Folgende nicht möglich, wenn Logger eine statische Klasse war. Die Klasse SomeClass
erwartet, dass eine Instanz der ILogger
-Implementierung an ihren Konstruktor übergeben wird.
Die Singleton-Klasse ist wichtig, damit die Abhängigkeitsinjektion möglich ist.
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();
}
}
Nun, ein Singleton ist nur eine normale Klasse, die IS nur einmal und indirekt aus dem Clientcode instanziiert. Statische Klasse wird nicht instanziiert. Soweit ich weiß, sind statische Methoden (statische Klassen müssen statische Methoden haben) schneller als nicht statische.
Bearbeiten:
Beschreibung der FxCop-Leistungsregel: "Methoden, die nicht auf Instanzdaten zugreifen oder Instanzmethoden aufrufen, können als statisch markiert werden (in VB freigegeben). Anschließend sendet der Compiler nicht virtuelle Aufrufsites an diese Mitglieder, die Verhindert eine Überprüfung zur Laufzeit für jeden Aufruf, der sicherstellt, dass der aktuelle Objektzeiger nicht null ist. Dies kann zu einem messbaren Leistungsgewinn für leistungsabhängigen Code führen. In einigen Fällen stellt der fehlende Zugriff auf die aktuelle Objektinstanz ein Korrektheitsproblem dar . "
Ich weiß eigentlich nicht, ob dies auch für statische Methoden in statischen Klassen gilt.
Singletons sind instanziiert, es gibt nur eine Instanz, die jemals instanziiert wurde, daher das single in Singleton.
Eine statische Klasse kann nur durch sich selbst instanziiert werden.
Hauptunterschiede sind:
Ich stimme dieser Definition zu:
Das Wort " single " bedeutet ein einzelnes Objekt über den gesamten Anwendungslebenszyklus, sodass der Geltungsbereich auf Anwendungsebene liegt.
Die statische hat keinen Objektzeiger, daher befindet sich der Bereich auf der Ebene der Anwendungsdomäne.
Darüber hinaus sollte beides threadsicher implementiert werden.
Sie finden interessante andere Unterschiede zu: Singleton Pattern Versus Static Class
Singleton ist aus der Testperspektive ein besserer Ansatz. Im Gegensatz zu statischen Klassen kann Singleton Schnittstellen implementieren und Sie können eine Scheininstanz verwenden und diese einfügen.
Im folgenden Beispiel werde ich dies veranschaulichen. Angenommen, Sie haben eine Methode isGoodPrice (), die eine Methode getPrice () verwendet, und Sie implementieren getPrice () als Methode in einem Singleton.
singleton mit getPrice-Funktionalität:
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;
}
}
Verwendung von 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();
}
Letzte Singleton-Implementierung:
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;
}
testklasse:
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);
}
}
Wenn wir die Alternative zur Verwendung der statischen Methode zur Implementierung von getPrice () wählen, war es schwierig, getPrice () zu verspotten. Mit Power Mock können Sie statische Aufladungen verspotten, aber nicht alle Produkte können sie verwenden.
Ein bemerkenswerter Unterschied ist die unterschiedliche Instanziierung, die mit Singletons geliefert wird.
Bei statischen Klassen wird sie von der CLR erstellt und wir haben keine Kontrolle darüber. Bei Singletons wird das Objekt bei der ersten Instanz instanziiert, auf die zugegriffen werden soll.
Wir haben unser DB-Framework, das Verbindungen zum Back-End herstellt. Um fehlerhafte Lesevorgänge zwischen mehreren Benutzern zu vermeiden, haben wir Singleton-Muster verwendet, um sicherzustellen, dass zu jedem Zeitpunkt nur eine Instanz verfügbar ist.
In c # kann eine statische Klasse keine Schnittstelle implementieren. Wenn eine einzelne Instanzklasse eine Schnittstelle für Geschäftsverträge oder IoC-Zwecke implementieren muss, verwende ich hier das Singleton-Muster ohne statische Klasse
Singleton bietet eine Möglichkeit, den Status in zustandslosen Szenarien zu erhalten
Hoffe das hilft dir ..
In vielen Fällen haben diese beiden keinen praktischen Unterschied, insbesondere wenn sich die Singleton-Instanz nie oder nur sehr langsam ändert, z. Halten von Konfigurationen.
Ich würde sagen, der größte Unterschied ist, dass ein Singleton immer noch eine normale Java Bean ist, im Gegensatz zu einer speziellen Klasse, die nur statisch ist Java. Aus diesem Grund wird ein Singleton in vielen weiteren Situationen akzeptiert. Dies ist in der Tat die Standard-Instanziierungsstrategie von Spring Framework. Der Verbraucher kann oder kann nicht wissen, dass es ein Singleton ist, der herumgereicht wird, es behandelt es gerade wie ein normales Java Bean. Wenn sich die Anforderungen ändern und ein Singleton stattdessen ein Prototyp werden muss, wie wir häufig im Frühjahr sehen, kann dies völlig nahtlos erfolgen, ohne dass eine Codezeile für den Verbraucher geändert werden muss.
Jemand anderes hat früher erwähnt, dass eine statische Klasse rein prozedural sein sollte, z. Java.lang.Math. In meinen Augen sollte eine solche Klasse niemals herumgereicht werden und sie sollte niemals etwas anderes als das statische Finale als Attribute enthalten. Verwenden Sie für alles andere einen Singleton, da dieser viel flexibler und einfacher zu warten ist.
Ich habe folgendes gelesen und finde es auch sinnvoll:
kümmert sich ums Geschäft
Denken Sie daran, eine der wichtigsten OO Regeln ist, dass ein Objekt für sich selbst verantwortlich ist. Dies bedeutet, dass Probleme im Zusammenhang mit dem Lebenszyklus einer Klasse in der Klasse behandelt und nicht an Sprachkonstrukte wie static usw. delegiert werden sollten.
aus dem Buch Objected-Oriented Thought Process 4th Ed.
In einem Artikel, den ich geschrieben habe, habe ich meine Sichtweise darüber beschrieben, warum der Singleton viel besser ist als eine statische Klasse:
Wir können das Objekt der Singleton-Klasse erstellen und an die Methode übergeben.
Die Singleton-Klasse unterliegt keiner Einschränkung der Vererbung.
Wir können die Objekte einer statischen Klasse nicht entsorgen, können aber Singleton-Klassen.
ein. Serialisierung - Statische Member gehören zur Klasse und können daher nicht serialisiert werden.
b. Obwohl wir den Konstruktor als privat deklariert haben, werden statische Membervariablen weiterhin in die Unterklasse übernommen.
c. Wir können keine verzögerte Initialisierung durchführen, da alles nur beim Laden der Klasse geladen wird.
Aus Client-Sicht ist das statische Verhalten dem Client bekannt, das Singleton-Verhalten kann jedoch vor einem Client verborgen abgeschlossen werden. Der Kunde wird möglicherweise nie erfahren, dass es nur eine einzige Instanz gibt, mit der er immer wieder herumspielt.
Es gibt einen großen Unterschied zwischen einer einzelne statische Klasse Instanz (dh einer einzelnen Instanz einer Klasse, die zufällig eine statische oder globale Variable ist) und einem einzelner statischer Zeiger = zu einer Instanz der Klasse auf dem Heap:
Wenn Ihre Anwendung beendet wird, wird der Destruktor der statischen Klasseninstanz aufgerufen. Das heißt, wenn Sie diese statische Instanz als Singleton verwendet haben, funktioniert Ihr Singleton nicht mehr ordnungsgemäß. Wenn immer noch Code ausgeführt wird, der diesen Singleton verwendet, beispielsweise in einem anderen Thread, stürzt dieser Code wahrscheinlich ab.
Eine statische Klasse in Java hat nur statische Methoden. Es ist ein Container mit Funktionen. Es basiert auf prozeduralem Programmierdesign.
Singleton-Klasse ist ein Muster in Object Oriented Design. Eine Singleton-Klasse hat nur eine Instanz eines Objekts in JVM. Dieses Muster wird so implementiert, dass in JVM immer nur eine Instanz dieser Klasse vorhanden ist.
Wenn ich Unterricht mit voller Funktionalität möchte, z. Es gibt viele Methoden und Variablen, ich benutze Singleton;
Wenn ich eine Klasse mit nur einer oder zwei Methoden haben möchte, z. MailService-Klasse, die nur 1 Methode hat SendMail () Ich verwende statische Klasse und Methode.
Der Unterschied in meinem Kopf ist die Implementierung von objektorientierter Programmierung (Singleton/Prototype) oder funktionaler Programmierung (Static).
Wir konzentrieren uns zu sehr auf die Anzahl der Objekte, die durch das Singleton-Muster erzeugt werden, wobei wir uns darauf konzentrieren sollten, dass wir am Ende ein Objekt halten. Wie andere bereits gesagt haben, kann es erweitert, als Parameter übergeben werden, aber vor allem ist es zustandsvoll.
Zum anderen wird mit static die funktionale Programmierung implementiert. Die statischen Member gehören zu einer Klasse. Sie sind staatenlos.
Übrigens wussten Sie, dass Sie statische Singleton-Klassen erstellen können :)
Wie ich den Unterschied zwischen einer statischen Klasse und einer nicht statischen Singleton-Klasse verstehe, handelt es sich bei der statischen Klasse in C # lediglich um einen nicht instanziierten "Typ", bei dem die Singleton-Klasse ein echtes "Objekt" ist. Mit anderen Worten, alle statischen Elemente in einer statischen Klasse werden dem Typ zugewiesen, befinden sich jedoch im Singleton unter dem Objekt. Beachten Sie jedoch, dass sich eine statische Klasse immer noch wie ein Referenztyp verhält, da es sich nicht um einen Werttyp wie ein Struct handelt.
Das heißt, wenn Sie ein Singleton erstellen, weil die Klasse selbst nicht statisch ist, sondern ihr Mitglied, ist der Vorteil, dass das statische Mitglied innerhalb des Singleton, das sich auf sich selbst bezieht, mit einem tatsächlichen "Objekt" verbunden ist und nicht mit einem hohlen "Typ" von sich selbst. Dadurch wird der Unterschied zwischen einem statischen und einem nicht statischen Singleton über die anderen Funktionen und die Speichernutzung hinaus verdeutlicht, was für mich verwirrend ist.
Beide verwenden statische Member, die einzelne Kopien eines Members sind, aber der Singleton umschließt das referenzierte Member mit einem echten instanziierten "Objekt", dessen Adresse zusätzlich zu seinem statischen Member existiert. Dieses Objekt selbst verfügt über Eigenschaften, in denen in umgangen und referenziert werden kann, wodurch ein Mehrwert erzielt wird. Die Static-Klasse ist nur ein Typ, sie existiert also nur, um auf ihre statischen Member zu verweisen. Dieses Konzept festigte den Zweck der Singleton vs Static Class über die Vererbung und andere Fragen hinaus.
Beispiel mit einer statischen Klasse
public class Any {
private static Any instance = new Any();
private Singleton() {
System.out.println("creating");
}
}
bei Singleton-Mustern gibt es nur eine Instanz:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
System.out.println("creating");
if (instance != null) {
throw new RuntimeException("Imposible create a new instance ");
}
}
}