2009-08-08 2 views
3

Ich denke, dass ich das OOP-Paradigma auf der Basisebene habe, aber es fällt mir schwer, den richtigen Weg zum Suchen von Datensätzen in einer Datenbank zu finden. Ich vermute, das ist, weil ich nicht wirklich OOP so viel wie ich denke, ich ...Wie arbeite ich mit Sammlungen von Objekten? Oder ruft ein Objekt eine Sammlung ähnlicher Objekte ab?

Die Anwendung, die ich versuche zu schreiben ist ein Warenkorb, weil es viele gute Kandidaten für Objekte hat. Das Objekt, mit dem ich arbeiten werde, ist ein Produkt (ja, das ist sehr primitiv).

<?php 
    class Product 
    { 
     public $id = 0; 
     public $name = ''; 
     public $price = 0; 

     function __construct($id) 
     { 
      // if $id exists try to retrieve 
      // a product with $id 
      // else create a new product 
      // and set $this->id 
     } 
    } 

    $product = new Product(); 
    echo $product->name; 
?> 

Einfach genug. Aber jetzt möchte ich mehrere Produkte (für eine Suchergebnisseite) nachschlagen und bin mir nicht sicher, wie ich damit umgehen soll.

Meine Neigung ist, eine andere Klasse zu schreiben, die einige Eingaben nimmt und eine SQL-Abfrage ausführt, die nur eine Liste von Produkt-IDs zurückgibt. Ich würde dann diese Ergebnisse durchlaufen und für jedes Produkt ein Produktobjekt erstellen. Ich könnte dann das Array von Objekten durchlaufen und meine Suchergebnisseite erstellen.

Ich bin mir nicht sicher warum, aber das fühlt sich einfach nicht richtig an. Scheint zu viel Arbeit, weil ich zuerst eine Abfrage mache, um nur eine Liste von Produkt-IDs zu erhalten, und dann weitere Abfragen, um die Daten jedes Produkts zu erhalten. Es wäre viel schneller, wenn nur eine Abfrage durchgeführt würde, die alle Daten zurückgab, die ich brauche.

Was ist das Richtige? Etwas anderes vielleicht?

Antwort

2

Schreiben Sie eine Produktklasse, die die Datenbank nicht kennt (schwer zu glauben, aber Produkte können existieren ohne eine Datenbank;)) und eine Klasse, die Produktobjekte aus einem Datenbankergebnis erstellen kann.

+1

Von "ist der Datenbank nicht bewusst" meinst du, dass das Objekt sich nicht mit Daten füllen sollte? – barophobia

+0

Zumindest nicht durch Abfrage der Datenbank selbst im Konstruktor. Vielleicht gibt es eine statische Methode, die ein Array (oder eine andere Sammlung) eines Objekts aus einer Datenquelle von "Datensätzen", z. ein Iterator. PDO-Ergebnisse können als Iterator verwendet werden; Die Methode muss nicht einmal wissen, dass sie das Ergebnis einer Datenbankabfrage ist. – VolkerK

0

Ich denke, Sie denken auf die richtigen Linien - eine Sache jedoch, warum nur IDs zurückgeben, das Array (oder Liste) der passenden Produkte zurück.

Wie wäre es mit einem ProductFinder, der über Abfragemethoden verfügt, Parameter sind Definitionen von Produkten, wobei der Rückgabetyp eine Sammlung von Produkten ist.

Sie können dann sehen, dass der ProductFinder auch Verantwortung für das Erstellen von Produkten (Einfügen in die DB), das Löschen von Produkten usw. übernehmen kann. Daher kennt das Produkt selbst wenig oder nichts über die db. Der ProductFinder erhält dann möglicherweise einen etwas anderen Namen wie ProductKeeper oder ProductHome.

Wenn Sie eine Reihe von Entitäten zusätzlich zu Produkten haben, dann können Sie feststellen, dass ihre "Keepers" eine Menge Code gemeinsam haben, bevor Sie mit einem Persistenz-Framework enden. Es scheint bei least one already für PHP zu sein, ich schlage vor, Sie sehen es sich an.

+0

Wer würde die Daten eines Produkts bearbeiten und die erforderlichen db-Aufrufe vornehmen? ProductKeeper oder Produkt? – barophobia

+0

ProductKeeper (oder das Persistenz-Framework). Wenn Sie also verschiedene Datenbanken oder andere Persistenzmechanismen verwenden, können Sie einfach unterschiedliche Keepers haben. – djna

2

Die Zuordnung von einer Datenbank zu einer objektorientierten Anwendung ist nicht trivial. Es gibt verschiedene Möglichkeiten, dies zu erreichen, aber eine einfache Strategie besteht darin, eine Entitätsklasse (Produkt) und eine Gateway-Klasse zu haben (könnte verschiedene Dinge heißen, aber normalerweise ProductGateway oder ProductFinder). Die Gateway-Klasse hat Zugriff auf die Datenbank und sie kann wie Sie Entitäten abrufen und initialisieren. Die gleiche Klasse würde auch wissen, wie das Objekt zurück auf die Datenbank abgebildet wird.

Zum Beispiel:

class ProductGateway { 
    function getProductById($id) { 
    $result = $this->db->query("select * from products where id = ?", $id); 
    return new Product($result->next()); 
    } 
    function save($product) { 
    if ($product->getId()) { 
     return $this->update($product); 
    } else { 
     return $this->insert($product); 
    } 
    } 
    ... 
} 

Der Punkt ist, dass Sie auf Anwendungsebene Code nicht wissen muss, wenn das Produkt aus einer Datenbank kam oder nicht. Es ändert nur das Entitätsobjekt und belässt es für das Gateway, um mit Persistenz umzugehen.

0

Vermeiden Sie die Verwendung bereits existierender Frameworks für den Umgang mit Datenbanken in OOP. Zend_Db hat verschiedene Benutzungsmethoden, vor allem die Table Gateway/Row Gateway Methode, wie oben beschrieben. TableGateway soll Abfragen ausführen und Zeilen zurückgeben. Zeilen stellen eine einzelne Zeile dar und können unabhängig voneinander bearbeitet werden.

Wenn Sie eine Abfrage für viele Zeilen durchführen, ist eine separate Klasse, die die Tabelle (oder sogar 'virtuelle' Tabelle im Falle eines komplexen Joins) darstellt, der sauberste Weg, um die Bedenken dieser Tabelle und der einzelne Reihen trennen sich.

Verwandte Themen