Domanda

Sto cercando un buon modo pulito per andare in giro per il fatto che PHP5 ancora non supporta l'ereditarietà multipla.Ecco la gerarchia di classi:

Messaggio
-- TextMessage
-------- InvitationTextMessage
-- EmailMessage
-------- InvitationEmailMessage

I due tipi di Invito* classi hanno molto in comune;mi piacerebbe avere un padre in comune classe, Invito, che entrambi avrebbero ereditare.Purtroppo, hanno anche molto in comune con il loro attuale antenati...TextMessage e EmailMessage.Classica desiderio per l'ereditarietà multipla qui.

Cosa c'è di più leggero approccio per risolvere il problema?

Grazie!

È stato utile?

Soluzione

Alex, il più delle volte è necessario l'ereditarietà multipla è un segnale che il vostro oggetto struttura è un po ' errato.Nella situazione che hai descritto vedo che hai classe di responsabilità semplicemente troppo ampio.Se il Messaggio è parte di applicazione del modello di business, si dovrebbe prendere cura di uscita di rendering.Invece, si potrebbe dividere responsabilità e utilizzare MessageDispatcher che invia il Messaggio passato utilizzando il testo o html backend.Non so il tuo codice, ma mi permetta di simulare in questo modo:

$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);

In questo modo è possibile aggiungere un po di specializzazione per la classe di Messaggio:

$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);

Nota che MessageDispatcher la decisione se inviare in formato HTML o testo normale a seconda type la struttura in oggetto del Messaggio trasmesso.

// 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");
    }
}

Per riassumere, la responsabilità è divisa tra due classi.Messaggio di configurazione è fatta in InvitationHTMLMessage/InvitationTextMessage classe, e l'invio di algoritmo è delegata al dispatcher.Questo è chiamato il Modello di Strategia, si può leggere di più su di esso qui.

Altri suggerimenti

Forse si può sostituire un 'è una' relazione 'ha una relazione?Un Invito potrebbe avere un Messaggio, ma non necessariamente 'è un' messaggio.Un Invito f.e.potrebbe essere confermato, che non va bene insieme con il Messaggio di modello.

La ricerca di " composizione vseredità' se avete bisogno di saperne di più.

Se posso citare il Fil in questo thread...

PHP, Java, non supporta l'ereditarietà multipla.

Venuta in PHP 5.4 sarà caratteristiche che tentano di fornire una soluzione a questo problema.

Nel frattempo, si potrebbe essere meglio per ri-pensare il design di classe.Si è possibile implementare più interfacce, se siete dopo un lungo API per le vostre classi.

E Chris....

PHP non supporta l'ereditarietà multipla, ma ci sono alcuni (un po ' disordinato) modi per la sua attuazione.Check out questo URL per alcuni esempi:

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

Il pensiero che entrambi avevano link utili.Non vedo l'ora di provare tratti o magari qualche mixins...

Il framework Symfony è un mixin plugin per questo, si potrebbe desiderare di check it out anche solo per le idee, se non usarlo.

Il "design pattern" e la risposta è astratta, la funzionalità condivise in una componente separata, e comporre in fase di runtime.Pensare a un modo per astrarre la Invito funzionalità come una classe che viene associato al tuo Messaggio classi, in qualche modo, diverso eredità.

Sto utilizzando tratti di PHP 5.4, come il modo per risolvere questo.http://php.net/manual/en/language.oop5.traits.php

Questo permette classico eredità che si distende, ma dà anche la possibilità di collocare la funzionalità comune e proprietà in un 'tratto'.Il manuale dice:

Tratti è un meccanismo per il riutilizzo del codice in ereditarietà singola linguaggi come PHP.Una Caratteristica è destinato a ridurre alcune limitazioni di ereditarietà singola, consentendo allo sviluppatore di riutilizzare gli insiemi di metodi liberamente in diverse classi indipendenti che vivono in diverse gerarchie di classe.

Sembra che l' pattern decorator può essere adatto, ma è difficile dire, senza ulteriori dettagli.

Questo è sia una domanda e una soluzione....

Che cosa circa il magico _call(),_get(), __set() metodi?Non ho ancora provato questa soluzione, ma cosa succede se si commette un multiInherit classe.Protetta variabile in una classe di bambini potrebbe contenere un array di classi ereditate.Il costruttore multi-interfaccia di classe è possibile creare istanze di ciascuna delle classi che vengono ereditati e collegarli ad una proprietà privata, dire _ext.L' __call() metodo che potrebbe utilizzare il method_exists() funzione di ciascuna delle classi in _ext array per individuare il metodo più corretto per chiamare.__get() e __set può essere utilizzato per individuare interno proprietà, o se il vostro esperto con referenze si potrebbe fare che la proprietà del bambino in classe e le classi ereditate riferimento agli stessi dati.L'ereditarietà multipla dell'oggetto sarebbe trasparente per codice di utilizzo di tali oggetti.Inoltre, gli oggetti interni potrebbe accedere a oggetti ereditati direttamente, se necessario, come lungo come il _ext array indicizzati dal nome della classe.Ho immaginato la creazione di questo super-classe e non hanno ancora implementato come mi sento che se funziona che potrebbe portare allo sviluppo di alcuni variare cattive abitudini di programmazione.

Ho un paio di domande per chiedere di chiarire che cosa si sta facendo:

1) oggetto il tuo messaggio solo contengono un messaggio ad es.il corpo, il destinatario, il tempo di pianificazione?2) che Cosa hai intenzione di fare con il vostro Invito oggetto?Ha bisogno di essere trattati in modo speciale rispetto ad un EmailMessage?3) Se è così che COSA è così speciale?4) Se, che è poi il caso, perché il messaggio di tipi di trattamento in modo diverso per un invito?5) Cosa succede se si desidera inviare un messaggio di benvenuto o un messaggio OK?Sono nuovi oggetti troppo?

Suona come si sta cercando di combinare troppe funzionalità in un insieme di oggetti che devono essere solo interessato con il possesso di un contenuto del messaggio e non come dovrebbe essere gestita.Per me, si vede, non c'è differenza tra un invito o un messaggio standard.Se l'invito richiede un trattamento speciale, allora significa che la logica dell'applicazione e non un tipo di messaggio.

Per esempio:un sistema che ho costruito era una base comune oggetto del messaggio che è stato esteso in SMS, e-Mail, e altri tipi di messaggi.Tuttavia:questi non sono stati estesi ulteriormente - un messaggio di invito era semplicemente pre-definito di testo tramite un messaggio di tipo e-Mail.Un Invito specifico l'applicazione sarebbe interessato con la convalida e altri requisiti per un invito.Dopo tutto, tutti si desidera fare è inviare un messaggio di X al destinatario Y che dovrebbe essere un discreto sistema vero e proprio.

Stesso problema come Java.Provare a utilizzare le interfacce con funzioni astratte per risolvere quel problema

PHP supporta le interfacce.Questa potrebbe essere una buona scommessa, a seconda dei casi d'uso.

Come circa un Invito classe, sotto a destra, la classe di Messaggio?

quindi la gerarchia va:

Messaggio
--- Invito
------ TextMessage
------ EmailMessage

E Invito classe, aggiungere la funzionalità InvitationTextMessage e InvitationEmailMessage.

So che l'Invito non è davvero un tipo di Messaggio, è più di una funzionalità di Messaggio.Quindi non sono sicuro se questo è un bene, OO o no.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top