In realtà ci sono molti più modi di quello che pensi.
Metodo di chiamata magica
Questo è il codice per me. Non è difficile da seguire e, come mostrato, apre alcuni possibili problemi di codifica per i chiamanti esterni della classe. Se chiamo $ model- > something (), e non esiste, proverà a eseguire prepost__something () in modo errato. La magia è generalmente difficile da seguire e può darti delle condizioni inaspettate.
Metodi di chiamata esplicita
L'esplicito è sempre migliore, ma non quando interrompe il flusso principale del tuo metodo. Inoltre, quanto spesso stai facendo questo? In 1 classe? 10? 100? Se si tratta di qualcosa che si sta ripetendo molto, allora dovresti esaminare completamente un altro metodo.
La grande domanda è quale tipo di funzionalità si nasconde in quelle funzioni pre / post ... è correlata? È qualcosa come la registrazione, il debug, ecc. Che non è affatto correlato, ma deve essere eseguito lì?
Event Driven
Se non sono correlati, il percorso migliore è un sistema basato su eventi. Questo è molto comune nelle applicazioni / framework più popolari (ben scritti, comunque).
class Model
{
function find($id)
{
$this->dispatcher->dispatch("model.find.pre", $event = new PreFindEvent($id));
// do whatever with $event->getId()
$this->dispatcher->dispatch("model.find.post", new PostFindEvent($id, $result));
return $result;
}
}
Ciò richiede che tu passi un componente del dispatcher di eventi nella tua classe (iniezione di dipendenza) e colleghi manualmente tutte le classi attivate nel dispatcher di eventi. Tuttavia, è possibile attivare il comportamento in classi molto concise che modificano la funzionalità prima / dopo che si sta andando. Questo può essere molto prolisso, ma è testabile e consente di scrivere codice molto modulare. Scopri il componente EventDispatcher di Symfony per ulteriori esempi, sebbene molti altri fornitori offrano funzionalità simili.
Se è troppo verboso per te, e vuoi qualcosa di un po 'più radicale, c'è anche
Programmazione orientata agli aspetti
Se vuoi implementare la funzionalità cross-cutting (ex, logging) tra diversi metodi, allora questa è un'opzione molto utile. Tuttavia, il supporto PHP non è eccezionale (è richiesta un'estensione sperimentale o integrazione del framework).
Ti consente di attivare dinamicamente il codice in vari punti dell'applicazione SENZA dover aggiungere esplicitamente i punti di aggancio nel codice. Qualcosa di simile,
aop_add_before('some_function', 'run_this');
Probabilmente, questo rende l'esecuzione del codice molto difficile da seguire, ma ti permette di fare cose molto interessanti senza tutta la complessità aggiuntiva della programmazione basata sugli eventi. Se usi qualcosa come un contenitore per le dipendenze, anche l'aggiunta di AOP potrebbe essere possibile, anche se dipende molto dagli strumenti che usi.
Conclusione
Queste sono le opzioni. Consiglierei event-based in quanto sembra essere lo standard della comunità in PHP. (Symfony, Zend, ecc.) AOP è meglio supportato in altri linguaggi (nativamente), ed è un po 'hacky in PHP al momento.
In ogni caso, ti stai dirigendo sempre più verso l'iniezione di dipendenza, e potrebbe essere una lattina completamente nuova di worm da aprire per prima.
Spero che questo aiuti. Non c'è una risposta giusta: dipende sempre dagli strumenti attuali e dal dominio problematico.