MVC: Nel pattern MVC, quando e dove viene creato il modello?

3

Diciamo che ho un'applicazione che salva e recupera i suoi dati da / verso DB. Per ragioni di spiegazione, immaginiamo che l'applicazione si occupi degli studenti.

Ho un'API completa che mi consente di lavorare con le classi di business logic e di salvarle / caricarle senza problemi dal / al database. Così posso istanziare uno "Studente", quindi chiamare qualche funzione Save(Student) , e sarà correttamente salvato nel DB (con tutte le connessioni ad altre entità gestite correttamente).

Ora diciamo che ho bisogno di creare una nuova finestra ( vista ) nella mia GUI per implementare alcune nuove logiche di business. La mia nuova vista verrà chiamata dalla finestra principale dell'applicazione quando gli utenti preme un pulsante di menu.

Ho creato la vista , il modello (una classe che esegue la necessaria manipolazione dei dati e salva i risultati nel DB) e il controller (che funge da colla tra il modello e la vista ). Funziona tutto bene. Ora la mia domanda è: quando e dove istanziare il modello ?

Attualmente lo faccio nel gestore di eventi della finestra principale, che apre la mia finestra di dialogo, come questa (pseudocodice):

MainWindow::OnMyDialogRequested()
{
  Model model;
  Controller controller(model);
  GUI gui(controller);
  gui.exec();
}

La GUI è di tipo stateless quindi va bene se tutto muore quando l'utente finisce di lavorarci. Quando la GUI si avvia, visualizza una schermata iniziale e (tramite il controller ) richiede il modello per preparare i dati. Quando la GUI muore, chiede al modello (anche tramite il controller) di salvare i dati nel DB.

Tuttavia, sono preoccupato che l'istanziazione del "modello" e il controller in questo modo potrebbero essere una pessima decisione di progettazione. Come faccio a farlo correttamente?

    
posta juz11994 15.03.2017 - 08:29
fonte

2 risposte

1

Il termine Model è incredibilmente fuorviante. La maggior parte delle persone che vengono a contatto con lo schema architettonico MVC pensa che un modello sia una forma di una struttura di dati. E poiché MVC è per lo più popolare tra la programmazione orientata agli oggetti, le strutture dati sono generalmente modellate come classi. Da qui l'idea sbagliata comune che un modello sia una sorta di classe. Ma non è del tutto corretto.

In base al tuo approccio di programmazione esatto un modello potrebbe significare cose diverse ma per la maggior parte di solito è un intero livello contenente le parti che rendono divertente la programmazione = logica (condizioni, interruttori, loop, ...).

Supponiamo che tu stia adattando la progettazione basata sul dominio. In DDD la logica di business è legata a determinati contesti e il contesto è protetto utilizzando le radici aggregate. Il problema è che le radici aggregate non appaiono dal nulla e non dovrebbero farlo . Appaiono come una risposta a una determinata azione, un comando, principalmente attraverso metodi di fabbrica, che forniscono loro il contesto della creazione.

Ma diciamo che non stai adattando la DDD, non stai usando nessuna delle parole d'ordine aggregate, hai solo diverse classi che agiscono insieme che, una volta cablate correttamente, rappresentano la tua logica di business. Da dove vengono queste lezioni?

Molto probabilmente incontrerai una sorta di classe di servizio. Questa classe di servizio verrà probabilmente rappresentata come istanza singleton e sarà senza stato. È praticamente una funzione pura - trasformare l'input in output - dove le dipendenze del servizio non vengono passate come parametro del metodo ma piuttosto fornite attraverso forma di iniezione di dipendenza (che stai facendo nel tuo esempio). Queste classi di solito provengono da una sorta di contenitore Inversion of Control . Si registrano queste classi e le recuperano indietro. In questo modo puoi estrarre tutti i brutti codici di tipo spaghetti dalla tua logica aziendale e mantenere la tua logica di business pulita.

Poi c'è il secondo tipo di classi. Classi che contengono stato. In qualche modo questi potrebbero essere paragonati alla buzzword di radici aggregate che ho menzionato prima. La creazione di queste classi dovrebbe riflettere alcuni comandi emessi o alcune operazioni ma sapere che non è necessario che queste entità escano sempre da un contesto come menziona Udi (nell'articolo che ho collegato sopra). Anche se a volte aiuta a capire meglio il dominio.

Da dove provengono queste classi è una grande domanda senza risposta. Per dirla in generale, di solito appaiono dove ne hai bisogno. Potrebbero apparire nel livello dell'applicazione subito dopo la convalida dell'input dell'utente e quindi essere passati al livello della logica aziendale, potrebbero essere visualizzati direttamente nel livello della business logic. Di solito si riduce alle tue esigenze personali.

Quindi, se il modello che ti preoccupa è in realtà i servizi stateless che ho menzionato, quelli di solito vengono istanziati oggi in una sorta di contenitore IoC mentre le classi stateful vengono istanziate da te, il programmatore, quando ne hai bisogno.

    
risposta data 15.05.2017 - 23:13
fonte
0

È possibile creare una classe factory che crea l'oggetto GUI in modo da poter risparmiare la finestra principale dei dettagli su come creare un'istanza di una nuova finestra. E potresti invocare questa fabbrica sull'evento che già usi poiché ritengo sia il posto giusto per farlo.

    
risposta data 15.03.2017 - 10:52
fonte

Leggi altre domande sui tag