Avatar von Ichthyostega
  • Ichthyostega

mehr als 1000 Beiträge seit 28.06.2005

Re: Warum nicht Singleton?

Ichthyostega schrieb am 09.04.2018 20:57:

Bei dem Stichwort "Singleton" gleich "böhse böhse" zu schreien, ist doch wohl ehr ein Kennzeichen von Möchtegern-Programmierern, die tatsächlich keinen Plan haben.

jensa (1) schrieb am 16.04.2018 14:26:

Netter Trollversuch. Aber ich habe leider schon viel Code gesehen, in dem Singletons fuer alles mögliche verwendet wurden, weil sie ja so schoen praktisch sind. Und man spart auch noch Parameter. Und kann von überall auf alle Objekte zugreifen. Und weil es ja ein objekt-orientiertes Pattern ist, ist es auch keine globale Variable...

Soll das jetzt ein Argument sein, oder willst Du Dich nur wichtig machen?

Ich nehm es mal als Argument ernst.
Korrekt. Wenn ein Singleton objektorientiert programmiert ist, dann ist es richtig eingekapselt, hat einen sauberen Kontrakt und der State bleibt drinnen und kann nicht jenseits des Kontraktes manipuliert werden.

Wenn dagegen ein Singleton nur eine Sammlung von public-Feldern ist, dann ist das das Problem, und nicht das Singleton-Pattern. Anstatt FUD über die Objektorientierung zu verbreiten, sollten die Helden vielleicht erst mal richtig programmieren lernen.

Zweitens: es ist Unfug, immer alles über Parameter durchzureichen. Verletzt die Separation of Concerns, und macht den Code unwartbar und schwer wiederverwendbar. Jeder Parameter sollte einen direkten Bezug zu dem Sinn des Dienstes haben. Gewisse Querschnittbelange gehören als Implementierungsdetail ausgeklammert.

Ichthyostega schrieb am 09.04.2018 20:57:

Und übrigens: wie implementiert ein DI-Container die Initialisierung der Objekte, die er injiziert?

jensa (1) schrieb am 16.04.2018 14:26:

Naja, DI wird wahrscheinlich nicht meinen Code modifizieren, also wird es keine statische Funktion in meiner Klasse geben, und die Konstruktoren koennen auch nicht private werden.

von welcher Seite redest Du jetzt? Bist Du der Service-Implementierer (d.h. schreibst Du das Singleton bzw den Service), oder bist du der Service-Konsument (also verwendest das Interface des Singletons)?

....also wird es keine statische Funktion in meiner Klasse geben, und die Konstruktoren koennen auch nicht private werden.
Zumindest in C++ wird das auch nochmal extra schwierig.

schon mal was von friend gehört? Oder von package acces in Java o.ä.?
Genau für solche Zwecke sind diese Konstrukte gedacht, sinnvoll und sauber.

Das ist auch eines der grössten Probleme von Singleton: Die Klasse selbst schreibt vor, dass es im System genau eine Instanz gibt.

So ein Quatsch.
Nicht die Klasse schreibt das vor, sondern die Factory-Funktion. Die beim Singleton eben im Scope der Klasse sitzt und über den Typnamen adressiert wird. Das ist auch angemessen bei einem überschaubaren System und in jedem Fall besser, als immer gleich mit einem Monster von DI-Container daherzukommen.

Wenn das System dann wächst, ist es ein Leichtes, die eingebettete Factory-Funktion an eine zentrale Factory delegieren zu lassen. Erst bei einem sehr viel größeren System lohnt es sich, einen Application-Manager zu bauen, der alle Komponenten erstellt und verdrahtet.

Der enscheidende Knackpunkt bei allen diesen Pattern ist doch, daß sie ineinander greifen. Sie bilden eine Pattern-Sprache. Singleton verwendet Factory. Factory kann wiederum Delegate und Dekorator verwenden u.s.w. Über diese Verbindungen zwischen den Pattern kannst Du Dich bewegen, und das System dem sich ändernden Bedarf anpassen.

Die Klasse selbst schreibt vor, dass es im System genau eine Instanz gibt.
Warum sollte die Klasse das tun, und warum sollte sie es überhaupt interessieren? Warum sollte Code, der die Klasse verwendet wissen, dass es genau ein Exemplar gibt?

Noch so ein wischi-waschi-Argument.

Bitte erst mal die Begriffe sauber gebrauchen!
Das Interface / der Kontrakt schreibt nicht vor, daß es im System genau eine Instanz gibt.
Sondern es schreibt vor:
Du (der Client) darf von mir keine Instanzen erzeugen (Konstruktor ist nicht zugreifbar),
sondern hat stattdessen eine Factory-Funktion zu verwenden. Und der Zugang zu dieser Factory-Funktion ist rein an den Namen der Schnittstelle (Klassennamen) gebunden, die der Client auch zu verwenden hat.

DBConnection::getInstance()

Sauber, klar und auf den Punkt.

Das Singleton-Pattern ist eine knappe, prägnante und präzise Weise, genau das auszudrücken, und mit einfachsten Mitteln zu implementieren. Nicht mehr und nicht weniger.

Wenn Du programmieren willst, mußt Du erst mal lernen, logisch-präzise zu argumentieren. Und die Ebenen sauber zu trennen.

Das eine ist das Interface, der Kontrakt. Das ist die Ansage, die für den Client-Code gilt. Das andere ist die interne Sicht, die Implementierung.

Und ja, es gibt sehr viele gute Gründe, warum eine Implementierung darauf bestehen muß, daß sie die einzige Stelle im System ist, die etwas bestimmtes macht. Beispielsweise DB-Verbindungen in einem Connection-Pool verwalten. Oder Handles für irgend einen aufwendigen Service ausgeben und verwalten.

Bewerten
- +