Einzelnen Beitrag anzeigen

choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#4

Re: Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 10:14
Hallo Jelly,

es geht bei Diesem Ansatz im Wesentlichen um die Einhaltung von gültigen Invarianten, die eine logiklose Struktur, wie ein Record, nicht gewährleisten kann.
Darüber hinaus sollte die Schnittstelle (hier: zugänglich durch Properties) nichts über die konkrete Implementierung aussagen. Tatsächlich ist es nicht notwendig, dass eine Klasse eine Exemplarvariable für den Strukturierten Datentyp besitzt.

Im folgenden Beispiel beschreibe ich eine Klasse zur Darstellung eines Quadrats, die eine Eigenschaft Bounds besitzt. Sie gibt Auskünft über das kleinste umschließende Rechteck des dargestellten Quadrats. Selbstverständlich entspricht der Wert beim lesenden Zugriff immer dem Quadrat selbst, beim schreiben jedoch, sollte das Quadrat angepasst werden (Setzen der Quadratkantenlänge auf die kleiner der beiden Seiten des umschließenden Rechtecks). Es ist offensichtlich unnötig, die beiden Seitenlängen des Rechtecks zu speichern.
Folgende Besonderheit ist in diesem Beispiel vorgesehen: Sollten beide Längen des umschließenden Rechtecks negativ sein, werden die beiden Längen invertiert betrachtet (andernfalls macht das Bsp wg der Invarianten keinen Sinn )
Delphi-Quellcode:
type
  TMySquare = class
  private
    FLen: Double;
    function GetBounds: TPoint;
    procedure SetBounds(const AValue: TPoint);
  public
    property Bounds: TPoint
      read GetBounds
      write SetBounds;
  end;

function TMySqare.GetBounds: TPoint;
begin
  Result:= Point(FLen, FLen);
end;

procedure TMySquare.SetBounds(const AValue: TPoint);
begin
  with AValue do
  begin
    // only same sign and not null
    if Math.Sign(X)*Math.Sign(Y)<>1 then
      raise EInvalidArgument...
  
    Self.FLen:= Min(Abs(X), Abs(Y));
  end;
end;
An diesem Beispiel kann nun gezeigt werden, dass Zugriffe auf Felder des Records nicht eindeutig realisiert werden können:
Delphi-Quellcode:
mySquare.Bounds:= Point(10, 10); //FLen=10
mySquare.Bounds:= Point(-5, -2); //FLen=2
myPoint:= mySquare.Bounds; // myPoint=(2, 2)
mySquare.Bounds.X:= 1; // ???
Solltest Du hingegen einen Zugriff der Art
mySquare.Bounds.X:= myValue; benötigen, kannst Du dies durch eine Hilfsklasse, die von TPersistent abgeleitet wird, realisieren. Die Eigenschaft Font der Klasse TControl ist bspw so realisiert.
gruß, choose
  Mit Zitat antworten Zitat