Hallo,
ich habe mal wieder eine Verständnisfrage zu OOP [FONT=Wingdings][FONT=Wingdings][/FONT][/FONT]
Diesmal geht es um die konkrete Implementierung einer Assoziation zwischen zwei Klassen Kunde und Kundenliste.
Kundenliste -> Kunde (Kundenliste enthält Kunde)
Mal angenommen ich habe eine Klasse Kunde:
(die Beispiele sind bewusst sehr einfach gehalten und dienen wirklich nur der Veranschaulichung des Problems)
Nun kann ich bequem ein neues Kundenobjekt erzeugen und mir z.B. die Lebenserwartung anzeigen lassen:
Jetzt möchte ich noch eine weitere Klasse erstellen mit der sich bestimmte Daten mehrerer Kunden in einer Tabelle/Liste darstellen lassen.
Lösung 1
Bei dieser Lösung wird in der Methode display() jedes mal ein neues Kundenobjekt erzeugt.
Vorteil:
ich arbeite mit einem Kundenobjekt und kann direkt auf seine Eigenschaften und Methoden zugreifen. Das ist sehr bequem und ich muss mich um die Implementierung der Kunden-Methoden nicht kümmern
Nachteil:
Jedes mal wenn ich ein neues Kundenobjekt erzeuge greife ich auf die DB zu um seine Daten zu holen. Das ist in diesem Fall sehr ineffizient und verursacht einen unnötigen DB-Overhead.
Lösung 2:
Vorteil:
Der DB-Overhead ist weg. Die Methode display() ist somit effizienter als bei Lösung 1
Nachteil:
Ich kann nicht mehr auf die Methoden und Eigenschaften des Kunden bequem über ein Kundenobjekt zugreifen. Schlimmer noch, ich muss die Methoden des Kundenobjektes die ich für die Darstellung in der Liste benötige neu implementieren. Jede Änderungen in der Klasse Kunde hat somit auch eine entsprechende Anpassung in der Klasse Kundenliste zur Folge.
Beide Lösungsansätze haben meiner Meinung nach zu große Nachteile und sind nicht wirklich zufriedenstellend. Wie macht man es in OOP aber richtig? Wie aggregiert oder injiziert man ein Kundenobjekt in die Klasse Kundenliste ohne dabei zusätzlich den DB-Overhead zu verursachen und ist es überhaupt der richtige Ansatz das Problem so zu lösen, oder würde man es mit OOP ganz anders angehen?
Eine Idee hätte ich da noch, wenn der Konstruktor von Kunde wie folgt ergänz wird:
dann ließe sich auch ein „leeres“ Kundenobjekt so eine Art Prototyp erstellen, der mit entsprechenden setter-Methoden nachträglich in der Klasse Kundenliste mit Daten gefüllt werden könnte:
Ok, damit könnte man den DB-Overhead komplett vermeiden und hätte gleichzeitig den Vorteil, daß man bequem mit dem Kundenobjekt arbeiten könnte, allerdings müsste man dann sicherstellen, daß man dem Kundenobjekt auch wirklich alle Daten übergibt, das wiederum würde bei Umfangreichen Objekten mit vielen Eigenschaften schnell relativ aufwendig werden und könnte leicht zu inkonsistenten Objekten führen.
Was wäre bei dieser Problemstellung nun die richtige Vorgehensweise im Sinne des objektorientierten Designs?
jack
ich habe mal wieder eine Verständnisfrage zu OOP [FONT=Wingdings][FONT=Wingdings][/FONT][/FONT]
Diesmal geht es um die konkrete Implementierung einer Assoziation zwischen zwei Klassen Kunde und Kundenliste.
Kundenliste -> Kunde (Kundenliste enthält Kunde)
Mal angenommen ich habe eine Klasse Kunde:
PHP-Code:
class Kunde {
protected $kundennummer = null;
protected $name = null;
protected $alter = null;
protected $gesundheit = null;
public function __construct($kundennummer) {
// Kundendaten aus DB Laden und Eigenschaften setzen
// SELECT .... FROM Kunde WHERE id=$kundenummer
$this->kundenummer = $db_row["kundenummer"];
$this->name = $db_row["name"];
// usw...
}
public function getLebenserwartung() {
//Algorithms zur Berechnung der Lebenserwartung
// Lebenserwartung wird nicht in der DB gespeichert (dient nur der Veranschaulichung)
return 100-($this->alter*$this->gesundheit);
}
}
Nun kann ich bequem ein neues Kundenobjekt erzeugen und mir z.B. die Lebenserwartung anzeigen lassen:
PHP-Code:
$ulli = new Kunde(10);
echo $ulli->getLebenserwartung();
Lösung 1
PHP-Code:
class Kundenliste {
private $sqlResult = null;
punblic function __construct($kdnr_von,$kdnr_bis) {
//select-abfrage auf die Kundendaten z.B;
// SELECT * FROM Kunde WHERE id>=$kdnr_von && id<=$kdnr_bis
$this->sqlResult = $ergebnisskennung_der_abfrage;
}
public function display() {
foreach($this->sqlResult as $row) {
$kunde = new Kunde($row["kundenummer"]);
echo $kunde->name.", Lebenserwartung: ".$kunde->getLebenserwartung();
}
}
}
Vorteil:
ich arbeite mit einem Kundenobjekt und kann direkt auf seine Eigenschaften und Methoden zugreifen. Das ist sehr bequem und ich muss mich um die Implementierung der Kunden-Methoden nicht kümmern
Nachteil:
Jedes mal wenn ich ein neues Kundenobjekt erzeuge greife ich auf die DB zu um seine Daten zu holen. Das ist in diesem Fall sehr ineffizient und verursacht einen unnötigen DB-Overhead.
Lösung 2:
PHP-Code:
class Kundenliste {
private $sqlResult = null;
punblic function __construct($kdnr_von,$kdnr_bis) {
//select-abfrage auf die Kundendaten z.B;
// SELECT .... FROM Kunde WHERE id>=$kdnr_von && id<=$kdnr_bis
$this->sqlResult = $ergebnisskennung_der_abfrage;
}
public function display() {
foreach($this->sqlResult as $row) {
echo $row["name"].", Lebenserwartung: ".$this->getLebenserwartung($row["alter"],$row["gesundheit"]);
}
}
protected function getLebenserwartung($alter,$gesundheit) {
return 100-($alter*$gesundheit);
}
}
Der DB-Overhead ist weg. Die Methode display() ist somit effizienter als bei Lösung 1
Nachteil:
Ich kann nicht mehr auf die Methoden und Eigenschaften des Kunden bequem über ein Kundenobjekt zugreifen. Schlimmer noch, ich muss die Methoden des Kundenobjektes die ich für die Darstellung in der Liste benötige neu implementieren. Jede Änderungen in der Klasse Kunde hat somit auch eine entsprechende Anpassung in der Klasse Kundenliste zur Folge.
Beide Lösungsansätze haben meiner Meinung nach zu große Nachteile und sind nicht wirklich zufriedenstellend. Wie macht man es in OOP aber richtig? Wie aggregiert oder injiziert man ein Kundenobjekt in die Klasse Kundenliste ohne dabei zusätzlich den DB-Overhead zu verursachen und ist es überhaupt der richtige Ansatz das Problem so zu lösen, oder würde man es mit OOP ganz anders angehen?
Eine Idee hätte ich da noch, wenn der Konstruktor von Kunde wie folgt ergänz wird:
PHP-Code:
public function __construct($kundennummer) {
if($kundennummer) {
// Kundendaten aus DB Laden und Eigenschaften setzen
// SELECT .... FROM Kunde WHERE id=$kundenummer
$this->kundenummer = $DB["kundenummer"];
// usw...
}
}
PHP-Code:
public function display() {
foreach($this->sqlResult as $row) {
$kunde = new Kunde(false);
$kunde->setName($row["name"]);
$kunde->setAlter($row["alter"]);
// usw
echo $kunde->name.", Lebenserwartung: ".$kunde->getLebenserwartung();
}
}
Was wäre bei dieser Problemstellung nun die richtige Vorgehensweise im Sinne des objektorientierten Designs?
jack
Kommentar