Einzelnen Beitrag anzeigen

Schokohase
(Gast)

n/a Beiträge
 
#24

AW: TWinControl via TInterfacedObject via TInterfacedPersistent

  Alt 8. Jun 2018, 17:32
Hier mal ein Beispiel, wie so etwas gehen kann
Delphi-Quellcode:
type
  IFoo = interface ['{a895c8b4-db8c-40e9-a907-a0a4b01ff773}']
    procedure Bar;
  end;

  TFooImplementer = class(TObject,IFoo)
  private type
    IFooProxy = interface(IFoo) ['{20920822-173c-4e67-8f7b-8959366cc6b2}']
      procedure Release;
    end;
  strict private
    FProxy: IFooProxy;
    function GetFoo: IFoo;
  strict protected
    property Foo: IFoo read GetFoo implements IFoo;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Bar; // Die Methode macht die echte Arbeit
  end;

  TInterfacedFooProxy = class(TInterfacedObject, IFoo, TFooImplementer.IFooProxy)
  strict private
    FFoo: TFooImplementer;
  strict protected
    procedure Bar;
  strict protected
    procedure Release;
  public
    constructor Create(AFoo: TFooImplementer );
    destructor Destroy; override;
  end;

  { TFooImplementer }

procedure TFooImplementer.Bar;
begin
  WriteLn('*** TFooImplementer.Bar ***');
end;

constructor TFooImplementer.Create;
begin
  inherited Create;
  FProxy := TInterfacedFooProxy.Create(Self);
end;

destructor TFooImplementer.Destroy;
begin
  WriteLn('TFooImplementer.Destroy');
  FProxy.Release;
  inherited;
end;

function TFooImplementer.GetFoo: IFoo;
begin
  Result := FProxy;
end;

{ TInterfacedFooProxy }

procedure TInterfacedFooProxy.Bar;
begin
  WriteLn('TInterfacedFooProxy.Bar');
  if Assigned(FFoo)
  then
    FFoo.Bar;
end;

constructor TInterfacedFooProxy.Create(AFoo: TFooImplementer);
begin
  inherited Create;
  FFoo := AFoo;
end;

destructor TInterfacedFooProxy.Destroy;
begin
  WriteLn('TInterfacedFooProxy.Destroy');
  inherited;
end;

procedure TInterfacedFooProxy.Release;
begin
  FFoo := nil;
end;
und ein kleiner Test dazu
Delphi-Quellcode:
procedure Main;
var
  fooObj : TFooImplementer;
  fooIntf: IFoo;
begin
  fooObj := TFooImplementer.Create;
  try
    fooIntf := fooObj;
    // direkter Aufruf
    fooObj.Bar;
    // indirekter Aufruf durch IFoo
    fooIntf.Bar;
  finally
    fooObj.Free;
    fooObj := nil;
  end;

  // indirekter Aufruf durch IFoo, der aber ins Leere geht
  fooIntf.Bar;
  fooIntf := nil;
end;
und was dabei herauskommt
Code:
*** TFooImplementer.Bar ***
TInterfacedFooProxy.Bar
*** TFooImplementer.Bar ***
TFooImplementer.Destroy
TInterfacedFooProxy.Bar
TInterfacedFooProxy.Destroy
  Mit Zitat antworten Zitat