Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Lazy Initialization im Type? (https://www.delphipraxis.net/184013-lazy-initialization-im-type.html)

Thomas_K 19. Feb 2015 10:45

Lazy Initialization im Type?
 
Ich bin in Codefragmente mehrfach auf folgendes Pattern gestoßen:
Code:
unit UnitUnknownLazyInitializationPattern;

interface

uses
  UnknownInterfaces, MoreUnknownUnits;

type
  TFoo = class
  private
    FMyUnknownObject: UnknownObject; // Type without the letter "T"?
    function GetMyUnknownObject: IUnknownObject;
  public
    property MyUnknowObject: IUnknownnObject read GetMyUnknownObject;
  end;

implementation

{ TFoo }

function TFoo.GetMyUnknownObject: IUnknownObject;
begin
  Result := FMyUnknownObject;
end;

end.
Und genutzt wird es so.
Code:
var
  Foo: TFoo;
begin
  Foo := TFoo.create;
  try
    Foo.MyUnknownObject.UnknownProcedure; // crash here, because UnknowProject still is nil
  finally
    Foo.free;
  end;
end;
Der Type von UnknowObject instanziiert Objekte bei Methoden Zugriffe selbst und kümmert sich auch um deren Freigabe(InterfacedObject, Smartpointer, ?).

Wie müsste die Implementierung von Type „UnknownObject“ aussehen, um diesen Effekt zu bekommen?

TiGü 19. Feb 2015 11:49

AW: Lazy Initialization im Type?
 
Was denn für Codefragmente?

Ich kann mir folgende Lösung vorstellen:
Delphi-Quellcode:
type
  TFoo = class
  private
    FMyUnknownObject: IUnknownObject;
...
Delphi-Quellcode:
function TFoo.GetMyUnknownObject: IUnknownObject;
begin
  if not Assigned(FMyUnknownObject) then
    FMyUnknownObject := TMyUnknownObject.Create;

  Result := FMyUnknownObject;
end;

Stevie 19. Feb 2015 11:56

AW: Lazy Initialization im Type?
 
Delphi-Quellcode:
type
  UnknownObject = record
  private
    fInstance: IUnknownObject;
    procedure EnsureInstance;
  public
    class operator Implicit(const value: UnknownObject): IUnknownObject;
    procedure UnknownObject;
  end;

procedure UnknownObject.EnsureInstance;
begin
  if not Assigned(fInstance) then
    fInstance := TUnknownObject.Create;
end;

class operator UnknownObject.Implicit(
  const value: UnknownObject): IUnknownObject;
begin
  value.EnsureInstance;
  Result := value.fInstance;
end;

procedure UnknownObject.UnknownObject;
begin
  EnsureInstance;
  fInstance.UnknownObject
end;

Thomas_K 19. Feb 2015 21:08

AW: Lazy Initialization im Type?
 
Zitat:

Was denn für Codefragmente?
http://www.delphipraxis.net/183799-m...pertychanged#2 Einfach mal dort auf der Seite mit der Browser-Text-Suche nach "GetPropertyChanged" Ausschau halten.

Dort gibt es auch eine Sache die ich erst eben bemerkt habe, innerhalb des Objektes wird auch noch direkt auf die Feldvariabel zu gegriffen. FPropertyChanged.Invoke(..), was ich in dem unknown Beispiel nicht berücksichtig hatte.

@Stevie danke, für die Implementierung, wieder was gelernt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:32 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