Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Ist das ein Pattern? (https://www.delphipraxis.net/167398-ist-das-ein-pattern.html)

Jumpy 28. Mär 2012 00:03

Ist das ein Pattern?
 
Hallo,

ich habe neulich in einem Programm das folgende Konzept entdeckt, durch das (nur bei Bedarf) eine Instanz einer anderen Klasse erzeugt wird, die dann innerhalb der erzeugenden Klasse überall verfügbar ist. Ist das ein Pattern und wenn ja, wie nennt man das. Und ist der Einsatz sinnvoll?

Delphi-Quellcode:
Type IrgendeineKlasse = class
  private
    fAndereKlasse:TAndereKlasse
    function getAndereKlasse:TAndereKlasse;
  public
    property AndereKlasse:TAndereKlasse read getAndereKlasse;
  end;
Im Implementaionsteil dann:

Delphi-Quellcode:
TIrgendeineKlasse.getAndereKlasse:TAndereKlasse;
begin
  if fAndereKlasse=nil then
    fAndereKlasse:=TAndereKlasse.Create;
  Result:=fAndereKlasse;
end;
Im Destruktor der Klasse wird die andere Klasse dann ggf. freigegeben mit:
Delphi-Quellcode:
if fAndereKlasse<>nil then
  fAndereKlasse.Free;
Die andere Klasse kann dann in der IrgendeineKlasse überall aufgerufen werden mit:
Delphi-Quellcode:
AndereKlasse.Machwas

himitsu 28. Mär 2012 00:36

AW: Ist das ein Pattern?
 
Jupp, ist ein ganz normales und oftgenutztes Verhalten, auch wenn es etwas überdimensioniert ist.
Wird auch gerne für Bei Google suchenSingletons verwendet. (wenn man es noch etwas aufmotzt)

Wozu soll man etwas schon erstellen, obwohl es jetzt (zur Erstellungszeit) noch nicht oder überhaupt jemals verwendet wird?

z.B. das Free, es prüft selber auch nochmal auf NIL.
Delphi-Quellcode:
function TIrgendeineKlasse.getAndereKlasse: TAndereKlasse;
begin
  if not Assinged(fAndereKlasse) then
    fAndereKlasse := TAndereKlasse.Create;
  Result := fAndereKlasse;
end;

destructor TIrgendeineKlasse.Destroy;
begin
  fAndereKlasse.Free;
  inherited;
end;
Viele erstellen ihre Programme so, daß alle dutzende/hunderte Fenster gleich beim Programmstart unsichtbar erstellt werden, auch wenn viele der Fenster garnicht oder nur selten/kurz verwendet werden.
= unnötige Resourcenverschwendung

Valle 28. Mär 2012 06:21

AW: Ist das ein Pattern?
 
Ich kann es mir jetzt aber nicht verkneifen
zu sagen, dass das kein Singleton ist!

Liebe Grüße,
Valentin

mz23 28. Mär 2012 06:35

AW: Ist das ein Pattern?
 
Zitat:

Zitat von Valle (Beitrag 1159013)
Ich kann es mir jetzt aber nicht verkneifen
zu sagen, dass das kein Singleton ist!

Liebe Grüße,
Valentin

Mal sehen, was de.Wikipedia dazu sagt:

http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

Schöne Grüße aus Nürnberg,
Manfred

Sir Rufo 28. Mär 2012 06:44

AW: Ist das ein Pattern?
 
Zitat:

Zitat von mz23 (Beitrag 1159014)
Zitat:

Zitat von Valle (Beitrag 1159013)
Ich kann es mir jetzt aber nicht verkneifen
zu sagen, dass das kein Singleton ist!

Liebe Grüße,
Valentin

Mal sehen, was de.Wikipedia dazu sagt:

http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

Schöne Grüße aus Nürnberg,
Manfred

Jetzt frage ich mich aber was soll das?

Popov fragt eigentlich nach Lazy Creation
Himitsu verweist darauf, dass das (Lazy Creation) gerne bei Singletons eingesetzt wird
Valle weist nochmals explizit darauf hin, dass es (Popovs Klasse) kein Singleton ist.

Und die Wikipedia sagt da auch nicht anderes ... (wär ja sonst auch falsch)

s.h.a.r.k 28. Mär 2012 06:50

AW: Ist das ein Pattern?
 
Muss das Sir Rufo voll und ganz Recht geben ;) Ein richtiges Design Pattern ist es nicht, eher ein Konzept, oder? Kenne das auch unter dem Begriff Lazy Load/Lazy Creation.

Aber das obige Codebeispiel finde ich eher etwas ungeschickt, da der Zugriff auf die Variable fAndereKlasse noch gekapselt werden sollte. Programmierer müssen sonst ja wissen, dass man auf die Get-Methode zugreifen muss und nicht auf fAndereKlasse zugreifen darf. Aber das nur so am Rande :stupid:

vagtler 28. Mär 2012 07:11

