Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi OOP wirklich nicht möglich? (https://www.delphipraxis.net/194060-oop-wirklich-nicht-moeglich.html)

Delbor 12. Okt 2017 14:56

Delphi-Version: XE8

OOP wirklich nicht möglich?
 
Hi zusammen

Mit folgender Klasse speichere ich die von einem SQLStatement von MySQL zurückgegeben Daten zwischen:
Delphi-Quellcode:
type
  TQueryResultClass = Class(TPersistent)
  private
    FidBild: Integer;
    FThumbnail : TMemorystream;
    FBitmap: TMemorystream;
    FBildDescribeTabelle : TBildDescribeTabelle;
    FKategoryTabelle : TKategoryTabelle;
    FPass: String;
    FUser: String;
    procedure SetBitmap(Value: TMemoryStream);
    procedure SetThumbnail(Value: TMemoryStream);

    function GetBitmap: TMemoryStream;
    function GetThumbnail: TMemoryStream;
    function FillThumbnail(var Thumbnail: TMemoryStream): TMemoryStream;

  public
    constructor Create(AOwner: TComponent); //
    destructor Destroy; override;
    procedure Assign(Source:TPersistent); override;
    property IdBild :integer read FidBild write FidBild;
    property Thumbnail: TMemoryStream read GetThumbnail write SetThumbnail;
    property Bitmap: TMemoryStream read GetBitmap write SetBitmap;
    property BildDescribeTabelle : TBildDescribeTabelle read FBildDescribeTabelle write FBildDescribeTabelle;
    property KategoryTabelle : TKategoryTabelle read FKategoryTabelle write FKategoryTabelle;
  end;
Nun arbeite ich daran, die AnwendungsDB auf SQLite umzustellen. Leider (?) habe ich Kritik von hier wegen unsäglich langer Taellennamen befolgt und zu diesem Zweck ein neues Datenbankmodell, analog dem mit MySQL benützten, aber mit deutlich gekürzten Tabellennamen erstellt.
Das heisst, ich kann obige Klasse nicht verwenden, sondern muss eine neue, grundsätzlich gleich aufgebaute Klasse erstellen - ein e Anforderung an die Klasse ist, dass deren Felder und Propertys so heissen, wie die Tabellen, deren Inhalte sie übernehmen sollen. Allees andere gäbe früher oder später ein unentwirrbares Chaos.
Die neue, noch nicht fertig erstellte Klasse mit den neuen Tabellennamen:
Delphi-Quellcode:
type
  TCMQueryClass = Class(TPersistent)
  private
    FidBild: Integer;                                      //    FidBild: Integer;
    FThumbnail : TMemorystream;                            //    FThumbnail : TMemorystream;
    FBitmap: TMemorystream;                                //    FBitmap: TMemorystream;
    FTblBildText : TTblBildText;                           //    FBildDescribeTabelle : TBildDescribeTabelle;
    FTblAlbum : TTbl_Album;                                //    FKategoryTabelle : TKategoryTabelle;
    FPass: String;                                         //    FPass: String;
    FUser: String;                                         //    FUser: String;
    procedure SetBitmap(Value: TMemoryStream);             //    procedure SetBitmap(Value: TMemoryStream);
    procedure SetThumbnail(Value: TMemoryStream);          //    procedure SetThumbnail(Value: TMemoryStream);

    function GetBitmap: TMemoryStream;
    function GetThumbnail: TMemoryStream;
    function FillThumbnail(var Thumbnail: TMemoryStream): TMemoryStream;

  public
    constructor Create(AOwner: TComponent); // override;
    destructor Destroy; override;
    procedure Assign(Source:TPersistent); override;
    property IdBild :integer read FidBild write FidBild;
    property Thumbnail: TMemoryStream read GetThumbnail write SetThumbnail;
    property Bitmap: TMemoryStream read GetBitmap write SetBitmap;
    property TblBildText : TTblBildText read FTblBildText write FTblBildText;
    property TblAlbum : TTbl_Album read FTblAlbum write FTblAlbum;
  end;
Ich habe mir lange darüber Gedanken gemacht, wie man dieses Problem mit OOP-Miteln lösen könnte, aber bislang keine befriedigende Lösung gefunden.

Hat jemand einen Vorschlag?

Gruss
Delbor

Neutral General 12. Okt 2017 15:03

AW: OOP wirklich nicht möglich?
 
Ich finde es komisch, dass du überhaupt solche "Zwischen-Klassen" für die Daten einer Query machst.
Die "Query-Results" sind die Rows die deine Query zurückgibt.

Die nächst höhere Ebene wäre Objekt einer "richtigen" Klasse für das die Daten bestimmt sind.
z.B. TUser o.ä.

Du könntest zwischen die Query und der eigentlichen Klasse noch eine Art Factory stellen, der du die Query-Daten übergibst und die dir dann auf deinen Wunsch hin das gewünschte/benötigte Objekt erstellt. Intern entweder durch manuelle Zuweisung oder durch RTTI-Magie.

Delbor 12. Okt 2017 16:29

AW: OOP wirklich nicht möglich?
 
Hi Neutral General

Zitat:

Du könntest zwischen die Query und der eigentlichen Klasse noch eine Art Factory stellen, der du die Query-Daten übergibst und die dir dann auf deinen Wunsch hin das gewünschte/benötigte Objekt erstellt. Intern entweder durch manuelle Zuweisung oder durch RTTI-Magie.
Das Hauptproblem ist, ich müsste dazu wohl fast das ganze Programm umstellen - einmal mehr. Das eigentliche Problem sind die Bilder. Die sind je nach Kamera zwischen 10 und 24MB gross. Allerdings nur die Rohdaten. Bitmaps sind dreimal grösser.

Mein Programm lädt die vorhandenen Daten vorerst ohne die Bilder. Die werden nachgeladen, wenn sie zur Bearbeitung benötigt werden. Dabei werden Thumpnails für die Navigation und Bitmaps für die grafische Bildbearbeitung erstellt. Bitmaps und Rohdaten werden anschliessend in einer externen DB auf einem beliebigen Laufwerk abgelegt (und dienen da gewissermassen als Backup).

Ich hab eine Factory eingebaut, die mir einen da registrierten Frame (ich habe mehrere verschiedene) zur Laufzeit erstellt und zurückliefert. So, wie ich das verstehe, geht dein Vorschlag genau dahin.
Bei dieser Framefactory sind diverse Frames registriert, die von meiner Anwendung in Abhängigkeit von dem, was der User tun will, alle gebraucht werden und deren Aufbau wegen der Bindung an dieses Programm in den Grundzügen gleich ist.
Das muss aber bei dem angestrebten Objekt nicht sein - oder wird in den wenigsten Fällen so sein.
Die gezeigte Klasse enthält weitere Klassen, die ihrerseits die Tabellen- und Feldstruktur einer DB-Tabelle abbilden.

Gruss
Delbor

TigerLilly 12. Okt 2017 17:40

AW: OOP wirklich nicht möglich?
 
Hilft dir das Decorator Pattern hier nicht?
Du routest aus der neuen Klasse alles auf die alte durch. So kannst du nach und nach alles auf die neue Klasse umstellen.

Delbor 12. Okt 2017 18:23

AW: OOP wirklich nicht möglich?
 
Hi Tigerlilly

Ich muss gestehen, von Decorator Pattern hab ich jetzt von dir zum ersten Mal gehört. Aber nachdem, was mir Wikipedia verrät, wohl eher nicht.
Wenn du die von mir geposteten Klassen ansiehst, wirst du bemerken: Es handelt sich eigentlich um eine in einer Klassenstruktur zusammengefasste Ansammlung sprechender Variablen. Eine Klasse ist das einer Objektliste wegen, die auf diese Weise die Query-Ergebnisse bereithält, ohne das eine Query-Komponente während einer möglicherweise längeren DB-Sitzung dauernd offen sein müsste.

Gruss
Delbor

hoika 12. Okt 2017 19:25

AW: OOP wirklich nicht möglich?
 
Hallo,
Zitat:

aber mit deutlich gekürzten Tabellennamen erstellt.
Das heisst, ich kann obige Klasse nicht verwenden
Was hat denn der Tabellenname mit einer Datenklasse zu tun?

Delbor 12. Okt 2017 23:27

AW: OOP wirklich nicht möglich?
 
Hi hoika
Zitat:

Was hat denn der Tabellenname mit einer Datenklasse zu tun?
In diesem (und nur in diesem) Fall sehr viel. Lies dazu nochmal den Beitrag direkt vor deinem.
Delphi-Quellcode:
type
  TQueryResultClass = Class(TPersistent)
  private
    FidBild: Integer;
    FThumbnail : TMemorystream;
    FBitmap: TMemorystream;
    FBildDescribeTabelle : TBildDescribeTabelle;
    FKategoryTabelle : TKategoryTabelle;
...
  • FIdBild dürfte selbsterklärend sein - das Feld soll den PrimaryKey speicern.
  • FThumbnail ist ein Feld zur Aufnahme von Blob-Daten.
  • Ebenso FBitmap. Aber dann wirds interessant:
  • FBildDescribeTabelle ist vom Tip TBildDescribeTabelle, einer Klasse, die die gleichnamige Tabelle in der DB abbildet und eine Detailtabelle der BildTabelle darstellt. (1:n-Beziehung)
  • TKategoryTabelle hingegen bildet die gleichnamige Tabelle aus der DB ab, ist aber it der Bildtabelle in einer n:m-Beziehung.

Gruss
Delbor

TiGü 13. Okt 2017 08:36

AW: OOP wirklich nicht möglich?
 
Zitat:

Zitat von Delbor (Beitrag 1383183)
Ich habe mir lange darüber Gedanken gemacht, wie man dieses Problem mit OOP-Miteln lösen könnte, aber bislang keine befriedigende Lösung gefunden.

Hat jemand einen Vorschlag?

Wie wär's mit diesem neuartigen Konzept:
Gemeinsamkeiten von zwei oder mehr Klassen in eine gemeinsame Basisklasse und nur in den Ableitungen das neue Zeug?! 8-)

