PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Franz Hofer schrieb:
[..]
> Kennt jemand von euch eine gute ORM Lösung für PHP, die womöglich besser
> als
> Propel zu verwenden ist?
Nein, Propel ist da schon recht gut - wenn man denn tatsächlich soviel
von ORM hält.
Ich persönlich jedoch halte es für den falschen Weg. Denn ORM bedeutet,
dass sich Persistenzstruktur direkt auf Codestruktur auswirkt - was
wiederum bedeutet: Ändert sich die Persistenzstruktur, muß viel Code
manipuliert werden. Da kann man ja gleich SQL in den Code werfen. Oder
Gettern und Settern verwenden. ;)
Gruß,
Torsten
Re: PHP und ORM
Hallo, Torsten,
Du (thorny) meintest am 05.09.07:
> Nein, Propel ist da schon recht gut - wenn man denn tatsächlich
> soviel von ORM hält.
> Ich persönlich jedoch halte es für den falschen Weg. Denn ORM
> bedeutet, dass sich Persistenzstruktur direkt auf Codestruktur
> auswirkt - was wiederum bedeutet: Ändert sich die Persistenzstruktur,
> muß viel Code manipuliert werden. Da kann man ja gleich SQL in den
> Code werfen. Oder Gettern und Settern verwenden. ;)
Gibt es diesen Text auch in Hochdeutsch?
Viele Gruesse!
Helmut
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Helmut Hullen schrieb:
> Hallo, Torsten,
>
> Du (thorny) meintest am 05.09.07:
>
>> Nein, Propel ist da schon recht gut - wenn man denn tatsächlich
>> soviel von ORM hält.
>> Ich persönlich jedoch halte es für den falschen Weg. Denn ORM
>> bedeutet, dass sich Persistenzstruktur direkt auf Codestruktur
>> auswirkt - was wiederum bedeutet: Ändert sich die Persistenzstruktur,
>> muß viel Code manipuliert werden. Da kann man ja gleich SQL in den
>> Code werfen. Oder Gettern und Settern verwenden. ;)
>
> Gibt es diesen Text auch in Hochdeutsch?
Was stört dich daran?
Gruß,
Torsten
Re: PHP und ORM
Franz Hofer schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Ich persönlich jedoch halte es für den falschen Weg. Denn ORM
>> bedeutet, dass sich Persistenzstruktur direkt auf Codestruktur
>> auswirkt - was wiederum bedeutet: Ändert sich die Persistenzstruktur,
>> muß viel Code manipuliert werden. Da kann man ja gleich SQL in den
>> Code werfen. Oder Gettern und Settern verwenden. ;)
>
> Das sind durchaus angebrachte Gedanken.
>
> Wenn du allerdings Abfragen hast, bei denen im Select ein Join über rund
> 50 Tables gemacht wird, und dann auch noch ca. 150 Zeilen
> Where-Bedingungen folgen, dann bist du froh dass es ORM gibt.
Genau dort finde ich ORM eine Katastrophe - zumindest basierend auf
meinen bisherigen Erfahrungen.
Mein Datenbanklayer z.B. reduziert den sich auf Datenbank beziehenden
Code auf 2 Zeilen. Die erste Zeile spezifiziert die zu nutzende
Datenbank (da ich ein Pooling verwende, welches es ermöglicht mit einer
unbegrenzten Anzahl an Datenbanken gleichzeitig zu arbeiten). Die Zweite
spezifiziert den Query an Hand eines Aliases und übermittelt die
benötigten Parameter. Fertig. Egal ob ich die Datenbank portiere und
alles umschreibe - ich muß diese eine Zeile niemals ändern.
> Und noch glücklicher wird man, wenn solche Abfragen mehrmals in der
> Applikation vorkommen und man bei einer Änderung des Datenmodells nur
> ein paar Zeilen in der Datenklasse ändert ;-)
Wie oben geschrieben - ich biete keinerlei Manipulation ;)
Was mich an ORM-Implementationen standardmäßig stört sind Konstrukte
alla[1]:
"
$c = new Criteria();
$cton1 = $c->getNewCriterion(AuthorPeer::FIRST_NAME, "Leo");
$cton2 = $c->getNewCriterion(AuthorPeer::LAST_NAME,
array("Tolstoy", "Dostoevsky", "Bakhtin"),
Criteria::IN);
// combine them
$cton1->addOr($cton2);
// add to Criteria
$c->add($cton1);"
Hier wirkt sich die Struktur der Datenbank viel zu stark im Code aus.
> Das hab ich jetzt zwar nicht hier unter PHP, habe es aber schon woanders
> erlebt.
>
> Im speziellen Fall wird man wahrscheinlich den Aufwand abwägen müssen.
> Und wenn spätere Wartbarkeit bei einem eventuell komplex gewachsenen
> Programm sehr wichtig ist, dann muss man überlegen, ob man mit einer ORM
> Lösung nicht vielleicht Zeit sparen kann - auch wenn es vor Allem am
> Anfang einen gewissen Overhead bedeutet.
Sollte es sich bei den Objekten um reine Getter/Setter Objekte handeln:
Bah! ;)
Zum einen Zeug das von schlechtem Design und zum anderen ist es auch
noch um den Faktor 10 langsamer als eine Sequenz oder um Faktor 8
langsamer als ein Array.
Die grundsätzliche Frage sollte auch sein: Warum benötige ich ORM,
obwohl man mit einem einfachen Datenbanklayer schneller und effektiver
arbeiten kann ohne auf die Objekte verzichten zu müssen?
Gruß,
Torsten
Fußnoten
========
[1]
http://propel.phpdb.org/docs/en/user_guide/chapters/FindingO bjects.html#FindingRecods.Criteria
Re: PHP und ORM
Franz Hofer wrote:
> Hallo!
>
> Wie gebräuchlich ist in PHP Anwendungen denn object realational mappi=
ng,
> also
> der Zugriff auf die Datenbank mittels Datenobjekten, ohne selber
> SQL-Statements
> formulieren und Tables anlegen zu müssen?
Ich nutze es nicht.
> So wie ich den Eindruck habe, dürften sich nicht viele damit
> beschäftigen, was
> aber wohl am Einsatzgebiet von PHP - nämlich keineren Webanwendungen =
-
> liegen
> dürfte.
Oder an dem Problem, bereits genutzte Strukturen auf ORM umzustellen.
> Ich suche gerade eine ORM Lösung für PHP und hab dazu EZPDO und nac=
hher
> auch
> Propel in die engere Auswahl gezogen.
Propel habe ich hier nicht zum Laufen bekommen, damit würde bei mir
Propel schon immer ausscheiden ;-)
EZPDO habe ich installiert und fand das nicht schlecht, jedoch kann ich
das nicht in bestehende Projekte integrieren. Mir ist es klar, dass
gerade die Standard Sachen abgenommen werden, jedoch habe ich bisher
mit Klassenkapselung das Problem auch so prinzipiell unproblematisch in
den Griff bekommen. Jedoch habe ich auch noch nie eine Anwendung
gehabt, wo man, wie in einem anderen Posting geschrieben, SQL
Statements mit 150 Zeilen WHERE Bedingungen verfasst.
> Ezpdo hat den großen Nachteil, dass es nicht besonders flexibel ist u=
nd
> so zB
> für 1:N-Beziehungen zwischen Tabellen jeweils eine eigene Zwischentab=
elle
> anlegt, anstatt einfach eine Spalte in einer der Tabellen für einen
> Fremdschlüssel zu verwenden.
Nachdem was in EZPDO mitbekommen habe, sind die ganzen ORM Programme
nicht so flexibel, was jedoch auch in der Natur der Sache liegt.
>
> Propel scheint mir da weit fortschrittlicher zu sein. Dort beschreibt
> man in
> einem bloßen Xml-File den Aufbau der Datenbank und kann sich daraus z=
um
> Einen
> die Datenklassen für den PHP-Zugriff auf die Tabellen als auch die
> SQL-Statements zum Erzeugen der Db-Tabellen selbst generieren lassen.
Gerade *das* hat mich *etwas* abgeschreckt, ich fand die Beschreibung
in EZPDO wesentlich angenehmer. Jedoch bin ich über das Stadium des
"Hello World" Problem kaum hinaus gekommen, weil mir, wie gesagt, die
Einbindung in meine bestehenden Projekte fehlt.
> Kennt jemand von euch eine gute ORM Lösung für PHP, die womöglich=
besser
> als
> Propel zu verwenden ist?
Nein, ich sowieso nicht. Jedoch nehme ich davon erstmal noch Abstand,
denn meine PHP-Probleme löse ich auch noch mit ein paar
handgeschriebenen Statements an die SQL-Datenbank. Man muss ja auch in
=DCbung bleiben, oder?
Gruß
Anne
Re: PHP und ORM
Torsten Zühlsdorff schrieb:
> Helmut Hullen schrieb:
>
>> Du (thorny) meintest am 05.09.07:
>>
>>> [...] Oder Gettern und Settern verwenden. ;)
>>
>> Gibt es diesen Text auch in Hochdeutsch?
>
> Was stört dich daran?
Wer oder was sind "Gettern" und "Settern"?
Gruß. Claus
Re: PHP und ORM
Claus Reibenstein schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Helmut Hullen schrieb:
>>
>>> Du (thorny) meintest am 05.09.07:
>>>
>>>> [...] Oder Gettern und Settern verwenden. ;)
>>> Gibt es diesen Text auch in Hochdeutsch?
>> Was stört dich daran?
>
> Wer oder was sind "Gettern" und "Settern"?
Gettern/Settern werden Methoden eines Klasse genannt, du nur dazu da
sind, den Wert einer Objektvariable auszugeben oder diesen zu setzen.
Bsp:
class foo {
private $bar = 1;
private $foo = 2;
function getBar() {
return $this->bar;
}
function getFoo() {
return $this->foo;
}
# settern lasse ich jetzt außen vor
}
Es gibt diverse Glaubenskriege, ob man noch von Gettern und Settern
reden kann, wenn die Methoden noch etwas anderes erledigen, außer dem
stumpfen setzen oder zurückgeben.
Die meisten guten Programmierer kennt man daran, dass sie
Gettern/Settern meiden, da sie eine sehr schlechte Designentscheidung sind.
Gruß,
Torsten
Re: PHP und ORM
Torsten Zühlsdorff wrote:
> Claus Reibenstein schrieb:
>> Torsten Zühlsdorff schrieb:
>>
>>> Helmut Hullen schrieb:
>>>
>>>> Du (thorny) meintest am 05.09.07:
>>>>
>>>>> [...] Oder Gettern und Settern verwenden. ;)
>>>> Gibt es diesen Text auch in Hochdeutsch?
>>> Was stört dich daran?
>>
>> Wer oder was sind "Gettern" und "Settern"?
>
> Gettern/Settern werden Methoden eines Klasse genannt, du nur dazu da
> sind, den Wert einer Objektvariable auszugeben oder diesen zu setzen.
Woher kommt das 'n' am Ende?
>
> [snip]
>
> Die meisten guten Programmierer kennt man daran, dass sie
> Gettern/Settern meiden, da sie eine sehr schlechte Designentscheidung sind.
Eine sehr pauschale Aussage - jetzt aber -v, bitte.
regards,
Jens
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Jens Himmelrath schrieb:
> Torsten Zühlsdorff wrote:
>> Claus Reibenstein schrieb:
>>> Torsten Zühlsdorff schrieb:
>>>
>>>> Helmut Hullen schrieb:
>>>>
>>>>> Du (thorny) meintest am 05.09.07:
>>>>>
>>>>>> [...] Oder Gettern und Settern verwenden. ;)
>>>>> Gibt es diesen Text auch in Hochdeutsch?
>>>> Was stört dich daran?
>>>
>>> Wer oder was sind "Gettern" und "Settern"?
>>
>> Gettern/Settern werden Methoden eines Klasse genannt, du nur dazu da
>> sind, den Wert einer Objektvariable auszugeben oder diesen zu setzen.
>
> Woher kommt das 'n' am Ende?
Vom etwas unglücklich gewähltem Plural ;)
>> [snip]
>>
>> Die meisten guten Programmierer kennt man daran, dass sie
>> Gettern/Settern meiden, da sie eine sehr schlechte Designentscheidung
>> sind.
>
> Eine sehr pauschale Aussage - jetzt aber -v, bitte.
Getter- und Setter-Methoden projizieren die spezifische Implementation
einer Klasse auf ihre API. Der hauptsächliche "Sinn" einer Klasse
besteht aber in der Abstraktion (oder besser gesagt dem Verbergen)
spezifischer Implementationen. Aktionen sollen über die feste API einer
Klasse erfolgen. Bei Getter und Setter ist beides nicht gewährleistet,
da API und Implementation plötzlich voneinander abhängig sind und
Änderungen dementsprechend fatale Auswirkungen haben. Konkret: Ändern
sich die Objektvariablen, ändert sich plötzlich die API. In stark
typisierten Sprachen hat selbst die Änderung des zurückgegebenen
Datentypes gravierende Auswirkungen.
Aus diesem Punkt ergibt sich auch der ganze Rest. Die Vorteile die in
einer kleineren und stabilieren API zu finden sind, die auch
Implementationsänderungen übersteht.
APIs werden logischer, da man keine Interaktion zwischen verschiedenen
Eigenschaften mehr beachten muß. Gibt es z.b. eine Methode "save" und 5
verschiedene Eigenschaften, muß man sehr sehr umfangreich dokumentieren,
wie "save" in der Kombination verschiedener Eigenschaften arbeitet. Ohne
G/S gibt es genau eine Methode für eine Funktionalität. Das entspricht
auch im wesentlichen der Definition von "Funktion", die mit G/S häufig
gezwungenermaßen missachtet wird ;) (obwohl man sich natürlich darauf
berufen kann, dass das setzen und auslesen einer Variable eine Funktion
darstellt)
Durch das Fehlen von G/S werden APIs im übrigen auch wesentlich
zusammengeschrumpft und damit wesentlich übersichtlicher. Es reduziert
damit die Einarbeitungszeit, die Wartungsarbeit und den
Dokumentationsaufwand.
Die Flexibilität und Erweiterbarkeit wird durch die Abstraktion stark
erhöht und die Lesbarkeit steigt zum Teil.
Außerdem werden viele G/S nur dazu verwendet, auf private Eigenschaften
zuzugreifen, was die Kapselung ad absurdum führt.
Oh - und bevor ich es vergesse: Der Verzicht auf G/S ist sogar ein
"kleiner" Performancegewinn. Das aufrufen einer Methode ist wesentlich
teurer als der Zugriff auf eine Variable. Objekte, die nur aus G/S
bestehen und durch einen Array oder eine Sequenz ersetzt werden, sind um
den Faktor 8 bis 10 schneller.
Es läßt sich zwar noch mehr zu diesem Thema sagen, aber ich denke das
reicht erstmal. ;)
Gruß,
Torsten
Re: PHP und ORM
Franz Hofer schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Die meisten guten Programmierer kennt man daran, dass sie
>> Gettern/Settern meiden, da sie eine sehr schlechte Designentscheidung
>> sind.
>
> Ich hab mich auch mal mit Händen und Füßen gegen Getter und Setter
> gewehrt ...
>
> Das ergeht wohl jedem Anfänger so ;-)
Da ich jetzt gerade in einem anderen Beitrag die vielen negativen Punkte
aufgezählt habe, möchtest du vielleicht etwas positives über G/S
schreiben? ;)
Gruß,
Torsten
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Franz Hofer schrieb:
>> Mein Datenbanklayer z.B. reduziert den sich auf Datenbank beziehenden
>> Code auf 2 Zeilen. Die erste Zeile spezifiziert die zu nutzende
>> Datenbank (da ich ein Pooling verwende, welches es ermöglicht mit
>> einer unbegrenzten Anzahl an Datenbanken gleichzeitig zu arbeiten).
>> Die Zweite spezifiziert den Query an Hand eines Aliases und
>> übermittelt die benötigten Parameter. Fertig. Egal ob ich die
>> Datenbank portiere und alles umschreibe - ich muß diese eine Zeile
>> niemals ändern.
>
> Was du aber vergisst, dass du bei einer Änderung deiner Datenstruktur
> alle deine 50 verschiedenen Selects ändern musst, die zB die geänderte
> Tabelle über den alten Namen ansprechen.
Absolut richtig.
Hat allerdings auch den Vorteil, dass dadurch das der Layer
unterschiedliche DB-Typen unterstützt, ein Query genau angepaßt auf
einen Datenbanktypen abgefeuert werden kann. So kann z.b. ein anderes
Verhalten bei der Indexverwendung erzwungen werden oder aber Funktionen,
die anderes heißen oder gar nicht existieren (durch Nachbildung) dennoch
verwendet werden.
> Wenn du dich im SQL verschreibst, dann merkst du einen Tipp- oder
> Denkfehler erst zur Laufzeit, mit dem Rot-Unterstreichen noch während
> des Schreibens wird es eher nicht so gut aussehen.
*hüstel* Ich teste. Da gibt es keinen SQL-Typo. Da liegen die Fehler
dann doch eher woanders oder aber der Unittest entlarvt meine Idiotie.
Abgesehen davon lasse ich nahezu alle einfachen Queries generieren -
auch für verschiedene DB-Typen.
> Und überhaupt könnte es ohne so einem komplexen Zwischen-Layer vor der
> Datenbank kompliziert werden, wenn sich diese plötzlich zB von einer DB2
> zu einer Oracle gewechselt wird.
> Das wird zwar nicht so oft vorkommen, aber ausschließen kann man es auch
> nicht.
Nein, dass stimmt nicht. Der (aka mein) Layer geht sogar davon aus! SQL
Definitionen liegen in einfachen Textdateien, können beliebig
manipuliert, generiert, ausgetauscht werden. Für jeden DB-Typ gibt es
eine solche Spezifikation. So ist auch eine Arbeitsteilung gut möglich:
Möchte ich portieren übergebe ich bestehende Doku und Statements dem
Datenbankmeister und er wird es für andere DB-Typen portieren.
Dafür sind gerade mal 500 Zeilen Code notwendig.
> Und klar im Vorteil ist der, der bei einer solchen Änderung zwar von
> Aufwand erzählen kann, im Endeffekt die Sache dann aber doch ohne große
> und komplizierte Schritte erledigbar ist.
Kann ich ;)
>> Was mich an ORM-Implementationen standardmäßig stört sind Konstrukte
>> alla[1]:
>> "
>> $c = new Criteria();
>> $cton1 = $c->getNewCriterion(AuthorPeer::FIRST_NAME, "Leo");
>> $cton2 = $c->getNewCriterion(AuthorPeer::LAST_NAME,
>> array("Tolstoy", "Dostoevsky", "Bakhtin"),
>> Criteria::IN);
>
> Das kann je nach Anwendung wirklich lästig sein, aber da gibt es
> Besseres - nur nicht mit Propel (und derzeit für PHP überhaupt?).
Beispiel bitte. Oder spielst du auf Hibernate und das schreckliche HSQL
(oder ähnliches) an?
Gruß,
Torsten
Re: PHP und ORM
Torsten Zühlsdorff wrote:
> Jens Himmelrath schrieb:
>> Torsten Zühlsdorff wrote:
>>> Claus Reibenstein schrieb:
>>>> Torsten Zühlsdorff schrieb:
>>>>
>>>>> Helmut Hullen schrieb:
>>>>>
>>>>>> Du (thorny) meintest am 05.09.07:
>>>>>>
>>>>>>> [...] Oder Gettern und Settern verwenden. ;)
>>>>>> Gibt es diesen Text auch in Hochdeutsch?
>>>>> Was stört dich daran?
>>>>
>>>> Wer oder was sind "Gettern" und "Settern"?
>>>
>>> Gettern/Settern werden Methoden eines Klasse genannt, du nur dazu da
>>> sind, den Wert einer Objektvariable auszugeben oder diesen zu setzen.
>>
>> Woher kommt das 'n' am Ende?
>
> Vom etwas unglücklich gewähltem Plural ;)
>
>>> [snip]
>>>
>>> Die meisten guten Programmierer kennt man daran, dass sie
>>> Gettern/Settern meiden, da sie eine sehr schlechte Designentscheidung
>>> sind.
>>
>> Eine sehr pauschale Aussage - jetzt aber -v, bitte.
>
> Getter- und Setter-Methoden projizieren die spezifische Implementation
> einer Klasse auf ihre API. Der hauptsächliche "Sinn" einer Klasse
> besteht aber in der Abstraktion (oder besser gesagt dem Verbergen)
> spezifischer Implementationen. Aktionen sollen über die feste API einer
> Klasse erfolgen. Bei Getter und Setter ist beides nicht gewährleistet,
> da API und Implementation plötzlich voneinander abhängig sind und
> Änderungen dementsprechend fatale Auswirkungen haben. Konkret: Ändern
> sich die Objektvariablen, ändert sich plötzlich die API. In stark
> typisierten Sprachen hat selbst die Änderung des zurückgegebenen
> Datentypes gravierende Auswirkungen.
Ah, wir definieren also "Getter" und "Setter" nur unterschiedlich, genau
was vermeide ich nämlich durch das was ich so nenne.
Imo ist nämlich der direkte Zugriff auf Objekt-Eigenschaften das
eigentliche Übel - eine Implementierung von Gettern und Settern muss
also immer der API treu bleiben und eben bei einer internen Änderung
nicht mehr bloß "die eine Zeile" enthalten.
>
> [snip]
>
> Oh - und bevor ich es vergesse: Der Verzicht auf G/S ist sogar ein
> "kleiner" Performancegewinn. Das aufrufen einer Methode ist wesentlich
> teurer als der Zugriff auf eine Variable. Objekte, die nur aus G/S
> bestehen und durch einen Array oder eine Sequenz ersetzt werden, sind um
> den Faktor 8 bis 10 schneller.
Moment... mit dem direkten Variablenzugriff machst du dir deine schöne
unantastbare API wieder genauso kaputt wie mit dem was du Getter/Setter
nennst.
> Es läßt sich zwar noch mehr zu diesem Thema sagen, aber ich denke das
> reicht erstmal. ;)
In PHP gibt es ja sogar die Möglichkeit getXXX und setXXX per __call zu
implementieren, das ist dann lesbarer Code, weil man nur in Sonderfällen
wirklich die Methode implementieren muss. Leider muss man um zu
überprüfen ob es sich um öffentliche Eigenschaften handelt die
Reflection bemühen, was dann wieder die Performance verringert. Oder
kennt da jemand eine performante Lösung?
regards,
Jens
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Jens Himmelrath schrieb:
>> Getter- und Setter-Methoden projizieren die spezifische Implementation
>> einer Klasse auf ihre API. Der hauptsächliche "Sinn" einer Klasse
>> besteht aber in der Abstraktion (oder besser gesagt dem Verbergen)
>> spezifischer Implementationen. Aktionen sollen über die feste API
>> einer Klasse erfolgen. Bei Getter und Setter ist beides nicht
>> gewährleistet, da API und Implementation plötzlich voneinander
>> abhängig sind und Änderungen dementsprechend fatale Auswirkungen
>> haben. Konkret: Ändern sich die Objektvariablen, ändert sich plötzlich
>> die API. In stark typisierten Sprachen hat selbst die Änderung des
>> zurückgegebenen Datentypes gravierende Auswirkungen.
>
> Ah, wir definieren also "Getter" und "Setter" nur unterschiedlich, genau
> was vermeide ich nämlich durch das was ich so nenne.
Was konkret meinst du mit "unterschiedlich definieren"?
> Imo ist nämlich der direkte Zugriff auf Objekt-Eigenschaften das
> eigentliche Übel - eine Implementierung von Gettern und Settern muss
> also immer der API treu bleiben und eben bei einer internen Änderung
> nicht mehr bloß "die eine Zeile" enthalten.
Soweit die Theorie. Wie machst du das, wenn z.b. eine Eigenschaft wegfällt?
>> [snip]
>>
>> Oh - und bevor ich es vergesse: Der Verzicht auf G/S ist sogar ein
>> "kleiner" Performancegewinn. Das aufrufen einer Methode ist wesentlich
>> teurer als der Zugriff auf eine Variable. Objekte, die nur aus G/S
>> bestehen und durch einen Array oder eine Sequenz ersetzt werden, sind
>> um den Faktor 8 bis 10 schneller.
>
> Moment... mit dem direkten Variablenzugriff machst du dir deine schöne
> unantastbare API wieder genauso kaputt wie mit dem was du Getter/Setter
> nennst.
Die G/S API ist nicht unantastbar - siehe oben.
Gruß,
Torsten
Re: PHP und ORM
Franz Hofer schrieb:
>> Getter- und Setter-Methoden projizieren die spezifische Implementation
>> einer Klasse auf ihre API. Der hauptsächliche "Sinn" einer Klasse
>> besteht aber in der Abstraktion (oder besser gesagt dem Verbergen)
>> spezifischer Implementationen.
>
> Betrachtet man ORM, ist die Sache mit dem Sinn einer Klasse genau anders.
> Eine Implementation tut hier nichts zur Sache, ebensowenig wie die
> Klasse jegliche Form von Logik besitzen dürfte.
>
> Eine Klasse stellt hier nämlich nichts Anderes als ein Abbild einer
> Tabellendefinition (oder meinetwegen theoretisch auch einer "logischen"
> View) dar.
>
> Ein Objekt einer Klasse hingegen ist eine Datenzeile der entsprechenden
> Tabelle.
>
> Eine API-Änderung bei einer Datenmodell-Anpassung findet so nie statt -
> denn eine Tabellendefiniton ist keine API.
>
> Ändert sich die Tabelle, ändert sich auch die Klasse. Das ist aber auch
> richtig so, denn beide "Konstruke" stellen schließlich Identisches dar -
> nur 1x eben aus der Sicht einer relationalen Datenbank und ein anderes
> mal aus objektorientierter Sicht.
Sie stellen identisches dar? Du meinst sie repräsentieren es in anderer
Form.
*sehr umfangreiche Erklärung gelöscht* Nunja, ich sehe jetzt mal davon
ab, alles möglichst umfangreich zu erklären und versuche es mal auf ein
prägnantes Beispiel zu reduzieren:
Gegeben sei eine Applikation X mit 100.000 LoC. Es wird ORM verwendet.
In der Tabelle wird eine Spalte entfernt. Damit muß ein Getter aus der
Klasse entfernt werden. Und 15.000 LoC müssen angepaßt werden, da sie
diesen Getter aufrufen. Wo ist der Vorteil?
>> Durch das Fehlen von G/S werden APIs im übrigen auch wesentlich
>> zusammengeschrumpft und damit wesentlich übersichtlicher.
>
> Getter und Setter sollten dort normalerweise sowieso nichts verloren.
Wo? In der API? Da hast du Recht. Das ist aber kein Grund sie irgendwo
anders ohne genaue Überlegung einzubauen.
Gruß,Torsten
Re: PHP und ORM
Franz Hofer wrote:
> Jens Himmelrath schrieb:
>
>> In PHP gibt es ja sogar die Möglichkeit getXXX und setXXX per __call
>> zu implementieren, das ist dann lesbarer Code, weil man nur in
>> Sonderfällen wirklich die Methode implementieren muss. Leider muss man
>> um zu überprüfen ob es sich um öffentliche Eigenschaften handelt die
>> Reflection bemühen, was dann wieder die Performance verringert. Oder
>> kennt da jemand eine performante Lösung?
>
> Wenn die Entwicklungsumgebung gut ist, solltest du damit die Getter und
> Setter automatisch definieren lassen können.
Darum ging es mir nicht. Es macht den Code nur lesbarer (IMO), wenn
nicht zu jeder 2. Variable 2 Methoden stehen.
Wichtig ist das allerdings nicht.
regards,
Jens
Re: PHP und ORM
Torsten Zühlsdorff wrote:
> Jens Himmelrath schrieb:
>
>>> Getter- und Setter-Methoden projizieren die spezifische
>>> Implementation einer Klasse auf ihre API. Der hauptsächliche "Sinn"
>>> einer Klasse besteht aber in der Abstraktion (oder besser gesagt dem
>>> Verbergen) spezifischer Implementationen. Aktionen sollen über die
>>> feste API einer Klasse erfolgen. Bei Getter und Setter ist beides
>>> nicht gewährleistet, da API und Implementation plötzlich voneinander
>>> abhängig sind und Änderungen dementsprechend fatale Auswirkungen
>>> haben. Konkret: Ändern sich die Objektvariablen, ändert sich
>>> plötzlich die API. In stark typisierten Sprachen hat selbst die
>>> Änderung des zurückgegebenen Datentypes gravierende Auswirkungen.
>>
>> Ah, wir definieren also "Getter" und "Setter" nur unterschiedlich,
>> genau was vermeide ich nämlich durch das was ich so nenne.
>
> Was konkret meinst du mit "unterschiedlich definieren"?
>
>> Imo ist nämlich der direkte Zugriff auf Objekt-Eigenschaften das
>> eigentliche Übel - eine Implementierung von Gettern und Settern muss
>> also immer der API treu bleiben und eben bei einer internen Änderung
>> nicht mehr bloß "die eine Zeile" enthalten.
>
> Soweit die Theorie. Wie machst du das, wenn z.b. eine Eigenschaft wegfällt?
Ok, Beispiel ich habe eine in die Jahre gekommene Klasse "Auto" mit der
Eigenschaft "zündschlüsselSteckt" und weil Autos jetzt nicht mehr per
Zündschlüssel gestartet werden, sondern per Fernbedienung (Wasweißich),
steckt kein Schlüssl mehr, dafür gibt es jetzt die Eigenschaft
"fernbedienungInReichweite", also schreibe ich dann in
"getZünschlüsselstckt()" sowas wie "return
$this->fernbedienungInReichweite && !$this->alarmanlageAktiv;" oder so.
Ich sehe das Problem nicht.
regards,
Jens
Re: PHP und ORM
Jens Himmelrath schrieb:
> Ok, Beispiel ich habe eine in die Jahre gekommene Klasse "Auto" mit der
> Eigenschaft "zündschlüsselSteckt" und weil Autos jetzt nicht mehr per
"zündschlüsselSteckt" ist ein Getter? Oder Setter? Wie machst du das?
Ich erwarte da jetzt ein boolschen Wert.
> Zündschlüssel gestartet werden, sondern per Fernbedienung (Wasweißich),
> steckt kein Schlüssl mehr, dafür gibt es jetzt die Eigenschaft
> "fernbedienungInReichweite", also schreibe ich dann in
> "getZünschlüsselstckt()" sowas wie "return
> $this->fernbedienungInReichweite && !$this->alarmanlageAktiv;" oder so.
>
> Ich sehe das Problem nicht.
Und ich sehe keine G/S.
Gruß,
Torsten
Re: PHP und ORM
Torsten Zühlsdorff schrieb:
> Jens Himmelrath schrieb:
>
>> Ok, Beispiel ich habe eine in die Jahre gekommene Klasse "Auto" mit der
>> Eigenschaft "zündschlüsselSteckt" und weil Autos jetzt nicht mehr per
>
> "zündschlüsselSteckt" ist ein Getter? Oder Setter? Wie machst du das?
> Ich erwarte da jetzt ein boolschen Wert.
>
>> Zündschlüssel gestartet werden, sondern per Fernbedienung (Wasweißich),
>> steckt kein Schlüssl mehr, dafür gibt es jetzt die Eigenschaft
>> "fernbedienungInReichweite", also schreibe ich dann in
>> "getZünschlüsselstckt()" sowas wie "return
>> $this->fernbedienungInReichweite && !$this->alarmanlageAktiv;" oder so.
>>
>> Ich sehe das Problem nicht.
>
> Und ich sehe keine G/S.
Und als Ergänzung: Wer kommt auf die wirklich bekloppte Idee, dass beim
Aufruf von "getZündschlüsselSteckt" überprüft wird, ob eine
Fernbedingung in Reichweite ist und eine Alarmanlage aktiv? Eine API mit
solchen Überraschungen sollte verbrannt werden.
Gruß,
Torsten
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Franz Hofer schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Gegeben sei eine Applikation X mit 100.000 LoC. Es wird ORM verwendet.
>> In der Tabelle wird eine Spalte entfernt. Damit muß ein Getter aus der
>> Klasse entfernt werden. Und 15.000 LoC müssen angepaßt werden, da sie
>> diesen Getter aufrufen. Wo ist der Vorteil?
>
> Wenn es diese Spalte nicht mehr gibt, wird man an den verschiedensten
> 15.000 Stellen auch nicht mehr auf ihre Daten zugreifen können.
>
> Ist doch logisch. Und das ein zu großer Nachteil ist, den Zugriff auf
> eine gelöscht Spalte zu verlieren, dann sollte man vielleicht vom
> Löschen absehen.
Aha! Das bedeutet, dass dich Getter dazu zwingen können, so umfangreiche
Änderungen vorzunehmen, dass man lieber toten Code behält.
Und damit hätten wir eines der eklatanten Nachteile von G/S, die
offenlegen, warum G/S wirklich schlechtes Design sind.
Und damit sind wir bei den Settern:
Gegeben sei eine Applikation X mit 100.000 LoC. Es wird ORM verwendet.
In der Tabelle wird eine Spalte umbenannt. Damit muß ein Setter aus der
Klasse umbenannt werden. Und 15.000 LoC müssen angepaßt werden, da sie
diesen Setter verwenden. Wo ist der Vorteil?
>> Wo? In der API? Da hast du Recht. Das ist aber kein Grund sie irgendwo
>> anders ohne genaue Überlegung einzubauen.
>
> Wenn du Klassen hast, die nichts Anderes tun, als Daten zu halten (zB
> verschiedenste Strings und Zahlen) und dir auf Wunsch auszuliefern, dann
> kann man theoretisch natürlich direkt auf die Member, also ohne Getter
> und Setter zugreifen.
Das sind für gewöhnlich auch nur G/S - lediglich durch die Sprache an
sich implementiert.
Gruß,
Torsten
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Franz Hofer schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Aha! Das bedeutet, dass dich Getter dazu zwingen können, so
>> umfangreiche Änderungen vorzunehmen, dass man lieber toten Code behält.
>> Und damit hätten wir eines der eklatanten Nachteile von G/S, die
>> offenlegen, warum G/S wirklich schlechtes Design sind.
>
> Das wäre wohl ziemlicher Unfug, so etwas "totes" wie du es nennst im
> Programm zu lassen. Denn der Code kompiliert nicht mehr (bzw.
> "interpretiert" bei PHP) und so etwas wird man wohl oder übel löschen
> müssen.
Absolut richtig.
> Genauso wenn du ohne Getter in deinen 15.000 Stellen direkt auf eine
> Variable zugreifst, die gar nicht mehr existiert.
> Auch diese Zugriffe wirst du allesamt löschen müssen.
Ah - quell des Missverständnisses gefunden. Wer behauptet, dass ich
soetwas tun würde? Denn dieses Vorgehen ist genauso schlecht wie G/S.
>> Und damit sind wir bei den Settern:
>
>> Gegeben sei eine Applikation X mit 100.000 LoC. Es wird ORM verwendet.
>> In der Tabelle wird eine Spalte umbenannt. Damit muß ein Setter aus der
>> Klasse umbenannt werden. Und 15.000 LoC müssen angepaßt werden, da sie
>> diesen Setter verwenden. Wo ist der Vorteil?
>
> Was ist denn der Unterschied, wenn man anstatt des Setters aufzurufen
> direkt in die entsprechende Variable der Klasse schreibt, also .variable
> = wert ?
>
> Macht das Sinn? Nur weil man einen nicht existierenden Setter aufrufen
> würde wäre es besser, man würde eine nicht existierende Variable
> beschreiben? Wo ist hier der Vorteil?
Nirgends. Ich habe auch nirgends behauptet, so vorzugehen oder das
dieses Vorgehen von Vorteil wäre.
Gruß,
Torsten
Re: PHP und ORM
Franz Hofer schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Und als Ergänzung: Wer kommt auf die wirklich bekloppte Idee, dass
>> beim Aufruf von "getZündschlüsselSteckt" überprüft wird, ob eine
>> Fernbedingung in Reichweite ist und eine Alarmanlage aktiv? Eine API
>> mit solchen Überraschungen sollte verbrannt werden.
>
> Das ist jetzt ein Getter ;-)
Nein ;)
> Wenn es keinen steckenden Zündschlüssel mehr geben kann, wie du ja
> vorher mit den Änderungen andeuten wolltest, dann wird man auch nicht
> mehr darauf zugreifen können?
Richtig.
> Oder würdest du ohne Getter und Setter noch immer die nicht existierende
> Zündschlüsselvariable abfragen?
> Wenn nein, wie sollte dies dann ein Getter oder Setter können?
Natürlich würde ich nicht die Zündschlüsselvariable abfragen. Die gibt
es ja auch nicht mehr. Ein G/S wäre in diesem Falle genauso sinnfrei.
Ich würde z.B. eine Methode "kannStarten()" schreiben oder
"istVerriegelt()". Dazu bedarf es keinen G/S und egal wie man festlegt,
ob ein Auto gestartet werden kann oder verriegelt ist - die API ändert
sich nicht. Es muß sich die Funktionalität der Klasse ändern, damit die
API ungültig wird - nicht ihre Eigenschaften. Und der Umkehrschluß
daraus erklärt, warum G/S Designfehler sind.
Gruß,
Torsten
Re: PHP und ORM
Torsten Zühlsdorff wrote:
Hallo,
> Soweit die Theorie. Wie machst du das, wenn z.b. eine Eigenschaft
> wegfällt?
- Setter/Getter als obsolete erklären -> Notice in PHP werfen
- Gleich oder in späteren Versionen den Setter/Getter ganz entfernen=
..
Wer jetzt versucht ihn noch zu benutzen erhält eine Fehlermeldung
inklusive Erklärung und weiß, was geändert werden muss.
tschuess
[|8:)
Re: PHP und ORM
Torsten Zühlsdorff wrote:
Hallo,
Ich verstehe unter Setter/Getter Methoden zum Setzen/Abfragen von
Eigenschaften.
> Getter- und Setter-Methoden projizieren die spezifische Implementatio=
n
> einer Klasse auf ihre API. Der hauptsächliche "Sinn" einer Klasse
> besteht aber in der Abstraktion (oder besser gesagt dem Verbergen)
> spezifischer Implementationen.
Wie sieht die Alternative aus?
a) $obj->setEMailAddress('john [at] example.com'); // Setter
b) $obj->emailAdress =3D 'john [at] example.com'; // Ohne Setter
Durch b) gewinnt man kein mehr an Abstraktion, während man beim Sett=
er
die Möglichkeit hat die E-Mail-Adresse zu überprüfen und per Exc=
eption
abzulehnen.
Umstritten ist AFAIK in erster Linie die Existenz von expliziten
setXXX(), getXXX()-Methoden. Das geht mit Properties (in etwa
__SET, __GET in PHP), bei der man dann erst wenns nötig eine
entsprechende Methode schreibt besser.
> Eigenschaften mehr beachten muß. Gibt es z.b. eine Methode "save" u=
nd 5
> verschiedene Eigenschaften, muß man sehr sehr umfangreich dokumenti=
eren,
> wie "save" in der Kombination verschiedener Eigenschaften arbeitet. O=
hne
> G/S gibt es genau eine Methode für eine Funktionalität.
Das klingt nach einem sehr umfangreichen und unflexiblen innerhalb
der save()-Methodenparameter versteckten Setter oder nach mail(), wo
es keine =DCberprüfung der Parameter gibt und man sehr leicht fehler=
hafte
E-Mails produzieren kann.
Die Frage ist IMHO eher wo benutzt man Setter/Getter und wo nicht?
Zum Zeichnen von 2D-Objekten ist es einfacher die Parameter direkt
anzugeben als Setter/Getter zu benutzen.
drawRect(top, left, width, height);
statt
$rect =3D createRect();
$rect->setTop(10);
$rect->setLeft(20);
....
$rect->draw();
Für weitere Eigenschaften wie Farben, Strichdicke, Füllmuster ist
es sinnvoll Getter/Setter zu verwenden, die man dann bequem
erweitern kann und auch für alle anderen Zeichenoperationen gelten
könnten.
$canvas->setColour('red'); // Umrissfarbe
$canvas->drawRect(top, left, width, height);
Per =DCberladen der Methoden oder mit benannten Parametern kann man be=
ide
Varianten auch kombinieren.
$canvas->setColour('red'); // Umrissfarbe
$canvas->drawRect(top, left, width, height, strike =3D> 5.0, fill =3D=
>
'blue');
tschuess
[|8:)
Re: PHP und ORM
Sven Drieling schrieb:
>> Soweit die Theorie. Wie machst du das, wenn z.b. eine Eigenschaft
>> wegfällt?
>
> - Setter/Getter als obsolete erklären -> Notice in PHP werfen
Wäre möglich. Bei einem anderem geschilderten Beispiel hätten wir so
15.000 Notices pro Aufruf.
> - Gleich oder in späteren Versionen den Setter/Getter ganz entfernen.
> Wer jetzt versucht ihn noch zu benutzen erhält eine Fehlermeldung
> inklusive Erklärung und weiß, was geändert werden muss.
Das klingt zwar gut, ist in Realität jedoch kaum umsetzbar. Denn
Quellcode der z.B. Getter verwendet, wird mit diesen Daten arbeiten. Da
diese nun fehlen, wird der Programmfluß völlig zerstört. Natürlich würde
ein guter Programmierer überprüfen, ob tatsächlich die benötigten Daten
vom Getter zurückkommen und falls dem nicht so ist, den Fehler behandeln
- in diesem Falle ändert das aber nichts daran, dass mit dem Wegfall
eines Datums das vollständige Programm zerstört werden kann.
Gruß,
Torsten
Re: PHP und ORM
Sven Drieling schrieb:
> Ich verstehe unter Setter/Getter Methoden zum Setzen/Abfragen von
> Eigenschaften.
Ich auch.
>> Getter- und Setter-Methoden projizieren die spezifische Implementation
>> einer Klasse auf ihre API. Der hauptsächliche "Sinn" einer Klasse
>> besteht aber in der Abstraktion (oder besser gesagt dem Verbergen)
>> spezifischer Implementationen.
>
> Wie sieht die Alternative aus?
Die nutzt du bereits weiter unten: Die Funktionalität bei der Klasse
belassen und Parameter verwenden. Oder CRC (classes, responsibilities,
collaboration) verwenden.
> Die Frage ist IMHO eher wo benutzt man Setter/Getter und wo nicht?
Juhu! Du hast den Nagel auf den Punkt getroffen. Deine Beispiele sind
vollständig richtig. Das ist der Punkt, auf den ich hinaus wollte. :)
Eine generelle Verwendung von G/S durch z.b. gedankenlose Anwendung von
ORM ist ein absoluter Designfehler. Der Code stinkt und ist so gut wie
nicht wartbar.
Hat man aber Klassen, die z.b. Zustandsmodelle simulieren, sind G/S
absolut zulässig und sogar eine Erleichterung.
Aber es verhält sich mit G/S wie bei eval und goto - zu predigen, dass
es böse[tm] ist, ist einfacher, als auf die wenigen guten
Anwendungsbeispiele zu verweisen.
Gruß,
Torsten
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Post removed (X-No-Archive: yes)
Re: PHP und ORM
Franz Hofer schrieb:
> Torsten Zühlsdorff schrieb:
>
>> Wäre möglich. Bei einem anderem geschilderten Beispiel hätten wir so
>> 15.000 Notices pro Aufruf.
>
> Ich wusste gar nicht, dass PHP derart schlecht ist und nicht mit so
> vielen Notices zurecht kommt.
Wer hat das behauptet?
Aber es sollte dem Programmierer arg zu denken geben, wenn da pro Aufruf
15.000 Notices erscheinen.
>> Das klingt zwar gut, ist in Realität jedoch kaum umsetzbar. Denn
>> Quellcode der z.B. Getter verwendet, wird mit diesen Daten arbeiten.
>> Da diese nun fehlen, wird der Programmfluß völlig zerstört. Natürlich
>> würde ein guter Programmierer überprüfen, ob tatsächlich die
>> benötigten Daten vom Getter zurückkommen und falls dem nicht so ist,
>> den Fehler behandeln - in diesem Falle ändert das aber nichts daran,
>> dass mit dem Wegfall eines Datums das vollständige Programm zerstört
>> werden kann.
>
> Das ist völlig ident mit der Situation, wo kein Getter verwendet,
> sondern direkt auf eine Member-Variable oder auch einen Wert eines
> Arrays zugegriffen wird,
Wie kommst du eigentlich ständig darauf, zu behaupten, dass das die
Lösung wäre? Es ist doch offensichtlich, dass dem nicht so ist.
> und hat deshalb rein gar nichts damit zu tun, dass ein Getter verwendet
> wird.
Wenn sie identisch sind, wohl schon, oder?
Gruß,
Torsten