AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Frage zu OOP - zwei Listen

Ein Thema von benwen · begonnen am 17. Sep 2006 · letzter Beitrag vom 21. Sep 2006
Antwort Antwort
benwen

Registriert seit: 11. Sep 2006
17 Beiträge
 
Delphi 7 Enterprise
 
#1

Frage zu OOP - zwei Listen

  Alt 17. Sep 2006, 20:43
Hallo alle zusammen!

In meinem Programm verwende ich zwei Listen:
- die erste Liste enhält die Grunddaten -> TElementList;
- die zweite Liste enthält die daraus gebildeten Graphikkomponenten (z.N. TNode, TBorder) -> TGraphicObjectList;

Während des Programmablaufs wird aus den Grunddaten ein Knoten-Kanten-Modell gebildet und gezeichnet. Zur Erklärung kurz die Struktur der verwendeten Klassen:

Delphi-Quellcode:

  TElement = class
    Color:TColor;
    Show: boolean;
    top: integer;
    layerID : integer;
    pos, absPos, length: real;
    elemID, elemType: string;
  public
     (...)
  end;

  TElementList = class(TList)
  private
    function GetElement(index: integer): TElement;
    (...)
  public
    (...)
    property Items[index: integer]: TElement Read GetElement;
  end;

TGraphicObject = class(TElement)
  S: TElement;
  Width: integer;
  Height: integer;
  Left: integer;
  TempFillColor: TCOlor;
  BorderPolygon: TBorderPolygon;
  BorderCircle: TRect;
  Marked: boolean;
  FillColor: TColor;
  Angle: extended;
  GraphicType: TGraphicType;
  BorderRect: TRect;
  //(und weitere Grafieigenschaften)
  procedure Paint(RefCanvas: TCanvas; ClipRect: TRect; BackgroundColor: TColor);
public
  procedure GetData(Source: TElement); virtual;
end;

TNode = class(TGraphicObject)
  nodeType: TNodeType;
  nodeID: string;
  (...)
public
  procedure GetData(Source: TElement); override;
  constructor Create(NType: TNodeType);
  procedure Paint(RefCanvas: TCanvas; ClipRect: TRect; BackgroundColor: TColor);
end;

TBorder = class(TGraphicObject)
  startNode, endNode: TNode;
  length: real;
  borderType: TBorderType;
public
  constructor Create(StartNode, EndNode: TNode; BorderType: TBorderType);
  procedure Paint(RefCanvas: TCanvas; ClipRect: TRect; BackgroundColor: TColor);
  procedure GetData(Source: TElement); override;
end;

(...u.a. Graphikobjecte...)

TGraphicObjectList = class(TList)
  FSource: TElementList;
public
  property Items[index: integer]: TGraphicObject Read GetGraphicObject;
  procedure Getdata(Source: TElementList);
  procedure SetData;
  procedure Paint(RefCanvas: TCanvas; BackgroundColor: TColor; ClipRect: TRect);
end;

implementation

procedure TGraphicObject.GetData(Source: TElement);
begin
  self.S := Source;
  //genau um diese Grundeigenschaften geht es. kann ich diese nicht als Verweis/Zeiger auf das Element in der ElementList verwenden??)
  pos := Source.Pos;
  absPos := Source.AbsPos;
  elemID := Source.elemID;
  elemType := Source.elemType;
  trackID := Source.trackID;
  long := Source.long;
  lat := Source.lat;
  alt := Source.alt;
  length := Source.length;
  dir := Source.dir;
  Show := Source.Show;
  layerID := Source.layerID;
  top := Source.top;

end;

constructor TNode.Create(NType: TNodeType);
begin
  GraphicType := gtCircle;
  NodeType := NType;
 // FillColor := NColor;
  //TempFillColor := NColor;
  Width := 15;
  Height := Width;
  Marked := False;
end;

procedure TNode.GetData(Source: TElement);
begin
  inherited;
  nodeID := 'blabla';
end;

(...das ähnliche nochmal mit TBorder usw...)

procedure TGraphicObjectList.Getdata(Source: TElementList);
var
  i: integer;
begin
  Clear;
  FSource := Source;
  for I := 0 to Source.Count - 1 do
    begin
      if Items[i].elemType = 'startthen
      begin
        Add(TNode.Create(ntStart));
        (Items[Count-1] as TNode).GetData(Source.Items[i]);
      end;
      (das gleiche mit TBorder u.a.)
    end;
end;
Ich hoffe das Grundprinzip ist mit diesem kleinen Ausschnittes deutlich geworden. Nun habe ich ein Problem damit, dass die Eigenschaften von TElement in beiden Listen "gespeichert" werden. Ich möchte aber bei der Erstellung der Grafikobjekte (TGraphicObject) nur auf die Daten der TElementList beziehen...wie kann ich das am besten realisieren?
Danke schonmal für Eure Antworten!!
  Mit Zitat antworten Zitat
