Thread Perl OOP (12 answers)
Opened by sid burn at 2006-09-21 19:24

sid burn
 2006-09-22 22:20
#70151 #70151
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Quote
oha. sorry, dass ich schon wieder was einzuwenden habe.

Wieso Sorry?
Ich hab doch extra den Thread erstellt damit ich ein paar einwände bekomme. Wenn ich keine Einwände akzeptieren würde, wäre ich ja ein schlechter Programmierer. ;)

Quote
bei einem normalen getter ein select auf die datenbank zu machen kann je nach anwendung *sehr* ineffizient sein.gerade gestern erlebt. eine klasse bei uns hat eine methode, die eine
reihe von strings zurückliefert. diese sind keine direkten attribute.
beim aufruf dieser methode wird ein select auf die datenbank gemacht.
bis vor kurzen lieferte die methode aber ein direktes attribut.
nun gibt es eine anwendung, die einen export macht und sich,
sagen wir, 100.000 objekte aus der db holt. für jedes objekt holt sich
der export nun noch über die genannte methode die strings.
das sind 100.000 selects extra. der export läuft jetzt doppelt so lange
wie vorher. nicht gut.

Ja das habe ich mir auch schon gedacht. Vielleicht sollte ich etwas mehr zum Thema erzählen warum ich das Trotzdem machen möchte. Ich habe für die Arbeit ein kleines Webinterface geschrieben um einen FTP Server zu verwalten. Zu der Benutzerverwaltung kommen halt noch Sachen dazu wie eMail Benachrichtigung wenn ein Account angelegt wurde, automatisches Löschen von Benutzern wenn Ihre Gültigkeitsdauer abgelaufen ist etc.

Das ganze läuft soweit schon, allerdings habe ich auch bei solch einen kleinen Projekt ziemlich viel Erfahrung dazu gewonnen. Programmiere halt noch nicht so lange. ;)

Ich habe das ganze mehr so geschrieben wie du es bisher beschrieben hast. Sprich ich stelle einfach durch einen Befehl z.B. eine Datenbankverbindung her. Und wenn ich Benutzer auslese werden alle Ihre Daten mit einem einzigen SELECT Befehl ausgelesen. Ich erzeuge halt ein User Objekt und packe alle Daten in dieses Objekt.

Bei der Logik sind mir aber ein paar probleme untergekommen. Zum einen hatt das User Objekt eine Fehlerüberprüfung. Das heißt es akzeptiert keine UID kleiner 1000 etc. Diese Überprüfung habe ich direkt in das User Objekt eingebaut.

Das Problem war wenn ich die Daten letztendlich Auslese und die HTML Seite aufgebaut habe. Den dann habe ich die Daten ausgelesen und über die Setter Methoden das Objekt gefüllt. Tjo und genau da war das Problem. Wenn in der Datenbank eine 500 steht. (Vielleicht war ja früher mal 500 als UID erlaubt) und ich damit mein User Objekt erzeuge dann habe ich alle Werte kleiner 1000 verworfen und einfach den Konfigurierten default_uid Wert genommen, wenn die min_uid nicht erfüllt war.

Letztendlich hat also die Webseite bei der Anzeige völlig andere Werte angezeigt als sie in der Datenbank standen. Das Problem habe ich nachher umgangen so das ich beim Auslesen die Werte direkt fülle, und nicht über Setter Methoden. Das muss ich sowieso machen. Sonst würde mir die Setter Methode für das password den Hash nochmal Hashen und erst dann anzeigen.

Eine andere Sache war die gewesen das wenn ich z.B. einfach nur ein Passwort ändern möchte, ich unnötig viel Code schreiben muss. z.B. hole ich mit "my $user = $ftp->getuser('anne')" die Benutzerinformationen zum User "anne", und das gibt mir ein Benutzerobjekt zurück. Wenn ich nur das Passwort des aktuellen Benutzers Löschen möchte, dann muss ich letztendlich wiederrum ein neues Objekt erstellen, dann die alten Werte in das neue Kopieren. Und hierbei darf ich keine Setter Methode Benutzen. Den wenn ich wie gesagt das passwort wieder mit einer Setter Methode schreibe, wird der Hash nochmals gehasht. Womit ein einloggen mit diesem benutzer nicht mehr Möglich wäre.

Und nachdem ich beide Objekt hatte, habe ich eine Methode Modify aufgerufen. "$ftp->modify( $old_user, $new_user)" das letztendlich den alten benutzer genommen hat, und dann die veränderten Werte in die Datenbank schreibt.

Ziemlich viel Aufwand. Zwar läuft das Webinterface aber ich möchte sicherlich noch etwas weiter Lernen. Daher habe ich mir überlegt ob es nicht deutlich Sinvoller ist die Daten einfach direkt auszulesen. Dann habe ich jedenfalls das Problem mit dem Auslesen der Daten und den Settern nicht mehr. Weil meine Klasse ja direkt mit der Datenbank Kommuniziert.

Und beim Setter das gleiche, die Werte werden sofort geschrieben. Natürlich kommt trotzdem vorher eine Fehlerüberprüfung. Jedenfalls um das Passwort dann neu zu setzen bräuchte ich nicht alle anderen Werte auslesen. Es würde praktisch folgender Code reichen.
Code: (dl )
1
2
3
my $user = $ftp->getuser('anne');
$user->password( "foobar" );
$ftp->disconnect;

Solch ein Interface finde ich dann doch deutlich angenehmer.

Und passend mit der Möglichkeit das hinter den einzelnen Werten Klassen stehen, würde ich dann auch folgendes machen.

Code: (dl )
$user->password->random;

Was dann einfach ein neues Random Passwort erzeugt, und dann natürlich auch gleichzeitig das "Plaintext" Passwort setzt, das ich noch für die Mail Versundung benötige.

Jedenfalls finde ich das Handlicher und einfacher. Problem ist aber halt die Performance. Ich greife nicht mehr mit einem Select auf mehrere Attribute drauf zu, sondern immer jedes Attribut einzelnd. Die Performance ist in diesem Fall aber vernachlässigbar.

Interesse wie ich das Beschleunigen könnte würden mich aber trotzdem Interessieren. Das Interface so wie ich es jetzt gerade beschrieben habe würde ich aber gerne beibehalten, das finde ich jedenfalls Handlicher. Auser du weißt eine Bessere Möglichkeit wie ich das ganze machen könnte.

Quote
vielleicht solltest du CPAN: DBIx::Class o.ä. verwenden, da
kann man dann auch angeben, welche attribute immer gleich mit
dem ersten select geholt werden sollen und welche nicht.

Werde ich mir mal anschauen.\n\n

<!--EDIT|sid burn|1158949514-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de

View full thread Perl OOP