Als ich die Klasse selbst mit dem Singleton-Muster definierte, fragte ich mich plötzlich, also schlug ich nach. Was ist das für eine Frage?
Warum in Singleton anstelle der Klassenmethode implementieren?
darüber. Als ich dies vertiefte, verstand ich nicht, warum ich die Klasse überhaupt mit dem Singleton-Muster implementierte.
In meinem privaten Projekt wollte ich eine Klasse zum Verwalten von Immobilien, daher habe ich Folgendes implementiert:
PropertyService.java
import java.util.HashMap;
import java.util.Map;
public class PropertyService {
private static final PropertyService INSTANCE = new PropertyService();
private Map<String, String> props = new HashMap<String, String>();
private PropertyService(){
initializeProps();
}
public static PropertyService getInstance() {
return INSTANCE;
}
private void initializeProps() {
//Implementieren Sie eine Methode zum Initialisieren von Eigenschaften
//Geben Sie den Wert der Einfachheit halber manuell ein.
props.put("a", "Tanaka");
props.put("b", "Suzuki");
props.put("c", "Sato");
}
public String getVal(String key) {
return this.props.get(key);
}
}
Die obige Implementierung hat ein Singleton-Muster. Für mich dachte ich: "Da wir in der Lage sein müssen, Eigenschaften zu verwalten, die allen Projekten gemeinsam sind, sollten wir ein" Singleton-Muster "verwenden, das so implementiert ist, dass es immer eine Instanz gibt." Es kann jedoch auch wie folgt unter Verwendung der obigen Klassen und Klassenmethoden implementiert werden.
PropertyUtils.java
import java.util.HashMap;
public class PropertyUtils {
private static final HashMap<String, String> props = new HashMap<String, String>();
static {
//Eigenschaftsinitialisierungsprozess
props.put("a", "Tanaka");
props.put("b", "Suzuki");
props.put("c", "Sato");
}
public static String getVal(String key) {
return props.get(key);
}
}
Es ist eine sogenannte Utility-Klasse. Dies ist einfacher zu implementieren und scheint in der Lage zu sein, Eigenschaften zentral zu verwalten.
Warum müssen wir es also in einem Singleton-Muster implementieren? Warum brauchen wir "*** immer nur eine Instanz ***", anstatt es in einer Klassenmethode zu implementieren?
Wenn Sie beispielsweise eine Schnittstelle implementieren möchten, können Sie sie nicht durch eine statische Methode ersetzen.
TestInterface.java
public interface TestInterface {
public void sayHello(String name);
}
TestImplements.java
public class TestImplements implements TestInterface {
private static final TestImplements INSTANCE = new TestImplements();
private TestImplements() {}
public static TestImplements getInstance() {
return INSTANCE;
}
@Override
public void sayHello(String name) {
System.out.println("Hello " + name + " !");
}
}
Natürlich können Sie eine statische Methode in der Schnittstelle definieren und eine statische Methode mit demselben Namen in der Implementierungsklasse definieren. Diese wird jedoch als völlig andere Methode behandelt, nicht als Überschreibung. Dies ist der Vorteil der Implementierung der Schnittstelle Ist weg. Wenn Sie eine statische Methode in der Schnittstelle definieren, können Sie diese Methode verwenden, ohne eine Implementierungsklasse zu erstellen. Wenn Sie die Schnittstelle also wie oben beschrieben implementieren möchten, müssen Sie weiterhin das Singleton-Muster verwenden.
Bei der Implementierung einer statischen Methode in der Schnittstelle
public interface TestInterface {
public static void sayHello(String name) {
System.out.println("Hello " + name + " !");
}
}
Sie können statische Methoden verwenden, ohne sie zu implementieren
public class TestImplements implements TestInterface {
...(Unterlassung)...
public static void sayHello(String name) {
TestInterface.sayHello(name);
}
}
Beim Überschreiben einer Methode einer abstrakten Klasse kann der statische Modifikator nicht hinzugefügt werden, daher muss er als Singleton-Muster implementiert werden.
TestAbstract.java
abstract public class TestAbstract {
abstract public void sayHello(String name);
}
TestExtends.java
public class TestExtends extends TestAbstract {
private static final TestExtends INSTANCE = new TestExtends();
private TestExtends() {}
public static TestExtends getInstance() {
return INSTANCE;
}
@Override
public void sayHello(String name) {
System.out.println("Hello" + name + " !");
}
}
Wenn Sie beispielsweise im Frühjahr eine Bean definieren möchten, müssen Sie die Klasseninstanz als Bean festlegen. Wenn Sie es also zu einer allgemeinen Klasse für Ihre Apps machen und diese Klasse als DI festlegen möchten, müssen Sie sie in einem Singleton-Muster implementieren.
Wenn Sie Spring Bean einstellen möchten
@Configuration
public class BeanConfiguration {
@Bean
public TestInterface testInterface() {
return TestImplements.getInstance();
}
}
Wenn Sie beispielsweise Abhängigkeiten mit Autowired wie spring einfügen möchten, können Sie das injizierte Feld nicht statisch machen, sodass Sie es in einem Singleton-Muster implementieren müssen.
python
public class TestImplements implements TestInterface {
...(Unterlassung)...
@Autowired
TestService testService;
...(Unterlassung)...
}
Obwohl es eine Möglichkeit gibt, Abhängigkeiten in statische Felder einzufügen, scheint es sich um eine eher aggressive Implementierung zu handeln (siehe Website als Referenz).
Sie können Abhängigkeiten in statische Felder einfügen
public class TestImplements implements TestInterface {
...(Unterlassung)...
static TestService testService;
@Autowired
public void setTestService(TestService service) {
testService = service;
}
...(Unterlassung)...
}
Schließlich muss der Setter nicht statisch sein, sodass er in einem Singleton-Muster implementiert werden muss.
Im Fall von "einer Klasse, die nur eine Methode implementiert, die immer nur einen festen Wert zurückgibt" wie der folgenden Klasse gibt es keinen Grund, sich die Mühe zu machen, sie in einem Singleton-Muster zu implementieren.
TestSingleton.java
public class TestSingleton {
private static final TestSingleton INSTANCE = new TestSingleton();
private TestSingleton() {}
public static TestSingleton getInstance() {
return INSTANCE;
}
public void sayHello() {
System.out.println("HelloWorld");
}
}
Bei einer Klasse wie der oben genannten können Sie sie wie zu Beginn erwähnt als Dienstprogrammklasse implementieren.
Dieses Mal habe ich mich gefragt, warum das Einzelton-Design "Nur eine Instanz kann erstellt werden" beim Erstellen einer Anwendung von Vorteil ist. Deshalb habe ich es untersucht. Der Grund, warum ich darüber nachgedacht habe, ist, dass, wie oben erwähnt, einige Singletons durch statische Methoden ersetzt werden können. *** *** Als ich das Singleton-Muster in dieser Studie verwenden wollte, dachte ich, ich müsste den Vorteil finden, weil es die einzige "*** Instanz ***" war.
Ich habe die Fälle aufgelistet, in denen es im Singleton-Muster implementiert werden sollte, und die Fälle, in denen es nicht in dem Bereich implementiert werden sollte, den ich mir vorstellen kann, aber ich werde es nach Bedarf hinzufügen, wenn ich in Zukunft etwas bemerke.
Referenz: Ich habe versucht, die Verwendung des Singleton-Musters zusammenzufassen Pros and Cons of Singleton. Erklären Sie sorgfältig Javas statische Methode! Lassen Sie uns gemeinsam Anwendungsbeispiele und -ideen lernen! Ich möchte statische Felder auf @Autowired ausrichten