2011-12-02 14 views
5

Ho notato che tutti i miei modelli sembrano molto simili. La maggior parte di essi tende a seguire uno schema in cui sono raccolte di metodi contenenti codice di registrazione attivo che sono solo lievi variazioni l'uno sull'altro. Ecco un esempio:I miei modelli sembrano tutti uguali

class Site extends CI_Model { 

    public function get_site_by_id($id) 
    { 
     // Active record code to get site by id 
    } 

    public function get_sites_by_user_id($user_id) 
    { 
     // ... 
    } 

    // ... 

    public function get_site_by_user_id_and_url_string($user_id, $url_string) 
    { 
     // ... 
    } 

    // Non active record methods and business logic 
    // ... 

} 

Questo approccio ha funzionato bene per me, ma mi chiedo se c'è una soluzione più elegante. Non mi sembra giusto che dovrei creare un nuovo metodo ogni volta che ho bisogno di cercare i dati in un modo nuovo. È questa pratica comune o mi manca un modo per refactoring questo?

+1

Questo sarebbe principalmente un effetto collaterale dell'utilizzo di un gruppo di [record attivo] (http://martinfowler.com/eaaCatalog/activeRecord.html) come sostituto del livello di modalità implementato completo. Potresti trovare [questo] (http://stackoverflow.com/a/11943107/727208) rilevante per le opzioni di refactoring. –

risposta

2

Seguendo rigorosamente la vostra richiesta, è possibile aggiungere una classe intermedia tra la classe principale del modello (CI_Model) e la classe (Site), qualcosa come

class MyCommonMethodsClass extends CI_Model { 
} 

e si sarebbe estenderlo nelle classi (Site) , mentre si inserisce il codice comune. Ciò funzionerebbe e potrebbe essere in qualche modo "elegante". In effetti alla fine si finirebbe per aggiungere le tue azioni di base, adatte al sito, ad esso.

Ora, se è "pulito", questa è un'altra cosa. Di nuovo, in senso stretto, il modello lo fa. Si prende cura dei getter comuni e 'avanzati'. E sì, hanno quasi sempre la tendenza ad avere lo stesso codice in tutto il tuo sito web. Il problema è che, anche se questo è bello nel tuo codice (meno codice) stai tecnicamente sacrificando l'astrazione tra la tua logica di business e il db. Sei un modello purista o pratico?

+0

+1 per "purista" e "pratico": troppe volte le persone fanno più lavoro per se stesse cercando di fare le cose nel modo "corretto". – swatkins

+0

Sì, è corretto, consente di eseguire lo slap di un'applicazione e attendere che i problemi arrivino a bussare. –

1

Penso che sia una questione di opinione, ma penso che la migliore pratica sia quella di creare una sorta di modello Create, Retrieve, Update, Delete (CRUD) che fa molte funzioni SQL di base come GetID, UpdateByID, GetById e così via.

I modelli CRUD possono solo spingersi fino ad ora con domande più modulari. Ma ha senso chiamare una funzione chiamata GetId e passargli alcuni parametri piuttosto che avere funzioni diverse per ogni tabella.

Come dico io, CRUD non può che andare così lontano. Ad esempio, avrebbe senso avere una funzione che interroga una tabella utenti del database per verificare se un utente ha verificato e nome utente & corrispondenza password. Poiché si tratta di una funzione unica e non astratta, dovrebbe avere la propria funzione definita.

Inoltre, come best practice, l'accesso alla logica e al database non deve mai essere mescolato nello stesso file.

0

È prassi comune disporre di metodi diversi per gestire i dati in questo modo. Lo Single Responsibility Principal afferma che ogni oggetto dovrebbe fare solo una cosa, creando più metodi che ottengono dati molto specifici che si creano codice molto manutenibile e facile da debugare.

+0

Forse per funzioni che tendono a fare cose specifiche ma non per funzioni molto astratte che possono essere applicate a molte situazioni diverse. –

+0

Penso anche di interpretare erroneamente ciò che intendono con 'Responsabilità singola', questo significa che la funzione ha un'azione, come un singleton che attiva una connessione al database, ma può ancora essere riutilizzata. La "responsabilità unica" è parte dell'incapsulamento in OOP, poiché l'incapsulamento è il principio del codice riutilizzabile. –

+0

I modelli devono essere molto specifici, ovvero il punto di un modello, la "Single Responsibility" del modello è un controllo specifico del dominio, con nel modello sono presenti metodi che eseguono un compito specifico. Se si dispone di più modelli che fanno tutti la stessa cosa, probabilmente si ha odore di codice, quindi si sposta il codice comune in una nuova classe, quindi si estende il modello con la classe comune. –

0

Se esistono più classi che forniscono essenzialmente la stessa funzionalità, ciò suggerisce che potrebbe esserci qualcosa di sbagliato nella gerarchia di classi (un cosiddetto "odore di codice"). Se hanno interazioni simili allora questo suggerisce che sono in qualche modo correlati. Se questo è il caso, allora è probabile che tutti debbano ereditare da una superclasse comune che implementa la funzionalità comune a tutte le sottoclassi, con ciascuna sottoclasse che sta semplicemente specializzando la funzionalità generalizzata della superclasse.

I vantaggi di questo approccio sono:

  • Non stai ripetendo il lavoro (SPOT, DRY)
  • codice che interagisce con le classi possono essere scritte in modo più generale e in grado di gestire qualsiasi oggetto che eredita dalla superclasse (sostituzione)
0

Non penso ci sia nulla di sbagliato nel creare una classe di modello 'base' per estendere altri modelli con. Se è solido e ben testato, può renderti la vita più facile. Qual è il punto di creare le stesse funzioni CRUD più e più volte?

Un altro vantaggio è che è possibile creare un repository di sviluppo di base da clonare per avviare tutti i nuovi progetti.

Se è necessario un esempio di come eseguire questa operazione, consultare uno question precedentemente richiesto.

Puoi anche fare lo stesso con il tuo controllers.

Problemi correlati