Indipendenza del modello in MVC e modo più efficiente per effettuare chiamate di metodo

4

TLDR: I modelli dovrebbero essere dipendenti dall'applicazione e del tutto inutili all'avvio di una nuova applicazione, oppure si suppone di progettare modelli in modo indipendente in modo che si comportino come classi / librerie stand-alone? (Questo non avrebbe molto senso con un framework come CodeIgniter in cui estendi CI_Model che ovviamente non ci sarà nel tuo progetto Kohana.) Ho letto anche molte domande simili ad alcuni dei miei punti qui, ma questo è il punto principale su cui non ho trovato risposta.

Utilizzo CodeIgniter da un po 'di tempo che mi ha fatto conoscere il pattern MVC. Anche se ci è voluto un po 'per approfondire, ho pagato di più, ho letto, riflettuto e ispirato a me stesso, tuttavia c'è qualcosa che mi ha sempre costantemente infastidito; come assemblare correttamente una composizione di oggetti valida, efficiente e funzionante.

Considerando i tre diversi workareas della struttura MVC che utilizzo (controller, modello e libreria - sì, ho detto libreria, per l'inclusione indipendente delle classi), ho avuto difficoltà a decidere se il modello dovrebbe funzionare come una classe indipendente stesso o agisce solo come una struttura dell'applicazione come la cosiddetta "scatola nera", "modello aziendale" o "modello grasso".

Mantengo i miei controllori "magri" e provo a farlo perché tutta la documentazione che ho letto ha cercato di farlo notare, ma poiché il controller è specifico dell'applicazione e non indipendente (in modo tale che potrei semplicemente prendilo dall'applicazione e applicalo a un'altra applicazione completamente diversa), sono confuso se il modello dovrebbe agire in modo simile, semplicemente essendo una coppia di classi "grasse" organizzate legate all'applicazione principale, perdere tutto il loro valore se trasferiti in un progetto totalmente nuovo.

E esattamente questo è il nocciolo del mio problema e ho davvero bisogno di ottenere una definizione cristallina al riguardo. Per aiutarti a capire meglio cosa intendo, posso dare alcuni esempi:

Sto facendo un'applicazione con PHP nel momento in cui ho un modello chiamato users.php . All'interno di questa classe ho metodi che lavorano contro la tabella 'users', come questa:

/**
     * Runs the login credentials against the database
     * @param string - username
     * @param string - password
     * @return user_id / false
     * */
    public function verifyLogin($username, $password) {

        $password = $this->_hashPassword($password);

        $this->db->where('username', $username);
        $this->db->where('password', $password);
        $this->db->where('activated', 1);
        $this->db->where('deleted', 0);

        $query = $this->db->get(DB_PREFIX.'users');

        if ($query->num_rows() > 0) {
            $r = $query->result_array();
            return $r[0]['id']; // User ID
        }

    }

Il modello viene caricato nel framework e chiamo questo metodo dal controller in questo modo:

$this->users->verifyLogin($_POST['login_username'], $_POST['login_password']);

Il modo in cui usavo chiamarlo prima era $this->users->verifyLogin(); , lasciando che il modello prendesse semplicemente le variabili $_POST e calcolasse tutto da solo. Ho appena cambiato questo aspetto, come direi che il controllo di tutti gli input e output dovrebbe passare attraverso il controller, lasciando virtualmente il modello 'effettivamente completamente incapsulato' anche a me come autore del codice.

Questo mostra la connessione tra il mio controller e il mio modello, ma cosa succede se ho deciso di utilizzare una libreria indipendente, ad esempio una classe di convalida che avevo fatto? Dove implementerei questa classe autonoma? Facciamo finta che questo sia un frammento della mia applicazione in cui utilizzo la mia classe di validazione progettata male per darmi un'eccezione:

require_once('validator-class.php');

$val = new Validator($_POST['login_username']);

try {
$val->max_length(16)
    ->min_length(4)
    ->alpha_numeric();
}

Dovrei inserire questo codice nel controller o nel modello per ottenere i migliori risultati? Se il modello fosse dipendente dall'applicazione, avrebbe più senso delegare / chiamare i metodi della classe della libreria all'interno del modello e quindi chiamare molto facilmente il modello in modo più semplificato, come un metodo save() dove tutto si sarebbe preso cura di dietro le quinte.

Sono giunto a chiedermi se il controller debba essere usato come "area principale" per collegare i punti, essendo il luogo in cui chiamerei i metodi di ogni classe, delegandoli al modello ecc. mantenendo il modello 100% fuori classe pulito, affidandosi solo a se stesso solo e sicuramente. Ma poi di nuovo, se si suppone che il modello sia dipendente dall'applicazione, questo non avrebbe senso se non portassi il modello con me a un nuovo progetto e invece dovessi semplicemente eseguire tutte le procedure di chiamata e disordinato all'interno della classe incapsulata.

Devo scusarmi per la lunga spiegazione, ma faccio fatica a usare anche il pattern MVC con questa domanda in mente nella misura in cui sto seriamente considerando di lasciarmi andare e tornare al PHP puro e rigido. Qualche aiuto sarebbe molto apprezzato. Inoltre, alcuni suggerimenti su come documentare i metodi di classe sarebbero molto graditi come bonus.

Grazie mille!

    
posta Melissa 23.10.2011 - 05:42
fonte

1 risposta

3

Would I put this code into the controller or the model for best effect?

La convalida fa parte del dominio dell'applicazione e, pertanto, dovrebbe trovarsi nel modello. Tutte le funzionalità che sono specifiche per l'interfaccia web, ad es. gestire le richieste HTTP, i cookie, i dati di sessione, dovrebbe trovarsi nel controller o nella vista.

Pensa al tuo modello come all'intera applicazione senza un'interfaccia utente. Dovresti essere in grado di estendere la tua applicazione con un'interfaccia aggiuntiva, ad es. servizio web, senza modifiche (o solo piccole modifiche) al modello. Inoltre, tutte le interfacce devono rispettare le stesse regole aziendali, ad es. il nome utente può contenere solo caratteri alfanumerici.

Il modo in cui hai cambiato il tuo metodo $this->users->verifyLogin($_POST['login_username'], $_POST['login_password']); è la strada giusta da percorrere. In questo modo il metodo verifyLogin non dipende da una richiesta POST HTTP (con alcuni nomi di parametri specifici), ma può essere utilizzato in varie situazioni migliorando così la qualità del codice, la manutenibilità e la separazione dei problemi.

Per citare Wikipedia :

The model manages the behaviour and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

    
risposta data 23.10.2011 - 09:17
fonte

Leggi altre domande sui tag