2009-08-28 6 views
19

sul mio posto di lavoro (solo php) abbiamo una classe base per l'astrazione del database. Quando si desidera aggiungere una nuova tabella di database al livello di base, è necessario creare una sottoclasse di questa classe di base e sovrascrivere alcuni metodi per definire il comportamento individuale per l'utilizzo di questa tabella. Il comportamento normale dovrebbe rimanere lo stesso.Implementazione corretta di funzioni virtuali in PHP?

Ora ho visto molti nuovi programmatori nella nostra azienda, che sostituiscono il metodo per il comportamento predefinito. Alcuni sono così "simpatici" da mettere in atto tutti i comportamenti di default e aggiungono solo cose individuali dove gli piace, altri si uccidono cercando di usare la baseclass e il loro erede.

Il mio primo pensiero per risolvere questo problema, è stato quello di pensare a metodi astratti che dovrebbero essere ignorati ereditando le classi. Ma accanto ad altri argomenti contro i metodi astratti, "astratto" non mostra semplicemente perché la baseclass non può essere utilizzata da sola e perché questa funzione deve essere sostituita da.

Dopo aver cercato su google, non ho trovato una buona risposta all'implementazione di funzioni virtuali "reali" in php (solo che esiste una funzione virtuale, che quasi uccide ogni speranza di un'implementazione concreta).

Quindi, cosa faresti con questo argomento?

+0

Mi dispiace ma non ho capito bene la tua domanda, quando dici "funzioni virtuali" stai parlando dei metodi magici __call() e __callStatic()? O funzioni lambda? –

+5

Penso che intenda il metodo di esclusione. http://en.wikipedia.org/wiki/Method_overriding che in C++ si riferisce a come funzioni virtuali. –

risposta

31

In PHP tutti pubblici e protette funzioni sono "virtuale". È possibile impedire l'overrid delle funzioni anteponendo la parola chiave final. (O rendendoli privati, ma questa è probabilmente una cattiva idea).

Nella progettazione della classe di base, vorrei pensare a comportamenti che le sottoclassi vorrebbero influenzare. Vorrei creare ad esempio funzioni vuote come before_update() e after_insert().

function after_insert() { 
    // Virtual 
} 

Che la baseclass chiamerà quando si verifica un evento di aggiornamento/inserimento.

Forse una funzione is_valid() che restituisce sempre true nella classe di base e utilizza il commentblock per descrivere quali sono le conseguenze quando una sottoclasse restituisce false.

Speriamo che questo possa darvi qualche spunto.

0

Senza un esempio dell'implementazione della classe base, è difficile dare informazioni concrete. Ma alcune cose vengono in mente:

  1. L'astrazione del database è una cosa complessa per cominciare. Capisco che tu voglia mantenerlo snello, pulito e cattivo, ma penso che sia dannatamente difficile. Devi davvero dare un'occhiata alle specifiche dei diversi motori DB per vedere quali parti sono generali e quali parti necessitano di specializzazione. Anche; sei sicuro di non avere l'astrazione di DB confusa con il pattern di Gateway dati di tabella, visto che stai parlando di aggiungere tabelle DB estendendo la classe di base?

  2. I metodi della classe base corrente potrebbero essere eccessivi e/o non sono abbastanza generali per cominciare, se le classi estese si piegano all'indietro troppo tenerlo pulito. Forse dovresti rompere i metodi dell'interfaccia di classe base con metodi protetti più piccoli che sono abbastanza generali da essere riutilizzati nei metodi di sovrascrittura delle classi estese? O viceversa: forse dovresti avere degli hook per metodi sovrascrivibili nei tuoi metodi di interfaccia.

  3. seguito dal punto 2: Cosa c'è di male ad avere una classe astratta con alcuni metodi implementati generali, e lasciate che la vostra classe di vaniglia (la classe base) e altre classi ereditare da che?

  4. Infine, forse dovresti semplicemente imporre un'interfaccia da implementare, invece di estendere la classe base?

3

È sempre possibile utilizzare la parola chiave "final" per evitare che alcune funzioni delle classi vengano sovrascritte se le persone utilizzano la classe in modo errato.

Mi sembra che non siano in grado di ottenere determinate funzionalità, ignorando quindi i metodi. Potrebbe essere necessario dare un'occhiata al design delle tue lezioni.