AW: Ist das ein Pattern?
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1159017)
[...] Aber das obige Codebeispiel finde ich eher etwas ungeschickt, da der Zugriff auf die Variable fAndereKlasse noch gekapselt werden sollte. [...]

Wie denn noch als über das Property?
Code:
public
    property AndereKlasse:TAndereKlasse read getAndereKlasse;
  end;

Stevie 28. Mär 2012 07:21

AW: Ist das ein Pattern?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1159016)
Popov fragt eigentlich nach Lazy Creation

Lazy initialization um genau zu sein 8-)

himitsu 28. Mär 2012 08:15

AW: Ist das ein Pattern?
 
Ja, für sich alleine gesehn ist es kein Singleton, aber

- komisch, es sieht vom Code genau wie die Wiki-Beispiele aus.
- abgesehn davon, daß es dort noch in einer statischen Klassenmethode versteckt ist, mit einer globalen Variable.
(wenn man implizit davon ausgeht, daß es von IrgendeineKlasse nur maximal eine Instanz gibt, dann ist es ein Singleton)
- und zusätzlich wird oftmals noch (was in den Wikicodes nicht zu sehn ist, das externe Freigeben der Instanz verhindert, wenn es sich um ein Singleton handelt.

Also nein, es ist Keines, aber mit ein paar Erweiterungen wird es Eines
und nix Anderes hab'sch doch gesagt?

Stevie 28. Mär 2012 08:22

AW: Ist das ein Pattern?
 
Zitat:

Zitat von himitsu (Beitrag 1159023)
Also nein, es ist Keines, aber mit ein paar Erweiterungen wird es Eines
und nix Anderes hab'sch doch gesagt?

Dir ist wohl entgangen, dass es sich hier um eine Aggregation von IrgendeineKlasse und TAndereKlasse handelt oder?

himitsu 28. Mär 2012 08:50

AW: Ist das ein Pattern?
 
Und was macht die öffentliche Funktion oftmals, bei den meisten Singletonpattern?
Die aggregiert einverleibt sich eine Klasseninstanz.

Wenn ich mir jetzt das auf'm Wiki nehm,
Zitat:

Zitat von http://en.wikipedia.org/wiki/Lazy_initialization
Code:
    private static $types = array();
 
    public static function getFruit($type) {
        // Lazy initialization takes place here
        if (!array_key_exists($type, self::$types)) {
            return self::$types[$type] = new Fruit($type);
        }
 
        return self::$types[$type];
    }

das Array und Static wegmach,
Code:
    private $types;
 
    public function getFruit {
        // Lazy initialization takes place here
        if (!self::$types) {
            return self::$types = new Fruit;
        }
 
        return self::$types;
    }
dann komm ich auf diesen Code.
Zitat:

Zitat von Jumpy (Beitrag 1159010)
Delphi-Quellcode:
private fAndereKlasse:TAndereKlasse

TIrgendeineKlasse.getAndereKlasse:TAndereKlasse;
begin
  if fAndereKlasse=nil then
    fAndereKlasse:=TAndereKlasse.Create;
  Result:=fAndereKlasse;
end;

Sehr eigenartig. :gruebel:

Codewalker 28. Mär 2012 08:54

AW: Ist das ein Pattern?
 
Zitat:

Zitat von himitsu (Beitrag 1159027)
und Static wegmach

Möhp! Genau das ist ja der Trick beim Singleton, dass es nur eine Instanz geben darf. Wenn du das static wegmachst, gibt es für jede Instanz der Klasse nur eine Instanz (und das ist was ganz anderes)

himitsu 28. Mär 2012 09:01

AW: Ist das ein Pattern?
 
In Delphi muß es nicht "class static" sein, es reicht schon "class", oder eine ordinäre Prozedur.
Wenn TIrgendeineKlasse die einzige vorhandene Instanz wäre, dann ist AndereKlasse implizit ebenfalls Alleine (ein Singleton).
Und ich hab nie behauptet das währe schon ein Singleton. (noch'n bissl aufmotzen und fert'sch)

Der Billigprogrammierer pappt diesen Code in seine TForm1, und schon hat er ein Singleton.
(solange er nicht auf die Idee kommt TForm1 mehrmals zu erzeugen, aber ist dann meist nur ein Bug und keine Absicht :stupid: )



Halten wir es also fest:
- es ist noch kein Singleton-Pattern (bissl erweitert wird es vielleicht mal Eines)
- es ist noch kein Lazy-Pattern (bissl erweitert wird es vielleicht mal Eines)
- es ist was Anderes
Zitat:

Wenn du das static wegmachst, gibt es für jede Instanz der Klasse nur eine Instanz (und das ist was ganz anderes)

Iwo Asnet 28. Mär 2012 10:03

AW: Ist das ein Pattern?
 
Noch mehr Senf:

Früher, als es noch kein OOP gab, hieß das "Fetch on Demand".

Jumpy 28. Mär 2012 10:04

AW: Ist das ein Pattern?
 
1. Ich bin nicht Popov. Aber das sei euch verziehen, Sir.

2. Danke für die Infos.

Ich hab als ich die Frage stellte im Stillen bei mir gedacht, ob das in Richtung Singelton geht, wollte die Frage aber offen halten. Hab somit gelernt, das ein Singelton doch noch etwas mehr ist und den schönen Begriff Lazy Load/Creation/Initialisation neu gelernt, bzw. das Konzept dahinter.

Dazu noch 'ne Frage:
if fKlasse<>nil then... vs. if Assigned(fKlasse) then...
Was ist genau da der Unterschied, ich vermute mal, das letzteres besser ist, wenn ich auch nicht weiß, warum?

Danke,
Jumpy

DeddyH 28. Mär 2012 10:07

AW: Ist das ein Pattern?
 
Delphi-Referenz durchsuchenSystem.Assigned, da steht' s ;)

Stevie 28. Mär 2012 11:00

AW: Ist das ein Pattern?
 
Zitat:

Zitat von Jumpy (Beitrag 1159043)
Was ist genau da der Unterschied, ich vermute mal, das letzteres besser ist, wenn ich auch nicht weiß, warum?

Gibt keinen unterschied, Assigned ist eine built-in inline Function (manche sagen dazu Compilermagic, weil man den Source davon nicht in der System.pas sieht) und erzeugt denselben assembler Code wie ein Vergleich auf nil.

Zitat:

Zitat von Delphi Dokumentation
Der Aufruf Assigned(P) entspricht bei einer Zeigervariablen dem Test P <> nil und bei einer Prozedurvariablen dem Test @P <> nil.

Assigned kann allerdings nicht in allen Fällen verwendet werden - zum Beispiel bei dem Ergebnis einer Funktion, da man dieses nicht über einen var Parameter weitergeben kann (E2036 Variable required.)

Jumpy 28. Mär 2012 16:11

AW: Ist das ein Pattern?
 
OK, danke.
Sorry für das späte Antworten, musste noch schnell mein FIAE Abschlussarbeit, der Grund meiner Fragen in den letzten Wochen, fertig dokumentieren und zur IHK hochladen. Mal sehn was es wird, hauptsache erstmal fertig.

DeddyH 28. Mär 2012 16:58

AW: Ist das ein Pattern?
 
Dann drücken wir doch mal die Daumen :thumb:

himitsu 28. Mär 2012 18:25

AW: Ist das ein Pattern?
 
Wofür Assigned einen Vorteil bietet.
> Methodenzeiger

Diese bestehen intern aus 2 Zeigern, also ist ein direktes Prüfen auf nil nicht möglich.
Und wöllte man die internen Zeiger prüfen, dann müßte man sich den Methodenzeiger erstmal in einen lesbaren Typen casten, welcher Zugriff auf die beiden Felder bietet.
> Datenzeiger (Objektinstanz) und Codezeiger (Zeiger auf die Methode/Prozedur)

Stevie 28. Mär 2012 19:13

AW: Ist das ein Pattern?
 
Zitat:

Zitat von himitsu (Beitrag 1159126)
Diese bestehen intern aus 2 Zeigern, also ist ein direktes Prüfen auf nil nicht möglich.

Falsch, lies mal, was ich oben ausm docwiki zitiert habe.

Assigned überprüft nicht, ob irgendwelcher Müll in dem Methodenzeiger steht, sondern nur ob er ungleich nil ist.

himitsu 28. Mär 2012 19:46

AW: Ist das ein Pattern?
 
Zitat:

Zitat von Stevie (Beitrag 1159134)
Assigned überprüft nicht, ob irgendwelcher Müll in dem Methodenzeiger steht, sondern nur ob er ungleich nil ist.

Hab ich was Anderes behauptet?

Delphi-Quellcode:
var
  X: TNotifyEvent;

if Assigned(X) then
  Beep;

if (TMethod(X).Code <> nil) or (TMethod(X).Data <> nil) then
  Beep;

Stevie 28. Mär 2012 20:03

AW: Ist das ein Pattern?
 
Ich fass nochmal zusammen:

Zitat:

Zitat von Delphi Dokumentation
Der Aufruf Assigned(P) entspricht bei einer Zeigervariablen dem Test P <> nil und bei einer Prozedurvariablen dem Test @P <> nil.

Zitat:

Zitat von himitsu (Beitrag 1159126)
Wofür Assigned einen Vorteil bietet.
> Methodenzeiger

Diese bestehen intern aus 2 Zeigern, also ist ein direktes Prüfen auf nil nicht möglich.
Und wöllte man die internen Zeiger prüfen, dann müßte man sich den Methodenzeiger erstmal in einen lesbaren Typen casten, welcher Zugriff auf die beiden Felder bietet.
> Datenzeiger (Objektinstanz) und Codezeiger (Zeiger auf die Methode/Prozedur)


Delphi-Quellcode:
if @x <> nil then
  Beep

himitsu 28. Mär 2012 22:31

AW: Ist das ein Pattern?
 
Hab grade was Neues gelernt. :shock:

Delphi-Quellcode:
  X := nil;
  if @@X <> nil then
    Beep;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz