Einzelnen Beitrag anzeigen

Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Daten zwischen Instanzen austauschen

  Alt 21. Feb 2006, 23:52
ein kleines Beispiel (mit 2 varianten wies geht)
TExample stellt deine Klasse dar wo jede Instanz die gleichen Daten haben soll.

property Msg1 ist die erste Variante. Die Instanz von TExample behält sich diese Message nirgends. Wird Msg1 gesetzt wird dieser wert beim TExampleLeader verändert. Und wenn diese Message abgefragt wird so wird diese vom Globalen TExampleLeader abgefragt.

Variante2 ist etwas komplizierter ist aber manchmal recht nützlich wenn die instanzen mitbekommen müssen das sich was geändert hat (um sich zum Beispiel neu zu malen (was in diesem Beispiel aber nicth der fall ist)).
Das Property Msg2 wird in der Instanz von TExample gehalten. Im Constructor wird jedoch von der Globalen Instanz GExampleLeader der aktuelle Wert abgefragt. Zusätzlich trägt sich die Instanz von TExample beim TExampleLeader ein damit dieser später über Änderungen benachrichtigen kann (im Destroy von TExample trägt sich die Instanz von TExample logicher Weise auch wieder beim globalen TExampleLeader aus).
Wird also Msg2 abgefragt wird einfach der Wert aus dem Private gelesen.
Wird jedoch Msg2 gesetzt so wird Msg2 beim globalen TExampleLeader gesetzt und dieser ändert dies bei allen Clients (im Beispiel greift der TExampleLeader auf ein Private-Property zu, es ist aber natürlich auch möglich das eine Methode aufgerufen wird die zum Beispiel ein neu zeichnen erzwingt etc.).

Da die globale Instanz von TExampleLeader (GMasterLeader) unter Implementation declariert wird ist diese Instanz außerhalb der Unit nicht sichtbar.
Delphi-Quellcode:
unit uexample;

interface

uses
  classes;

type
  TExample = class(TObject)
  private
    fMsg2: String;
    function FGetMessage1: String;
    procedure FSetMessage1(AMsg: String);
    procedure FSetMessage2(AMsg: String);
  public
    constructor Create;
    destructor Destroy; override;

    //Msg1 wird direkt von Leader abgefragt und gesetzt
    property Msg1: String read FGetMessage1 write FSetMessage1;
    //Msg2 wird intern behalten und nur beim leader gesetzt (dieser änderts dann bei den instanzen)
    property Msg2: String read fMsg2 write FSetMessage2;
  end;

  TExampleLeader = class(TObject)
  private
    fClients: TList;
    fMsg1: String;
    fMsg2: String;
    procedure FSetMsg2(AMsg: String);
  public
    constructor Create;
    destructor Destroy; override;

    property Msg1: String read fMsg1 write fMsg1;
    property Msg2: String read fMsg2 write FSetMsg2;

    procedure ClientAdd(AClient: TExample);
    procedure ClientRemove(AClient: TExample);
  end;

implementation

var
  GMasterLeader: TExampleLeader;

constructor TExampleLeader.Create;
begin
  fMsg1 := 'StdMessage1';
  fMsg2 := 'StdMessage2';
  fClients := TList.Create;
end;

destructor TExampleLeader.Destroy;
var LCount: Integer;
begin
  for LCount := fClients.Count - 1 downto 0 do
    TObject(fClients.Items[LCount]).Free;
  fClients.Free;
end;

procedure TExampleLeader.ClientAdd(AClient: TExample);
begin
  if fClients.IndexOf(AClient) < 0 then
    fClients.Add(AClient);
end;

procedure TExampleLeader.ClientRemove(AClient: TExample);
begin
  fClients.Remove(AClient);
end;

procedure TExampleLeader.FSetMsg2(AMsg: String);
var LCount: Integer;
begin
  fMsg2 := AMsg;
  for LCount := 0 to fClients.Count - 1 do
    TExample(fClients.Items[LCount]).fMsg2 := fMsg2;
end;

{==============================================================================}

constructor TExample.Create;
begin
  inherited Create;
  GMasterLeader.ClientAdd(Self);
  fMsg2 := GMasterLeader.Msg2;
end;

destructor TExample.Destroy;
begin
  GMasterLeader.ClientRemove(Self);
  inherited Destroy;
end;

function TExample.FGetMessage1: String;
begin
  result := GMasterLeader.Msg1;
end;

procedure TExample.FSetMessage1(AMsg: String);
begin
  GMasterLeader.Msg1 := AMsg;
end;

procedure TExample.FSetMessage2(AMsg: String);
begin
  GMasterLeader.Msg2 := AMsg;
end;

initialization
  GMasterLeader := TExampleLeader.Create;

finalization
  GMasterLeader.Free;


end.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat