Frage

Ich bin auf der Suche nach einem guten, sauberen Weg, um die Tatsache zu gehen, dass PHP5 noch keine Mehrfachvererbung nicht unterstützt. Hier ist die Klassenhierarchie:

Nachricht
  - Textmessage
    -------- InvitationTextMessage
  - Emailmessage
    -------- InvitationEmailMessage

Die beiden Arten von Einladung * Klassen haben viel gemeinsam; Ich würde gerne eine gemeinsame Elternklasse, Einladung haben, dass sie beide würden erben von. Leider haben sie auch viel gemeinsam mit ihren aktuellen Vorfahren ... Textmessage und Emailmessage. Klassischer Wunsch nach Mehrfachvererbung hier.

Was ist der leichtgewichtige Ansatz, das Problem zu lösen?

Danke!

War es hilfreich?

Lösung

Alex, die meiste Zeit benötigen Sie Mehrfachvererbung ist ein Signal, Ihre Objektstruktur etwas falsch ist. In der Situation skizziert Sie Ich sehe Sie Klasse Verantwortung einfach zu weit gefasst haben. Wenn Message Teil der Anwendungsgeschäftsmodell ist, sollte es nicht darauf achten, über Ausgabe zu machen. Stattdessen könnten Sie die Verantwortung geteilt und MessageDispatcher verwenden, die die Nachricht mit Text oder HTML-Backend übergeben senden. Ich weiß nicht, Ihren Code, aber lassen Sie es mich so simulieren:

$m = new Message();
$m->type = 'text/html';
$m->from = 'John Doe <jdoe@yahoo.com>';
$m->to = 'Random Hacker <rh@gmail.com>';
$m->subject = 'Invitation email';
$m->importBody('invitation.html');

$d = new MessageDispatcher();
$d->dispatch($m);

Auf diese Weise können einige Spezialisierung auf Message-Klasse hinzufügen:

$htmlIM = new InvitationHTMLMessage(); // html type, subject and body configuration in constructor
$textIM = new InvitationTextMessage(); // text type, subject and body configuration in constructor

$d = new MessageDispatcher();
$d->dispatch($htmlIM);
$d->dispatch($textIM);

Beachten Sie, dass MessageDispatcher eine Entscheidung treffen würde, ob übergeben HTML oder Nur-Text abhängig von type Eigenschaft in Message-Objekt zu senden.

// in MessageDispatcher class
public function dispatch(Message $m) {
    if ($m->type == 'text/plain') {
        $this->sendAsText($m);
    } elseif ($m->type == 'text/html') {
        $this->sendAsHTML($m);
    } else {
        throw new Exception("MIME type {$m->type} not supported");
    }
}

Um es zusammenzufassen, ist möglicherweise zwischen zwei Klassen aufgeteilt. Nachrichtenkonfiguration wird in InvitationHTMLMessage / InvitationTextMessage Klasse getan, und das Senden Algorithmus wird auf Dispatcher delegiert. Dies nennt man Strategy-Muster, können Sie mehr lesen Sie es hier .

Andere Tipps

Vielleicht können Sie ein 'is-a' Beziehung mit einer 'has-a' Beziehung ersetzen? Eine Einladung möglicherweise eine Nachricht, aber es muss nicht unbedingt zu ‚is-a‘ Nachricht. Eine Einladung F. E. könnte bestätigt werden, was nicht gut zusammen mit dem Message-Modell geht.

Suche nach ‚Komposition vs. Vererbung‘, wenn Sie mehr darüber wissen müssen.

Wenn ich Phil zitieren in dieses Thema ...

  

PHP, wie Java, nicht Mehrfachvererbung unterstützen.

     

in PHP 5.4 kommend wird Merkmale , die eine Lösung zur Verfügung zu stellen versuchen,   für dieses Problem.

     

In der Zwischenzeit würden Sie am besten sein Design zu überdenken Ihrer Klasse. Sie   können mehrere Schnittstellen implementieren, wenn Sie nach einer längeren API sind zu   Ihre Klassen.

Und Chris ....

  

PHP nicht wirklich Mehrfachvererbung unterstützen, aber es gibt einige   (Etwas chaotisch) Möglichkeiten, es zu implementieren. Aktivieren Sie diese URL heraus für einige   Beispiele:

     

http://www.jasny.net/articles/ how-i-php-Mehrfachvererbung /

Dachte sie beide nützliche Links hatte. Kann nicht Züge warten, um zu versuchen, oder vielleicht einige Mixins ...

Das Symfony Framework hat einen mixin Plugin für diese , möchten Sie vielleicht, es auszuprobieren -. auch nur für Ideen, wenn es nicht zu benutzen

Die „Entwurfsmuster“ Antwort zu abstrahieren der gemeinsam genutzte Funktionalität in eine separate Komponente, und zur Laufzeit zusammensetzen. Denken Sie an einem Weg zu abstrahieren der Einladung Funktionalität heraus als eine Klasse, die mit Ihrer Meldeklasse in irgendeine Weise anders als Vererbung assoziiert wird.

Ich verwende Züge in PHP 5.4 als Weg, dies zu lösen. http://php.net/manual/en/language.oop5.traits.php

Dies ermöglicht eine klassische Erbe mit sich, sondern gibt auch die mögliche gemeinsame Funktionalität des Vergebens und Eigenschaften in einen ‚Zug‘. Wie das Handbuch sagt:

  

Traits ist ein Mechanismus für die Wiederverwendung von Code in einzelne Vererbung Sprachen wie PHP. Ein Trait soll durch Aktivieren eines Entwickler einige Einschränkungen einzelner Erbe reduzieren Sätze von Methoden frei in mehreren unabhängigen Klassen in verschiedenen Klassenhierarchien leben wieder zu verwenden.

Es klingt wie die Dekorateur Muster rel="nofollow geeignet sein können, aber schwer, ohne weitere Details zu erzählen .

Dies ist sowohl eine Frage und eine Lösung ....

Was ist mit dem magischen _ call () _get (), __set () Methoden? Ich habe noch nicht diese Lösung getestet, aber was ist, wenn Sie eine multiInherit Klasse. Eine geschützte Variable in einer untergeordneten Klasse könnte eine Reihe von Klassen enthalten erben. Der Konstruktor in der Multi-Interface-Klasse Instanzen von jeder der Klassen erstellen können, die vererbt werden und verknüpfen sie mit einem Privateigentum, sagen _EXT. Die __call () Methode könnte die method_exists () Funktion auf jede der Klassen in der _EXT Array verwenden, um die richtige Methode zu lokalisieren, zu nennen. __get () und __set verwendet werden könnten interne Eigenschaften zu finden, oder wenn Ihr ein Experte mit Referenzen können Sie die Eigenschaften der untergeordneten Klasse machen und die geerbten Klassen Verweise auf die gleichen Daten sein. Die Mehrfachvererbung des Objekts würde transparent sein, diese Objekte Code. Auch könnten interne Objekte die geerbten Objekte direkt zugreifen, wenn nötig, solange die _EXT Array von Klassennamen indiziert ist. Ich habe in Betracht gezogen diese super-Klasse erstellt und noch nicht umgesetzt, wie ich das Gefühl, dass, wenn es funktioniert, als es einige variieren schlechte Programmierung zu entwickeln Gewohnheiten führen könnte.

Ich habe ein paar Fragen zu stellen, um zu klären, was Sie tun:

1) Gibt es in Ihrem Nachrichtenobjekt nur enthält eine Nachricht z.B. Körper, Empfänger, Zeitplan Zeit? 2) Was wollen Sie mit Ihrer Einladung Objekt zu tun? Braucht es speziell auf eine Emailmessage verglichen behandelt werden? 3) Wenn ja, was das Besondere daran ist? 4) Wenn das dann der Fall ist, warum die Nachrichtentypen für eine Einladung Handhabung unterschiedlich brauchen? 5) Was ist, wenn Sie eine Begrüßungsnachricht oder eine OK-Nachricht senden möchten? Sind sie neue Objekte zu?

Es klingt wie Sie zu viel Funktionalität in einer Menge von Objekten kombinieren versuchen, die nur mit Besitz einer Nachrichteninhalte betroffen sein sollte - und nicht, wie es gehandhabt werden sollte. Für mich, Sie zu sehen, gibt es keinen Unterschied zwischen einer Einladung oder einer Standard-Nachricht. Wenn die Einladung eine spezielle Handhabung erfordert, dann bedeutet, dass die Anwendungslogik und nicht einen Nachrichtentyp.

Zum Beispiel: ein System, das ich gebaut hatte ein gemeinsame Basis Nachricht Objekt, das in SMS verlängert wurde, E-Mail und andere Nachrichtentypen. Allerdings: diese wurden nicht weiter ausgebaut - eine Einladungsnachricht war einfach Text vordefiniert über eine Nachricht des Typs E-Mail gesendet werden. Eine spezielle Einladung Anwendung würde bei der Validierung und anderen Anforderungen für eine Einladung betroffen sein. Immerhin alles, was Sie tun möchten, ist Nachricht X an Empfänger sendet Y, die ein diskretes System in seinem eigenen Recht sein sollten.

Die gleiche Problem wie Java. Versuchen Sie es mit Schnittstellen mit abstrakten Funktionen zur Lösung dieses Problems

PHP funktioniert Unterstützung Schnittstellen. Dies könnte eine gute Wette, je nach Anwendungsfällen.

Wie wäre es eine Einladung Klasse direkt unterhalb der Meldeklasse?

so die Hierarchie geht:

Nachricht
--- Einladung
------ Textmessage
------ Emailmessage

Und Einladung Klasse, fügen Sie die Funktionen, die in InvitationTextMessage und InvitationEmailMessage war.

Ich weiß, dass Einladung nicht wirklich eine Art von Nachricht ist, es ist mehr eine Funktionalität von der Nachricht. Also ich bin nicht sicher, ob dies ein gutes OO-Design oder nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top