Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Aufbau Klassenstruktur (https://www.delphipraxis.net/131704-aufbau-klassenstruktur.html)

Antigo 29. Mär 2009 14:59


Aufbau Klassenstruktur
 
Hi,
Ich möchte gerne eine Daten bzw Objektstruktur anlegen. Dabei möchte ich gern die Klassen TKalender, TJahr, TMonat, TTag, TStunde und TMinute haben. Dann soll jede der Klassen ein dynamisches Array von der darunter liegenden Zeiteinheit haben, also der Kalender soll ein Array von Jahren haben, das Jahr ein Array von Monaten usw. Nur die Minuten sollen ein Array von einem Record haben.

In dieser Strukur möchte ich dann gerne meine Records speichern. Eine Variable dieses Record Typs hatt ein Datum als Eigenschaft. Wenn ich die Variable also dem Kalender hinzufüge (kalender.add), soll dieser sich das Datum ansehen und es quasi weiterreichen und dem entsprechenden Jahr übergeben (jahr.add) das wiedderrum an den richtigen Monat weiterreiche usw, bis ich die Variable schließlich in der richtigen Minute dann tatsächlich speichere.

Dann soll es anschließend noch Funktionen geben, die beispielsweise die Anzahl der Variablen in einem Jahr berechnen indem die Anzahl der Variablen je Monat addiert werden, und diese dann jeweils aus der Summe der Variablen der einzelnen Tage berechnet werden usw. bis ich bei den Minuten angelangt bin und nur noch die Länge des Arrays meines records angucken muss.


Jetzt meine eigentliche Frage: Wie löse ich das ganze möglichst elegant. Die einzelnen Zeitklassen Tkalender, TJahr usw sehen eigentlich fast gleich aus, sie brauchen ein array der darunter liegenden Zeiteinheit und auch die selben Funktionen bzw, die Prozedur Add zum hinzufügen eines Datensatzes.
Ich hatte das ganze zunächst so gelöst, dass ich halt 6 verschiedene Klassen angelegt hab und mit Copy und Paste dann jeweils alles angepasst. So dass dann Tkalender ein array of Tjahr hat und Tjahr dann ein Array of TMonat usw.

hat vielleicht jemand eine Idee wie ich das vielleicht mit Vererbung besser machen kann? So das ich vllt sogar nur eine Klasse hab namens TZeitEinheit, die dann wiederrum ein Array von TZeitEinheit hat usw? Nur mir ist nicht klar wie ich dann die TMinute, die ja anders aussieht als die anderen Klassen, da sie ja ein Array meines Records hatt da unterbringen soll. Ausserdem muss ich ja wissen ob ich grad in einem Monat bin und mir vom zuspeichernden Datensatz jetzt den Tag angucken muss oder doch die Stunde.

Würde mich über tipps sehr freuen ;)

mkinzler 29. Mär 2009 15:28

Re: Aufbau Klassenstruktur
 
Warum so kompliziert? Was bringt das mit den verschiedenen Typen für Jahr, Monat, ...?

Satty67 29. Mär 2009 15:39

Re: Aufbau Klassenstruktur
 
Ich gehe mal von einem Übungs-Projekt aus...

Also Basis-Klasse
Delphi-Quellcode:
TTimeUnity = class
  FChildUnitys : array of TTimeUnity; // forward-Deklaration nicht vergessen
  FUnitySegemnt : Integer;
public
  function Add(TimeLine : TypNachWunsch) : TTimeUnity
  property UnitySegment : Integer read FUnitySegment
...um nur einen Teil der Idee zu visualisieren.

- Als Basis wird z.B. Kalender : TTimeUnity definiert.
- Ein Aufruf von Add lässt prüfen, ob der 1. Teil der TimeLine (hier 2009) schon eine ChildUnity hat (Timeline z.B. 2009;11;01;10;12;00)
- Nein anlegen (Child merkt sich seinen Wert in UnitySegment)
- Ja mit gekürzter TimeLine aufrufen.

