2008-09-28 5 views
2

Ich erstelle ein ORM in PHP, und ich habe eine Klasse 'ORM', die im Grunde ein Objekt erstellt, das einer Datenbanktabelle entspricht (ich strebe ähnliche/gleiche Funktionalität wie ein ActiveRecord-Muster an.) ORM selbst erweitert 'Database', die die Datenbankverbindung einrichtet.Sollte ich diese Klasse erweitern? (PHP)

So kann ich nennen:

$c = new Customer(); 
$c->name = 'John Smith'; 
$c->save();

Die ORM-Klasse stellt diese Funktionalität (legt die Klasseneigenschaften auf, bietet save(), finden(), findAll() usw. Methoden) und des Kunden erstreckt ORM. In der Zukunft möchte ich jedoch dem Kunden (oder einem anderen von mir erstellten Modell) zusätzliche öffentliche Methoden hinzufügen. Soll das also ORM erweitern oder nicht?

Ich weiß, dass ich hier nicht viele Informationen zur Verfügung gestellt habe, aber hoffentlich ist dies auf eine vage Erklärung verständlich, im Gegensatz zum Posten von mehr als 300 Zeilen Code.

+0

Noch ein ORM? Wird das auch veröffentlicht? Ich bin neugierig! – Till

+0

Es könnte eine Idee sein, das "PHP" im Titel und den Tags zu entfernen, da dies eine ziemlich allgemeine Frage zu OOP und nichts speziell zu PHP ist. – nickf

+0

'sprachunabhängig' hinzugefügt, da die Frage zwar PHP referenziert, aber eher eine OOP-Frage ist. – Chris

Antwort

3

Ich stimme den anderen Antworten hier zu - legen Sie die zusätzlichen Methoden in eine Nachkommenklasse. Ich würde jedoch auch ein Sternchen hinzufügen: Jedes Mal, wenn Sie die Klasse mit zusätzlichen Methoden erweitern, denken Sie darüber nach, was Sie mit der Erweiterung erreichen möchten, und überlegen Sie, ob es verallgemeinert und in die Elternklasse zurückgearbeitet werden kann . Zum Beispiel:

// Customer.class.php 
function getByName($name) { 
    // SELECT * FROM `customer` WHERE `name` = $name 
} 

// ** this could instead be written as: ** 
// ORM.class.php 
function getByField($field, $value) { 
    // SELECT * FROM `$this->table` WHERE `$field` = $value 
} 
1

Ja, platzieren Sie Ihre Geschäftslogik in einer abgeleiteten Klasse. Dies ist ein sehr häufiges Muster, das in den meisten Data Access Layers-Generierungsframeworks zu sehen ist.

2

Sie denken sicher richtig, um Ihre Geschäftslogik in eine neue Klasse außerhalb Ihres 'ORM' zu bringen. Anstatt die ORM-Klasse einfach zu erweitern, würde ich sie stattdessen lieber mit einer neuen Wertobjektklasse kapseln, um einen zusätzlichen Grad an Freiheit von Ihrem Datenbankentwurf zu bieten, damit Sie sich die Klasse als reines Geschäftsobjekt vorstellen können.

0

Sie sollten die ORM-Klasse unbedingt erweitern. Verschiedene Dinge sollten Objekte verschiedener Klassen sein. Kunden unterscheiden sich sehr von Produkten, und die Unterstützung beider in einer einzigen ORM-Klasse wäre unnötig und würde den Zweck der OOP vollständig zunichte machen.

Eine weitere nette Sache ist es, Hooks für vor dem Speichern, nach dem Speichern usw. hinzuzufügen. Diese geben Ihnen mehr Flexibilität, da Ihre ORM-Erweiterungsklassen vielfältiger werden.

0

Angesichts meiner begrenzten Kenntnisse von PHP bin ich nicht sicher, ob das verwandt ist, aber wenn Sie versuchen, viele Geschäftsobjekte zu erstellen, könnte dies ein unglaublich zeitaufwändiger Prozess sein. Vielleicht sollten Sie Frameworks wie CakePHP und andere mögen. Das ist nett, wenn Sie noch dabei sind, Ihre Geschäftslogik zu erstellen.

2

Nein. Sie sollten Komposition statt Vererbung verwenden. Siehe das folgende Beispiel:

class Customer { 
    public $name; 
    public function save() { 
     $orm = new ORM('customers', 'id'); // table name and primary key 
     $orm->name = $this->name; 
     $orm->save(); 
    } 
} 

Und ORM Klasse nicht Database verlängern sollte. Die Zusammensetzung ist wiederum in diesem Anwendungsfall am besten geeignet.

+0

Zusammensetzung ist ein großes Nein, nein in OO-Design. – Till

+0

haben Sie weitere Informationen darüber, warum dies besser als Vererbung ist? – nickf

+1

Vererbung ist eine "ist" Beziehung, während Zusammensetzung ist "hat" Beziehung. Daher ist es falsch anzugeben, dass "ORM eine Datenbankverbindung ist". Stattdessen sollte "ORM hat eine Datenbankverbindung" angegeben werden. –

0

Ich habe es so in meinem Pork.dbObject gelöst. Stellen Sie sicher, es zu überprüfen und snag einige der braincrunching habe ich schon: P

class Poll extends dbObject // dbObject is my ORM. Poll can extend it so it gets all properties. 
{ 
     function __construct($ID=false) 
     { 
      $this->__setupDatabase('polls', // db table 
       array('ID_Poll' => 'ID', // db field => object property 
         'strPollQuestion' => 'strpollquestion', 
         'datPublished' => 'datpublished', 
         'datCloseDate' => 'datclosedate', 
         'enmClosed' => 'enmclosed', 
         'enmGoedgekeurd' => 'enmgoedgekeurd'), 
         'ID_Poll', // primary db key 
         $ID); // primary key value 
     $this->addRelation('Pollitem'); //Connect PollItem to Poll 1;1 
     $this->addRelation('Pollvote', 'PollUser'); // connect pollVote via PollUser (many:many) 


     } 

function Display() 
{ 

// do your displayíng for poll here: 
    $pollItems = $this->Find("PollItem"); // find all poll items 
    $alreadyvoted = $this->Find("PollVote", array("IP"=>$_SERVER['REMOTE_ADDR'])); // find all votes for current ip 
} 

Beachten Sie, dass auf diese Weise, eine beliebige Datenbank oder ORM-Funktionalität von der Poll-Objekt abstrahiert entfernt. Es braucht nicht zu wissen. Nur die Setup-Datenbank, um die Felder/Mappings zu verbinden. und die addRelation, um die Beziehungen zu anderen dbObjects zu verknüpfen.

Auch die DbObject-Klasse weiß nicht viel über SQL. Select/Join-Abfragen werden von einem speziellen QueryBuilder-Objekt erstellt.

0

Sie denken hier definitiv an die richtige Linie mit der Vererbung.

Wenn Sie ein ORM bauen, nur um eines zu bauen (oder weil Sie die Art und Weise, wie andere Dinge handhaben, nicht mögen), dann sollten Sie sich ein vorgefertigtes ORM ansehen, das die meisten generieren kann Ihr Code direkt aus Ihrem Datenbankschema. Es spart Ihnen Bootsladungen an Zeit. CoughPHP ist derzeit mein Favorit.