Delphi-Quellcode:
type
  TCustomQuery = Class(TPersistent)
  protected
    FidBild: Integer;
    FThumbnail: TMemoryStream;
    FBitmap: TMemoryStream;
    FPass: String;
    FUser: string;
    procedure SetBitmap(Value: TMemoryStream);
    procedure SetThumbnail(Value: TMemoryStream);
    function GetBitmap: TMemoryStream;
    function GetThumbnail: TMemoryStream;
    function FillThumbnail(var Thumbnail: TMemoryStream): TMemoryStream;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
    property IdBild: Integer read FidBild write FidBild;
    property Thumbnail: TMemoryStream read GetThumbnail write SetThumbnail;
    property Bitmap: TMemoryStream read GetBitmap write SetBitmap;
  end

  TQueryResultClass = Class(TCustomQuery)
  protected
    FBildDescribeTabelle: TBildDescribeTabelle;
    FKategoryTabelle: TKategoryTabelle;
  public
    procedure Assign(Source: TPersistent); override;
    property BildDescribeTabelle: TBildDescribeTabelle read FBildDescribeTabelle write FBildDescribeTabelle;
    property KategoryTabelle: TKategoryTabelle read FKategoryTabelle write FKategoryTabelle;
  end;

  TCMQueryClass = Class(TCustomQuery)
  protected
    FTblBildText: TTblBildText;
    FTblAlbum: TTbl_Album;
  public
    procedure Assign(Source: TPersistent); override;
    property TblBildText: TTblBildText read FTblBildText write FTblBildText;
    property TblAlbum: TTbl_Album read FTblAlbum write FTblAlbum;
  end;

Elrond 13. Okt 2017 09:18

AW: OOP wirklich nicht möglich?
 
Ich muss zugeben das ich das Problem überhaupt nicht verstehe, was genau möchtest du?

Wenn es dir um eine detailgetreue Abbildung deines Datenbankmodells auf eine Klasse geht, kannst du natürlich einen Wrapper schreiben der aus der DB die entsprechenden Klassen extrahiert. Das lässt sich auch gut automatisiert in den Entwicklungsprozess einbinden. Man kann auch den eher üblicheren Weg gehen und deine Klassen auf die DB Mappen (ORM). In beiden Fällen müsstest du nur an einer Stelle Änderungen vornehmen (Klasse oder DB, statt Klasse und Query). Für deine großen Bilddateien könntest du damit auch das lazy loading Feature nutzen.

generic 13. Okt 2017 12:21

AW: OOP wirklich nicht möglich?
 
Ich kann bei solchen Architektur Problemen diese Buch empfehlen:
https://martinfowler.com/books/eaa.html


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:16 Uhr.
Seite 1 von 5  1 23     Letzte »    

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