Ein Prüfen/Aufruf erfolgt, bis Timeline leer ist. Rückgabe an Kalender sollte die kleinste angelegte TimeUnity sein.
Für die Timeline könnte man sich auch ein dyn. Array vorstellen oder die Fähigkeit der Klasse, die richtige Position aus dem datum selbst zu schneiden.

Antigo 29. Mär 2009 16:35

Re: Aufbau Klassenstruktur
 
Zitat:

Zitat von mkinzler
Warum so kompliziert? Was bringt das mit den verschiedenen Typen für Jahr, Monat, ...?

ja garnichts ^^ deswegen auch mein Thread uum zu fragen wies besser geht.


Zitat:

Zitat von Satty67
Ich gehe mal von einem Übungs-Projekt aus...

Also Basis-Klasse
Delphi-Quellcode:
TTimeUnity = class
  FChildUnitys : array of TTimeUnity; // forward-Deklaration nicht vergessen
  FUnitySegemnt : Integer;
public
  function Add(TimeLine : TypNachWunsch) : TTimeUnity
  property UnitySegment : Integer read FUnitySegment
...um nur einen Teil der Idee zu visualisieren.

- Als Basis wird z.B. Kalender : TTimeUnity definiert.
- Ein Aufruf von Add lässt prüfen, ob der 1. Teil der TimeLine (hier 2009) schon eine ChildUnity hat (Timeline z.B. 2009;11;01;10;12;00)
- Nein anlegen (Child merkt sich seinen Wert in UnitySegment)
- Ja mit gekürzter TimeLine aufrufen.

Ein Prüfen/Aufruf erfolgt, bis Timeline leer ist. Rückgabe an Kalender sollte die kleinste angelegte TimeUnity sein.
Für die Timeline könnte man sich auch ein dyn. Array vorstellen oder die Fähigkeit der Klasse, die richtige Position aus dem datum selbst zu schneiden.

Ok so ähnlich hab ich es jetzt gelöst:

Delphi-Quellcode:
  TTyp = (Kalender,Jahr,Monat,Tag,Stunde,Minute);

  TZeitEinheit= class
  private
    FTyp: TTyp;
    FIndex: Integer;
    FItems: array of TZeitEinheit;
    FPings: array of TPing; //Record der bei Minuten gespeichert werden soll
    FCountPings:Integer;
    FCountTimeOuts: Integer;
    FGetLoss:Single;
  public
    function CountPings: integer;
    function CountTimeouts: integer;
    function GetLoss  : Single;

    procedure AddPing(APing: Tping);
    procedure WriteTreeView(ATreeView:TTreeView;AParent:TTreeNode);

    property PingCount: Integer read FCountPings;
    property TimeOutsCount: Integer read FCountTimeouts;
    property Loss: Single read FGetLoss;

    constructor create(ATyp:TTyp; AIndex:Integer);
  end;
Und dann beim AddPing:

Delphi-Quellcode:
begin
  case FTyp of
    Minute : begin
                Setlength(FPings,length(FPings)+1);
                FPings[High(Fpings)]:=APing;
              end;
    Stunde : Add(APing,MinuteOf(APing.datetime));
    Tag    : Add(APing,HourOf(APing.datetime));
    Monat  : Add(APing,DayOf(APing.datetime));
    Jahr   : Add(APing,MonthOf(APing.datetime));
    Kalender: Add(APing,YearOf(Aping.datetime));
  end;
end;
Ist halt nur nicht so schön das ich bei allen Objekten die nicht Minute sind auch das Array Fpings mitschleppe, dass eigtl nur Instanzen die Minuten darstellen brauchen. Ausserdem muss ich bei allen Funktionen immer gucken ob es der Ftyp der Instanz = Minute ist und dann anders reagieren, weil ich dann nichtmehr auf die Fitems zugreife, sondern auf die Fpings.
Aber als ich noch für jede Zeiteinheit ne eigene Klasse (Tjahr, TMonat usw) hatte musste ich quasi 6 mal die gleichen Funktionen implementieren, und nur den Array Namen anpassen, daher denke ich, dass diese Lösung schon eleganter ist.


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