bttb930

Registriert seit: 6. Okt 2003
372 Beiträge
 
#2

Re: Frage zu OOP - zwei Listen

  Alt 17. Sep 2006, 22:34
Du musst die Verantwortung klären: Welche Klasse ist Besitzer von TElement und welche Klasse verweist nur darauf?

Ich würde vermutlich TElementList zum Besitzer von TElement-Instanzen küren. TGraphicObject enthält dann nur Zeiger auf diese Elemente, ist aber nicht Besitzer.

Das heißt: TGraphicObject gibt ein TElement nicht automatisch im Destruktor frei.

Alternativ könnte TGraphicObject der Besitzer sein, dann wäre TElementList aber evtl. überflüssig (und stattdessen TGraphicObjectList gefragt).

By the way: Sieh Dir vielleicht mal Bücher zum Thema Entwurfsmuster (Design Patterns) an. Es gibt für derartige Probleme schon fertige design patterns, die man nur anwenden muss. Könnte dir - in der Zukunft - das eine oder andere Problem ersparen. Jedenfalls sieht die Klasse TGraphicObject sehr gut aus (weit über dem Niveau dessen was man hier sonst so sieht), sieht aber trotzdem nicht sehr zukunftsfähig aus. Du mischst zuviel, den TGraphicType könntest Du entfernen und stattdessen mit einer abstrakten Basisklasse und Vererbung arbeiten. Und es könnte auch sein, dass die Paint-Methode besser nicht in der Klasse selbst angesiedelt ist, sondern dass Du externe Painter baust. So könntest Du verschiedene Painter für verschiedene Answendungsgebiete bauen.

Hört sich alles kompliziert an, ist am Anfang auch nicht so leicht - schau mal ob Entwurfsmuster was für dich sind und wenn ja, dann lerne sie langsam und versuche an solchen Beispielen durchzusteigen.
  Mit Zitat antworten Zitat
benwen

Registriert seit: 11. Sep 2006
17 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Frage zu OOP - zwei Listen

  Alt 17. Sep 2006, 23:22
Danke für deine Antwort!

Ich werde mich in Zukunft mit den Design Patterns auseinandersetzen, sodass ich solche Probleme effektiver lösen kann.

Zu dem Problem an sich nochmal:

Wie du richtig vermutet hast: TElementList ist der Besitzer der Elemente. Die TGraphicObjectList beinhaltet die Grafikobjekte, wobei sich die Grundeigenschaften (von TELement) bei beiden Listen, bzw. deren Einträgen, decken. Irgendwie erscheint es mir nicht der richtige Weg zu sein und da bräuchte ich einen kleinen Denkanstoß, wie es anders zu lösen geht. Wie kann ich in TGraphicObject.GetData() erreichen, dass nur die Adressen abgespeichert werden? ODer sollte ich es ganz anders strukturieren? ICh würde mich gern noch intensiver damit befassen (siehe Design Patterns), da das Projekt jedoch bald fertig sein muss, kann ich mich erst danach mit der Verbesserung des Programmierstils befassen (klingt unbefriedigend, ist es auch). Also bitte einen kleinen Tipp, wie ich das mit den Zeigern schaffe in der Prozedur TGraphicObject.GetData();??? ODer ein ganz anderer Weg?
(Die Paint-Methode ist mir übrigens bei TGraphicObject nur reingerutscht, die hat dort nichts zu suchen.)
  Mit Zitat antworten Zitat
bttb930

Registriert seit: 6. Okt 2003
372 Beiträge
 
#4

Re: Frage zu OOP - zwei Listen

  Alt 18. Sep 2006, 07:49
Na, du lässt es einfach bei "self.s := Source" und lässt den Rest weg. TGraphicObject braucht keine Eigenschaften die schon in TElement stehen - die kann es sich ja von TElement holen. Also etwa

Delphi-Quellcode:
type
  TGraphicObject = class
  private
    Element: TElement;
    function GetColor: TColor;
  ...
  public
  ...
    property Color: TColor read GetColor;
  end;

...

function TGraphicObject.GetColor: TColor;
begin
  if Assigned(Element) then
    Result := Element.Color
  else
    ...;
end;
Und Thema Design Patterns: Die lernt man nicht "mal eben", mach also unbedingt weiter wie bisher aber befass dich vielleicht mal in der Zukunft damit.
  Mit Zitat antworten Zitat
benwen

Registriert seit: 11. Sep 2006
17 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Frage zu OOP - zwei Listen

  Alt 21. Sep 2006, 01:01
Das Ganze über Properties zu regeln, darauf hätt ich auch mal selbst kommen können. Danke für den Tipp! Umsetzung hat natürlich auch geklappt, sodass das Thema damit für mich erledigt ist.

ciao benwen
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:28 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