2012-12-20 11 views
10

Attualmente sto lavorando a un progetto in cui il sistema principale è distribuito a molti client diversi e quindi se il client richiede modifiche, dobbiamo renderli individualmente su ciascun sistema che significa che alla fine il codice base varia da client a client, e tenerlo aggiornato e copiare nuove funzionalità nel sistema è difficile.Ignora la classe e il metodo PHP - implementa i callback

Ho proposto di passare a (quello che sto chiamando) un 'modello di override' che ha una struttura di scheletro esterna del codice. Un po 'come:

|- controllers 
|- models 
|- views 
|- core 
    |- controllers 
     |- Controller1.php 
    |- models 
    |- views 

Se poi si volesse apportare modifiche a Controller1.php, si sarebbe copiarlo nella struttura esterna e di apportare modifiche - un caricatore automatico sarebbe quindi caricare i file appropriati se esistono, controllando la struttura Skeleton per loro in primo luogo, vale a dire

Loader::controller('Controller1'); 

Tuttavia mi sono chiesto se è possibile andare un po 'più di questo - la sua buona e giusta sovrascrivendo il controller se i cambiamenti sono necessari, ma poi tutte le aggiunte principali futuri o correzioni non potrebbe aggiunta. Quindi ho pensato che potreste creare una copia del file e sovrascrivere solo le chiamate al metodo singolare. Un semi-esempio di ciò che intendo è il seguente:

class Override { 

public function __call($method, $args) { 
    return call_user_func_array(array('Something', $method), $args); 
} 

public static function __callStatic($method, $args){ 
    return call_user_func_array(array('Something', $method), $args); 
    } 

} 

// Core class 
class Something { 

    static function doTest() { 
     echo "Class something <br/>"; 
    } 

    static function doOtherTest() { 
     echo "That works <br/>"; 
     self::doTest(); 
    } 

} 


// Overriding class - named differently for ease of example and reasons explained later 
class SomethingElse extends Override { 

    private static function doTest() { 
     echo "Success <br/>"; 
    } 

} 

// Actual function calling 
SomethingElse::doTest(); 
SomethingElse::doOtherTest(); 

L'idea generale è che se il metodo non esiste nella classe originari, allora l'azione dalla classe 'parent' (che è codificato qui). Tuttavia ho due problemi con questo metodo:

  • penso di avere dei problemi quando le classi hanno gli stessi nomi
  • Se io sto cercando di eseguire l'override un metodo che la classe padre chiama successivamente, userà è la propria versione del metodo rispetto a quella che sto tentando di sovrascrivere
    • Sebbene la soluzione 'semplice' è quella di dire che è necessario eseguire l'override di tutti i metodi in congiunzione, ma altri potrebbero essere aggiunti in un secondo momento.

Attualmente sto cercando di fare solo la soluzione iniziale di una piena di classe override utilizzando il caricatore, che funziona ed è meno complessa.

Tuttavia mi chiedevo se nessuna delle grandi menti di StackOverflow potesse sapere di una risposta o di una configurazione che potrebbe aiutare a risolvere i problemi con l'idea di sovrascrivere il metodo. Tieni presente che sto lavorando con un sistema esistente configurato , anche se l'idea della struttura dello scheletro è ciò che sto cercando di implementare per portare una qualche forma di "controllo" su ciò che è cambiato. Idealmente, nulla nel nucleo sarebbe cambiato (almeno non di molto) quando qualcuno vuole scavalcare un metodo o simili.

+1

Consiglierei di scaricare [FuelPHP Framework] (http://fuelphp.com/) e di esaminare il loro codice per vedere come hanno risolto questo tipo di problemi. – PhearOfRayne

+0

perché stai usando la statica per questo? L'intero punto di MVC sta avendo componenti riutilizzabili/sostituibili. La statica accoppia strettamente tutto. Questa è una cosa molto brutta dal punto di vista del design. Vedi: http://misko.hevery.com/2008/12/15/static-methods-are-death-to-estibility/ e http://stackoverflow.com/questions/9560484/static-methods-or-not/11933130 # 11933130 –

+0

@StevenFarley evviva il link! – Dan

risposta

1

beh, il rigoroso tipo di soluzione OO sarebbe sicuramente quello di diffondere il controller come interfacce astratte che potrebbero essere implementate da diversi approcci del mondo reale e quindi riuniti dalla composizione sul principio di ereditarietà.

Come ho capito, hai qui il codice esistente che intendi sovrascrivere o estendere. Se il PHP-versione consente di utilizzare Tratti, questo potrebbe aiutare anche voi:

PHP 5.4: why can classes override trait methods with a different signature?

+0

SVBokenham ha scritto come faremo questo, ma sto contrassegnando questo come la risposta corretta in quanto è cosa ci ha portato alla soluzione. – Dan

3

Bene abbiamo appena risolto. Tratti è!

Ma seriamente convertendo il codice versione in caratteri e quindi chiamandoli nei file senza versione nella struttura sopra. Ciò quindi nega la necessità di una classe del programma di caricamento e di altri livelli di prevenzione dei conflitti e consente di aggiornare, testare e eseguire il commit del codice di base senza influire sul codice personalizzato per client.

+3

Questa è la prima ragione reale e non idiota che ho visto per usare i tratti, buon lavoro. –

Problemi correlati