Tach!
Die Methode, einen Artikel in einen Einkaufskorb zu legen, gehört IMHO in die Warenkorb-Klasse und nicht in die Artikel-Klasse.
Ja, klar. Die Artikel-Klasse bedient sich dieser Methode (z.B. Delegation).Warum? In der realen Welt legt sich weder ein Artikel selbst in den Warenkorb, noch greift der Warenkorb ins Regal. Es gibt am Ende eine dritte Instanz, die einen Artikel nimmt und dem Warenkorb übergibt.
nicht:
$warenKorb->put($warenRegal->getProductById(<prodID>);
???
Abgesehen davon, dass ich bei hotti nie so richtig weiß, ob er Fachbegriffe richtig verwendet oder sie nach Gutdünken verwendet, vor allem wenn er sie nur als Stichwortbrocken in die Runde wirft, sieht das bei ihm vielleicht eher so aus (die Initialisierung von $this->warenkorb mit einem Warenkorb-Objekt mal weggelassen):
class Artikel {
var $warenkorb;
function Kunde_will_haben() {
$this->warenkorb->add($this);
}
}
In deinem Codebeispiel hingegen wissen weder der Warenkorb noch das Regal zwangsläufig etwas voneinander. Die dritte Instanz ist hier der Code, der anzunehmenderweise im Kontext eines Kunden läuft.
Man kann hier nicht alle Einzelheiten mit der realen Welt vergleichen oder diese abbilden. Denn dann müsste man zum Beispiel das Äquivalent programmieren, das die gesamte Oberfläche eines Produkts absucht, um die Artikelnummer oder einen aufgedruckten Preis zu finden. Hier ist es zur Vereinfachung zulässig, wenn man allen Artikeln ein gemeinsames Merkmal in Form eines Interfaces (oder bei nicht sehr unterschiedlichem Warenbestand einer Basisklasse) mitgibt. Der Warenkorb ist bei strenger Typisierung also auch so implementiert, dass er nur Objekte mit diesem Interface (oder der Basisklasse) annimmt.
In der realen Welt sind derzeit die notwendigen technischen Voraussetzugen noch nicht implementiert, so dass der Warenkorb weder seinen Inhalt kennt, noch eine Summe der Preise bilden kann. Hier weicht die elektronische Welt vor und schafft sich ihre eigenen Beziehungen der Dinge untereinander. Diese sollten aber logisch sinnvoll aufgebaut sein.
stattdessen
$user->putToWarenkorb(getProductById(<prodID>);
mit
class User {
private var $warenKorb = new Warenkorb();
public function putToWarenkorb($article) {
$this->warenKorb->put($article);
}
}
>
> ?
Unter der Annahme, dass deine "nicht"-Codezeile auch im Kontext eines Kunden läuft - der Warenkorb wird sicherlich nicht herrenlos programmiert sein -, sehe ich keinen grundlegenden Unterschied zur "stattdessen"-Variante.
dedlfix.