![]() |
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:
Nun arbeite ich daran, die AnwendungsDB auf SQLite umzustellen. Leider (?) habe ich Kritik von
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; ![]() 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:
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.
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; Hat jemand einen Vorschlag? Gruss Delbor |
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. |
AW: OOP wirklich nicht möglich?
Hi Neutral General
Zitat:
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 |
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. |
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 ![]() 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 |
AW: OOP wirklich nicht möglich?
Hallo,
Zitat:
|
AW: OOP wirklich nicht möglich?
Hi hoika
Zitat:
Delphi-Quellcode:
type
TQueryResultClass = Class(TPersistent) private FidBild: Integer; FThumbnail : TMemorystream; FBitmap: TMemorystream; FBildDescribeTabelle : TBildDescribeTabelle; FKategoryTabelle : TKategoryTabelle; ...
Gruss Delbor |
AW: OOP wirklich nicht möglich?
Zitat:
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; |
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. |
AW: OOP wirklich nicht möglich?
Ich kann bei solchen Architektur Problemen diese Buch empfehlen:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:21 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