Dove devono essere definiti dati / logica specifici per le viste in un'applicazione PHP MVC?

3

Dopo molte ore di ricerca e di riflessione ho trovato una comprensione, quindi sono venuta a interrogarla di nuovo, sto lottando per trovare qualcosa di concreto che riesco a cogliere e applicare al mio codice in senso pratico, andando avanti.

Penso che mi riferisca alla logica di presentazione e a un modello di dominio . Ho letto numerosi articoli come Modello di dominio anemico , ma non riesco ancora a capire quale sia la soluzione corretta . Inizierò con uno scenario reale che mi sta sconcertando.

Diciamo che ho un modulo web che richiede che i dati siano mostrati da 10 diversi modelli. Da ogni modello ho bisogno di ottenere un insieme specifico di dati che è utile solo a questa particolare vista. Ad esempio, potrebbe trattarsi di un gruppo di menu a discesa con determinate opzioni al loro interno.

1. Lascia che sia il controller a farlo

Pseudo codice:

/**
 * Controller action
 * 
 * Process a request for the specific view.
 */
public function myView()
{
    $options1 = $model1->query(
        // Get fields A, B, C from the database
        // Order the data by a certain field
        // Exclude data which does not meet conditions
        // Process the data some more
    );

    $options2 = $model2->query(
        // Get fields X, Y, Z from the database
        // Order the data by a certain field
        // Exclude data which does not meet conditions
        // Process the data some more
    );

    // ...repeat this sort of thing 8 more times

    $this->sendToView($options1, $options2, ...);
}

Quindi il controllore richiede a entità di modello diverse i dati necessari per la visualizzazione, esattamente nel formato richiesto dalla vista.

In un certo senso, questo mi sembra carino perché il livello del modello non ha idea della vista, e il controllore si assume la responsabilità di colmare il divario tra di loro. Tutta la logica su ciò che dovrebbe essere presentato nella vista è gestita dall'unico metodo nell'applicazione direttamente accoppiato a quella vista.

Tuttavia, questo potrebbe facilmente essere 200 linee nel mio controller, e questo è solo per la vista specifica one . Presto tutti i controller saranno enormi caos disordinati di dozzine di chiamate ai modelli per dati specifici per ogni vista. Puoi dividere le diverse chiamate in altri metodi sul controller (ad esempio privato) per renderlo un po 'più modulare / gestibile, ma qual è il punto?

Conclusione: mantenere il controller sottile e delegare questa roba altrove, suppongo.

2. Lascia che sia il livello Model a farlo

Pseudo codice:

/**
 * Controller action
 * 
 * Process a request for the specific view.
 */
public function myView()
{
    $options1 = $model1->getOptionsForAbc();
    $options2 = $model2->getOptionsForXyz();
    // ...repeat for 8 more models
}

/**
 * Model 1
 */
public function getOptionsForAbc()
{
    $options = $this->query(
        // Get fields A, B, C from an associated table
        // Order the data by a certain field
        // Exclude data which does not meet conditions
    );
    return $options;
}

// Each model has similar methods which retrieve specific sets of data

Quindi ora il controller è bello e sottile e non si occupa di alcuna logica. Richiede solo il modello per alcune cose di cui ha bisogno e il modello sa come ottenerlo.

Uso il termine "modello" liberamente qui. Capisco perfettamente che il modello è un livello composto da molte cose.

Il problema con questo sembra essere che i modelli finiranno per avere molte funzionalità che probabilmente sono utili solo per una vista particolare. Non sarà usato altrove perché solo quella vista richiede quel particolare sottoinsieme di dati. Questo mi sembra non corretto.

3. Implementa un livello di servizio / business logic

Credo che tutta la logica aziendale dovrebbe essere nel modello. Per la normale logica aziendale, come i calcoli, la convalida e altre cose che capita ai dati, lo capisco.

Tuttavia, che cosa dovrebbe accadere con questo particolare esempio di una vista che richiede dati specifici? Dovrei creare una classe di servizio che rappresenta il modulo, che è in grado di fornire tutti i dati richiesti dalla visualizzazione, nel formato corretto? Non sembra giusto.

Domanda finale: Quindi dove dovrei sto memorizzando questo tipo di logica di presentazione relativa ai dati che è solo per la vista?

    
posta BadHorsie 22.06.2016 - 19:21
fonte

3 risposte

2

Fai in modo che la vista faccia la formattazione. Ecco a cosa serve. Il compito del controllore è alimentarlo con dati arbitrari. MVC è un modello, non una cosa concreta. Non c'è niente di sbagliato nel fatto che le viste siano "intelligenti".

La convalida appartiene al modello. I controller spostano i dati utente direttamente sul modello ed è compito del modello rifiutare elementi non validi (ad esempio, lanciare un'eccezione).

Se ti trovi codice di formattazione copypasting, crea classi helper con metodi statici riutilizzabili o una gerarchia di classi di viste con metodi ereditati o utilizza tratti.

    
risposta data 08.08.2016 - 11:12
fonte
0

È possibile trattare il livello aziendale come un'applicazione MVC lato server e l'intero livello di presentazione potrebbe (ma non è necessario) essere un'altra applicazione MVC sul lato client. L'applicazione lato client può effettuare richieste in modo asincrono ai controller che a loro volta inoltrano le richieste ai modelli e inoltrano i risultati al livello di presentazione. Questo abilita il client

  1. per effettuare richieste asincrone parallele
  2. per ottenere dati parziali
  3. per gestire casi d'uso simili senza troppi sforzi

Personalmente, a parte gli scenari come le transazioni, preferisco aggregare dal lato del cliente. Sembra che ogni componente sia più leggero e semplice e che le preoccupazioni siano state separate e delegate in modo appropriato.

    
risposta data 08.08.2016 - 12:55
fonte
0

La cosa bella di MVC è che ci sono trilioni di implementazioni diverse là fuori. Sono sicuro che se hai guardato abbastanza duramente puoi trovarne uno che corrisponda a qualsiasi approccio tu abbia seguito. Per me, è stata la consapevolezza che le applicazioni web seguono un modello di richiesta / risposta che mi ha liberato dalla tirannia della cura di MVC. link

Il tuo controller ha davvero a cuore le opzioni di scelta del controllo del modulo? Ovviamente no. Quindi non c'è davvero alcuna ragione per il controller di prendere le opzioni solo per passarle sulla vista. Lascia che sia la vista a farlo. Può esserci qualche logica aziendale nel decidere quali opzioni richiede la vista? Sicuro. Quindi non vuoi davvero incorporare la logica nitida e grossa nelle tue opinioni.

Quindi qualcosa del tipo:

    // Inside of the view
    $this->gameOfficialChoices = array_merge(
        [null => 'Select Game Official'],
        $this->assignorFinder->findGameOfficialChoices($game)
    );

Nel codice di cui sopra, dobbiamo sapere quali funzionari di gioco sono autorizzati a officiare un determinato gioco. In realtà c'è un bel po 'di logica aziendale, quindi spostiamo la ricerca effettiva nel servizio AssignorFinder.

Questo tipo di approccio sembra funzionare bene per me. È MVC? Non lo so Non importa.

    
risposta data 07.09.2016 - 16:08
fonte

Leggi altre domande sui tag