Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Berechnungsergebnise verschiedener Klassen zusammenführen (https://www.delphipraxis.net/196113-berechnungsergebnise-verschiedener-klassen-zusammenfuehren.html)

EdAdvokat 24. Apr 2018 09:54

Berechnungsergebnise verschiedener Klassen zusammenführen
 
Hallo zusammen. Meine Frage ist eher theoretischer Natur. Ich habe von einer Basisklasse zwei Klassen abgeleitet. In den abgeleiteten Klassen wird eine einfache Preisberechnung(Anzahl*Preis) durchgeführt.
Nun möchte ich die Ergebnisse der Preisberechnungen der Klasse1 mit denen der Klasse 2 addieren. Dies geht natürlich in der Form ohne Schwierigkeiten, doch ist das der richtige Weg?
Gibt es eine Möglichkeit die Berechnung in der logic, also nicht in der Form durchzuführen.
Der Versuch in der Basisklasse(Elternklasse) diese Aufrechnung (Gesamtpreis:=Preis1+Preis2) durchzuführen klappt nicht. Eigentlich auch klar.
Ist mein Denkansatz überhaupt richtig und gibt es da einen Weg, der gangbar wäre?

himitsu 24. Apr 2018 10:00

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Die Berechnungsfunktion in der Basisklasse als Virtual und eventuell auch noch als Abstract definieren und dann in den Ableitungen überschreiben ... dann kannst du bei allen Ableitungen ohne Cast über den Basistyp das auslesen.

Wenn deine Klassen Objektinstanzen irgendwo registriert sind, dann kannst du der Liste/Registrierungsstelle eine Zusammenrechnen-Funktion verpassen.
Oder eine Funktion oder Klassen-Funktion in der Basisklasse, die als Parameter (eventuell als OpenArray) deine Instanzen bekommt und das Gesamtergebnis liefert.

p80286 24. Apr 2018 10:06

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Wenn ich ehrlich bin, verstehe ich Dein Problem nicht. Du hast zwei (drei,vier...) Berechnungsergebnisse. diese willst Du addieren. Dann pack Deine Ergebnisse in ein Array oder eine Liste und addiere die Array/Listeninhalte.
Fertig.

Gruß
K-H

EdAdvokat 24. Apr 2018 10:34

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
möglicherweise habe ich mich nicht klar ausgedrückt. Ich habe jeweils ein Ergebnis der Objektinstanz1 und das der Objectinstanz2. Diese sollen dann addiert werden.
1. wo kann diese Addition der Preisergebnisse durchgeführt werden? (in einer neuen Objectinstanz oder in der Form)
2. wie kann ich von außen auf die Berechnungsergebnisse der Objectinstanzen für diese Aufrechnung(Addition) in der logic zugreifen?

EdAdvokat 24. Apr 2018 10:48

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
hier ein Auszug aus der unit logic:
Delphi-Quellcode:
type
  TKarten = class
   private
    FAnzahl: int32;
    FAufrechnen: int32;
   public
    constructor create;
    destructor Destroy;override;
    procedure setAnzahl(a:Int32);virtual; abstract;
    procedure Aufrechnen(Value:Int32);virtual;abstract;
    function BerechnePreis: Currency;virtual; abstract;
    property Preis: Currency read BerechnePreis;
    property Anzahl: int32 read FAnzahl;
    property Aufre: int32 read FAufrechnen write FAufrechnen;
    end;

type
  TKartenErste = class(TKarten)
   private
    FAnzahl1: int32;
   public
    constructor create;
    destructor Destroy;override;
    procedure SetAnzahl(a:Int32);override;
    procedure aufrechnen(value: int32);override;
    function BerechnePreis: Currency;override;
    property Preis1: Currency read BerechnePreis ;
    property Anzahl1: int32 read FAnzahl;
  end;

type
  TKartenZweite = class(TKarten)
   private
    FAnzahl2: int32;
   public
    constructor create;
    destructor Destroy;override;
    procedure SetAnzahl(a:Int32);override;
    function BerechnePreis: Currency;override;
    property Preis2: Currency read BerechnePreis ;
    property Anzahl2: int32 read FAnzahl;
  end;


implementation

{ TKartenErste }

procedure TKartenErste.aufrechnen(value: Int32);
begin

  //hier weiss ich nicht weiter
end;

function TKartenErste.BerechnePreis: Currency;
begin
  Result := 10 * FAnzahl1;
end;

constructor TKartenErste.create;
begin
  inherited;
end;

destructor TKartenErste.Destroy;
begin
  inherited;
end;

procedure TKartenErste.SetAnzahl(a: Int32);
begin
  FAnzahl1:=a;
end;

{ TKartenZweite }

function TKartenZweite.BerechnePreis: Currency;
begin
  Result := 15 * FAnzahl2;
end;

constructor TKartenZweite.create;
begin
  inherited;
end;

destructor TKartenZweite.Destroy;
begin
  inherited;
end;

procedure TKartenZweite.SetAnzahl(a: Int32);
begin
  FAnzahl2:=a;
end;

{ TKarten }

constructor TKarten.create;
begin
  inherited;
end;

destructor TKarten.Destroy;
begin
  inherited;
end;

end.
und hier den Teil der Form, in der die Zusammenrechnung der Preise vorgenommen wird:
Delphi-Quellcode:
procedure TForm1.btnPreisaufgerechnetClick(Sender: TObject); //aufrechnen
begin
  lblPreisaufgerechnet.caption:=floattostr(Karten1.Preis1+Karten2.Preis2)
end;
dies funktioniert auch. Doch sollte man das so machen? Das ist meine Frage

Klaus01 24. Apr 2018 11:04

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
.. wenn Du es nur zur Anzeige benötigst - ist das aus meiner Sicht ok.
Wenn Du den Gesamtpreis noch weiter verwenden willst solltest Du noch eine Variable oder Containerklasse für den Gesamtpreis spendieren.

Die Klassen unterscheiden sich nur durch den Faktor (10;15) in der Berechnungsmethode.
Würde hier nicht eine Klasse ausreichen (mit dem Faktor als Parameter)?

Grüße
Klaus

EdAdvokat 24. Apr 2018 11:18

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Zitat:

Zitat von Klaus01 (Beitrag 1400317)
.. wenn Du es nur zur Anzeige benötigst - ist das aus meiner Sicht ok.
Wenn Du den Gesamtpreis noch weiter verwenden willst solltest Du noch eine Variable oder Containerklasse für den Gesamtpreis spendieren.

Die Klassen unterscheiden sich nur durch den Faktor (10;15) in der Berechnungsmethode.
Würde hier nicht eine Klasse ausreichen (mit dem Faktor als Parameter)?

Grüße
Klaus

Danke für die klare Feststellung. Das Ganze ist nur eine theoretische Übung, um festzustellen was geht und was nicht. Also muss die Ergebniszusammenführung in der Form (in welcher auch immer Array... einfache Addition...)erfolgen.
Weiter schreibst Du dass ich möglicherweise eine Containerklasse bilden sollte. Wie und wo könnte dies geschehen? Es ist das leidige Problem des Zugriffs auf gekapselte Werte der class1 und class2 von außen.
Geht Dein Vorschlag in Richtung Objectlist?
Das ist mir also noch nicht ganz klar.

Klaus01 24. Apr 2018 11:54

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
.. ja, das könnte z.B eine generische ObjectList<TKarte> sein.
Der "AlleKartenListe" könntest Du Deine Kartenklassen (eins, zwei) übergeben.

Oder Du baust Dir eine Warenkorbklasse die intern eine generische ObjectList verwendet.
Der Warenkorb kann dann den Gesamtpreis bereitstellen.

Grüße
Klaus

DeddyH 24. Apr 2018 12:44

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Ich hatte einen ähnlichen Gedanken:
Delphi-Quellcode:
uses ..., System.Generics.Collections;

type
  TBase = class
  strict private
    FAnzahl: integer;
    class var FInstances: TObjectList<TBase>;
    class constructor Create;
    class destructor Destroy;
    class function GetTotal: integer; static;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    property Anzahl: integer read FAnzahl write FAnzahl;
    class property Total: integer read GetTotal;
  end;

  TEins = class(TBase)

  end;

  TZwei = class(TBase)

  end;

...


class constructor TBase.Create;
begin
  FInstances := TObjectList<TBase>.Create(false);
end;

constructor TBase.Create;
begin
  inherited Create;
  FInstances.Add(self);
end;

destructor TBase.Destroy;
var
  idx: integer;
begin
  idx := FInstances.IndexOf(self);
  if idx > -1 then
     FInstances.Delete(idx);
  inherited;
end;

class destructor TBase.Destroy;
begin
  FInstances.Free;
end;

class function TBase.GetTotal: integer;
var
  lBase: TBase;
begin
  Result := 0;
  for lBase in FInstances do
    inc(Result, lBase.Anzahl);
end;

EdAdvokat 24. Apr 2018 14:54

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Danke DaddyH, zwar habe ich noch nicht alles verstanden, doch ich experimentiere damit bereits herum und versuche so hinter den tiefen Sinn Deines Quelltextes zu gelangen. Die Generics und auch die Anwendung von class-Methoden sind für mich noch Neuland. Jedenfalls rechnet er die in zwei edit-Felder eingegeben Anzahl-Werte zusammen.Na das ist ja schon mal was!
Ich versuche mich mit solchen theoretischen Tests an die Problematik heranzutasten, um dann damit eine praktische Anwendung zu erstellen. Doch da muss ich nochmals ein gutes Tutorial finden.

DeddyH 24. Apr 2018 15:06

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Das jetzt lang und breit zu erklären fehlt mir die Zeit, aber stell Dir die Objektliste als ein "klassenglobales Feld" vor, das für die Basisklasse sowie alle abgeleiteten Klassen gilt. Näheres dazu findest Du hier: http://docwiki.embarcadero.com/RADSt...lassenmethoden

EdAdvokat 24. Apr 2018 17:13

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Das ist verdammt harte Kost. Ich habe noch immer nicht verstanden, welche Vorteile mir die Arbeit mit Klassenmethoden gegenüber der bislang praktizierten OOP bringt, also was ist der Vorteil dieser Weiterentwicklung für den Programmierer mal unabhängig von Objectlisten usw.?
Was kann ich besser mit class function xyz oder class procedure xyz gegenüber function xyz oder procedure xyz bei der Programmierung grundsätzlich erreichen? Ich verstehe durchaus, dass es nicht einfach ist, soetwas hier zu erklären, doch mit entsprechender Literatur sieht es weniger gut aus.
Ich habe mich bereits an Marco Cantu in engl. herangemacht, doch das ist verdammt schwer für mich alten Zausel. Es ist ja nur für mich als Hobbyist.

freimatz 24. Apr 2018 17:33

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Hallo,
soweit ich das beurteilen kann, meine ich dass Du Klassenmethoden hier nicht nehmen sollst. Eine TKarte repräsentiert eine einzelne Karte und sollte von anderen Karten nichts wissen.
Du kannst das wie Du ja auch schon hast in das formular tun, das aber nur wie bei deinem Beispiel wenn es ganz einfach ist. Sonst schlage ich eine separate Klasse TKarten vor, die die einzelnen Karten enthält und auch die Aufrechnung vornimmt. Ob dann da intern eine ObjectListe oder wie auch immer drin ist, sollte von außen nicht mehr sichtbar sein.

Nochmals zu Klassenmethoden: ich halte die für fast so schlimm wie globale Methoden. Man sollte diese nur einsetzen wenn es unbedingt nötig ist.

PS.: Der Trend geht übrigens wieder weg von OOP

EdAdvokat 24. Apr 2018 17:52

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Zitat:

Zitat von freimatz (Beitrag 1400380)
Du kannst das wie Du ja auch schon hast in das formular tun, das aber nur wie bei deinem Beispiel wenn es ganz einfach ist. Sonst schlage ich eine separate Klasse TKarten vor, die die einzelnen Karten enthält und auch die Aufrechnung vornimmt. Ob dann da intern eine ObjectListe oder wie auch immer drin ist, sollte von außen nicht mehr sichtbar sein.

Meinst Du ggf. folgende Lösung, die ich vormals bereits vorgenommen habe: https://www.delphipraxis.net/191102-...inokarten.html
bitte dort die letzte Variante ansehen.
Mit den jetzigen theoretischen Versuchen wollte ich dieses alte Projekt ggf. so neu programmieren, dass ich für jeden Rang oder Loge (Kinokarten) eine gesonderte class bilde und so das Projekt neu erstelle.
Das ist wohl nicht ganz so einfach wie ich dachte.
Wohin geht denn nun der Trend, wenn weg von OOP?

DeddyH 24. Apr 2018 18:02

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Zitat:

Zitat von freimatz (Beitrag 1400380)
Sonst schlage ich eine separate Klasse TKarten vor, die die einzelnen Karten enthält und auch die Aufrechnung vornimmt. Ob dann da intern eine ObjectListe oder wie auch immer drin ist, sollte von außen nicht mehr sichtbar sein.

Und der Mehrwert gegenüber der Klasseneigenschaft liegt genau worin?

Jumpy 25. Apr 2018 08:59

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Es scheint ja um Kinokarten / Kinokasse oder sowas zu gehen.

Wäre da nicht formal folgende Struktur angebracht (sinnvoller weiß ich jetzt nicht).

Eine Warenkorbklasse mit Liste von Warenkorbpositionen und einer Funktion Gesamtsumme, die über die Positionen in der Liste iterriert und summiert.
Eine Warenkorbposition-Klasse mit einem Variable für Anzahl und eine für die Kartenklasse und der Funktion Positionssumme (Anz x Kartenpreis).

Bleibt die Frage, was ist eine Kartenklasse. Da könnte man mit einer Basisklasse und entsprechenden Ableitungen für die einzelnen Kartentypen (Loge/Parkett usw.) arbeiten und/oder man könnte auch das Dekorator-Pattern anwenden, da man zu der Karte ggf. noch was dazurechnen muss: 3D-Zuschlag, Überlängen-Zuschlag, usw.

EdAdvokat 25. Apr 2018 11:28

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Zitat:

Zitat von Jumpy (Beitrag 1400429)
Es scheint ja um Kinokarten / Kinokasse oder sowas zu gehen.

Wäre da nicht formal folgende Struktur angebracht (sinnvoller weiß ich jetzt nicht).

Eine Warenkorbklasse mit Liste von Warenkorbpositionen und einer Funktion Gesamtsumme, die über die Positionen in der Liste iterriert und summiert.
Eine Warenkorbposition-Klasse mit einem Variable für Anzahl und eine für die Kartenklasse und der Funktion Positionssumme (Anz x Kartenpreis).

Bleibt die Frage, was ist eine Kartenklasse. Da könnte man mit einer Basisklasse und entsprechenden Ableitungen für die einzelnen Kartentypen (Loge/Parkett usw.) arbeiten und/oder man könnte auch das Dekorator-Pattern anwenden, da man zu der Karte ggf. noch was dazurechnen muss: 3D-Zuschlag, Überlängen-Zuschlag, usw.

Ja, ich habe vor einiger Zeit mal so ein Übungsprogramm erstellt und wollte es jetzt anders nochmals gestalten mit Klassen für den Rang/Loge.
Ist das Du als Warenkorbklasse bezeichnest folgendes:
Delphi-Quellcode:
type
  TKinokarten = class(TObject)
   private
     const MWSt = 0.19; //gesetzliche MWSt
           Preisliste : TRangPreis =(15, 13,10);
           Ermaessigung: array [boolean] of Currency = (0,1);
       function GetVerkaufteKarten(index: TRang; ermaessigt: boolean):Currency;
     var
       fFreiePlVorgabe: TRangNr;
       FKarten: TRangNr;
       fgekaufteKarten: TRangNr;
       ffreiePlR: TRangNr;
       fPreisR : TRangPreis;

       function GetgekaufteKarten(index: TRang): integer;
       function GetfreiePlR(index: TRang): integer;
       function GetZwSu: Currency;
       function GetMWSteuer:Currency;
       function GetPreis: Currency;
       function GetVorgabePlaetze(index: TRang): integer;

     public
       constructor create(const VorgabePl1, VorgabePl2, VorgabePl3 : integer);

       procedure init;
       function setAnzKarten(index: TRang; Value: integer): boolean;
       procedure setgekKarten(index: TRang; Value: integer);
       procedure BerechnePreisRang(index: TRang; aErmaessigt: boolean);
       procedure BerechnegekKarten;
       procedure BerechnefreiePlRang;
       function getVorgabeGesamt: integer;
       function freiePlGesamt: integer;
       function gekaufteKartenGesamt : integer;

       property VorgabePlaetze[index: TRang]: integer read GetVorgabePlaetze;
       property gekaufteKarten[index: Trang]: integer read GetgekaufteKarten;
       property freiePlR[index: TRang]: integer read GetfreiePlR;

       property ZwSu: Currency read getZwSu;
       property MWSteuer: Currency read getMWSteuer;
       property Preis: Currency read getPreis;
       property VerkaufteKarten[index: TRang; Ermaessigt: boolean] : Currency read GetVerkaufteKarten;
     end;
Dies habe ich vormals so in Form einener Klasse erstellt. Nun wollte ich zunächst probieren ob eine Lösung mit abgeleiteten Klassen für die Ränge eine tragfähige Lösung wäre. Dabei ergibt sich das Problem der Zusammenführung von Werten aus den verschiedenen abgeleiteten Klassen, um beispielsweise die bisherigen Einnahmen oder die verkauften Karten für die Ränge zusammenzurechnen. Allein dieses Problem hat mich veranlasst die Frage hier zu stellen.

Jumpy 25. Apr 2018 11:38

AW: Berechnungsergebnise verschiedener Klassen zusammenführen
 
Deswegen ja mein skizzierter Ansatz mit verschiedenen Klassen und nicht alles in eine Klasse zu packen. Ist ja auch als Übung vllt. interessanter zu sehen, wie die Klassen ineinander greifen. Das Ganze kann ja beliebig komplex werden:
- Mehrere Kinosäle, mit unterschiedlicher Zusammensetzung an Loge- und Parket-Karten.
- Es müssen die Kartenstände (verkaufte Karten vs. freie Karten) für die einzelnen Säle für die einzelnen Tage oder besser Vorstellungen nachgehalten werden.
- Filme könnte einen Klasse sein, mit Eigenschaften, wie 3D, Überlänge usw. und Sälen/oder Vorstellungen zugeordnet werden.

Ich denke man sieht, das hier viele unterschiedliche Klassen am Werk sein sollten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz