Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Getter wird übergangen (https://www.delphipraxis.net/152302-getter-wird-uebergangen.html)

Medium 17. Jun 2010 18:36

AW: Getter wird übergangen
 
@implementation:
#Develop. Und das mit dem Schwachsinn will ich mal dahin gestellt sein lassen. Es gibt hier schon einen triftigen Grund dafür, dass die Referenz selbst nicht gepeichert werden soll. Immerhin ist die gesamte Klasse quasi abstrakt - es werden ja gar keine Instanzen erzeugt.

Was ich damit schlicht erreichen will ist, dass man im eigentlichen Programm nachher die angenehme Schreibweise hat, ála:
TDB.Users[id].Name
TDB.Rights[id].Description
usw., und zwar je nach Feld nur lesend, oder auch schreibend. Dabei ist es ebenfalls wichtig, dass IMMER live aus der DB gelesen wird. Was will ich dann jemals mit einer Instanz von TDB.Users[id] sinnvoll anfangen wollen!?

@himi:
Ich bastels mal um. Edit: Leider kein Effekt. Die Properties sind in der eigentlichen (etwas größeren) Klasse auch nicht allein:
Delphi-Quellcode:
  public
    class function AddUser(aName, aSurname, aLogin, aPassword: string): Integer;
    class function UserExists(aUserID: Integer): Boolean; overload;
    class function UserExists(aLogin: string): Boolean; overload;
    class property Query: TUniQuery read FQuery write FQuery;
    class property Users[aUserID: Integer]: TDBUser read GetDBUser;
    class property UsersByLogin[aLogin: string]: TDBUser read GetDBUserByLogin;

SirThornberry 17. Jun 2010 18:54

AW: Getter wird übergangen
 
Das Problem mit den ganzen Class-Methoden ist das es nicht Threadsicher ist.
Wenn ein mehrere Threads gleichzeitig die Klasse verwenden kommen ganz "tolle" Ergebnisse dabei raus.
Was spricht dagegen eine ganze normale Klasse daraus zu machen und dann, wenn es unbedingt sein muss, eine "globale" Instanzvariable zu nutzen? Dann kannst du diese Bei Programmstart initialisieren und bei Programm Ende freigeben und wirst keine Probleme haben wenn mal mehrere Threads die Klasse zum gleichen Zeitpunkt verwenden.

Es geht also nicht darum alle Klassenmethoden zu entfernen sondern nur zu verhindern das Variablen von mehreren Threads gleichzeitig genutzt werden.

Medium 17. Jun 2010 19:03

AW: Getter wird übergangen
 
Hm, mal abgesehen davon, dass im gesamten Projekt bisher keine Verwendung von Threads vorgesehen ist, ließe sich im Zweifel das Zuweisen der FID und die Rückgabe der Klassenreferenz noch in eine Critical Section stopfen. Das Problem wäre mit einer globalen Instanzvariablen auch das selbe: Es würde die ID von einem Thread gesetzt, und er könnte sich schon nicht mehr sicher sein, dass sie von einem anderen nicht umgehend geändert wurde, noch bevor die 2 Dereferenzierungen bis zum gewünschten Ergebnis ausgeführt sind.
Oder meintest du die TDB-Klasse, nicht die Sub-Klassen*? Da könnte eine Instanz pro Thread noch Sinn machen, ich müsste mir dann nur grad überlegen ob und wo ich diese dann hin schmeissen will. Eigentlich wollte ich den Zugriff von überall im Programm möglich machen, ohne je etwas dafür Createn zu müssen.
*) Da wäre dann die Frage, ob jede TDB-Instanz eine ganz eigene TDBUser-Klassenreferenz hat, und nicht nachher mehrere TDBs auf die selbe TDBUser-Klasse zugreifen.

Da das hier offenbar alles zu nichts führt, frage ich einfach mal anders:
Wie würdet IHR es angehen, eine DB im Programm wie eine Collection aussehen zu lassen, die sämtliche Abfragen live aus der DB tätigt, und Zuweisungen auch umgehend in diese zurück speichert? Und zwar so, dass ich mir bei der Verwendung keinerlei Gedanken um Freigaben o.ä. machen muss.

Medium 18. Jun 2010 11:13

AW: Getter wird übergangen
 
Update: Wenn ich die inneren Klassen zu Records (mit normalen Methoden natürlich, aber nach wie vor private) mache, aber ansonsten nichts zur ersten Version ändere, DANN funktioniert das ganze! Ich würde das daher durchaus als tatsächlichen Bug bezeichnen, und da soweit keine weiteren Vorschläge zum grundsätzlichen Vorgehen kamen, bzw. ich mit dem hier eigentlich recht zufireden bin, kann ich das Thema denke ich als gelöst betrachten.
Edit: Und das sollte auch die Problematik mit der Threadsicherheit eliminieren, da ja jetzt immer ein neuer Record geliefert werden dürfte.

Nochmals vielen Dank an alle!

SirThornberry 18. Jun 2010 12:27

AW: Getter wird übergangen
 
genau, damit sollte es auch Threadsicher sein.
Ich hatte das Global in Anführungszeichen gepackt weil ich nicht wirklich global meinte sondern global innerhalb einer Threadklasse, innerhalb deiner Klasse die das handelt etc. so das aber keiner von außen drauf zugreifen kann. Aber durch den Umstieg auf Records hat sich das erübrigt.

Medium 18. Jun 2010 14:43

AW: Getter wird übergangen
 
Jau, das hatte ich auch so verstanden. Meine Bauchschmerzen diesbezüglich lagen auch beim Hauptthread, dem ich mehr als ungerne eine unitübergreifende Magic-Super-Global spendiert hätte. Deswegen hab ich ja als aller erste Anlaufstelle die Klasse TDB, die nur statische Elemente enthält, damit man eben nicht nachher nicht so recht weiss wohin mit der Instanz, bzw. sich überhaupt ums Erzeugen/Freigeben kümmern muss.

Ziel ist hierbei übrigens die totale Entkopplung der Logik von der Datenhaltung, so weit, dass im eigentlichen Programm kein Fitzel SQL mehr auftaucht. Wenn die DB getauscht würde, müssten in der TDB-Klasse lediglich 6 Strings (SQL-Prototypen quasi*) angepasst werden falls sich an der Syntax was tut, und eben das Query-Feld gegen die entsprechende neue Zugriffskomponente getauscht werden. Im Zugriff programmseitig schaut das nachher wie eine große Collection aus, die aber immer "frisch" ist, und keinerlei Polling o.ä. bedarf.
*) Gut, es gibt auch eine Hand voll speziellerer und umfangreicherer Statements, die nicht aus den Prototypen gebildet werden, und daher auch ggf. anstünden. Aber dafür jeder auch wirklich nur ein Mal.

Ich hätte auch ehrlich gesagt angenommen, dass das Vorgehen im Groben recht üblich ist :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 Uhr.
Seite 2 von 2     12   

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