Come posso separare l'interfaccia utente dalla logica aziendale pur mantenendo l'efficienza?


19

Diciamo che voglio mostrare un modulo che rappresenta 10 oggetti diversi su una casella combinata. Ad esempio, desidero che l'utente scelga un hamburguer tra 10 diversi che contengono pomodori.

Dal momento che voglio separare l'interfaccia utente e la logica, dovrei passare al modulo una rappresentazione in formato stringa degli hamburger per visualizzarli nella casella combinata. Altrimenti, l'interfaccia utente dovrebbe scavare nei campi degli oggetti. Quindi l'utente selezionerebbe un hamburguer dalla casella combinata e lo inoltrerebbe nuovamente al controller. Ora il controller dovrebbe ritrovare detto hamburguer in base alla rappresentazione di stringa utilizzata dal modulo (forse un ID?).

Non è incredibilmente inefficiente? Avevi già gli oggetti da cui sceglierne uno. Se hai inviato al modulo tutti gli oggetti e poi hai restituito un oggetto specifico, non dovresti trovarlo più tardi poiché il modulo ha già restituito un riferimento a quell'oggetto.

Inoltre, se sbaglio e dovresti effettivamente inviare l'intero oggetto al modulo, come posso isolare l'interfaccia utente dalla logica?


In che modo sarebbe inefficiente? In ogni caso, devi mostrare una rappresentazione di stringa all'utente e mappare la sua risposta all'oggetto originale.
Simon Bergot,

Il problema è che per lavorare con detto oggetto, devo recuperarlo di nuovo dopo che l'utente lo ha scelto.
Uri,

Risposte:


34

Prima di tutto, l'esempio che hai fornito non è incredibilmente inefficiente; è solo leggermente inefficiente; la sua inefficienza è inferiore al livello percepibile. Ma, in ogni caso, andiamo avanti con la domanda.

Il modo in cui lo capisco, quando parliamo di separazione di UI e Logica , intendiamo evitare l'abbinamento stretto .

Lo stretto accoppiamento si riferisce alla situazione in cui l'interfaccia utente conosce (e invoca) la logica e la logica conosce (e invoca) l'interfaccia utente. Per evitare un accoppiamento stretto non è necessario ricorrere completamente all'abolizione dell'accoppiamento. (È quello a cui sembra mirare demolendo l'interfaccia tra loro fino a un'interfaccia di stringa con il minimo comune denominatore.) Tutto ciò che occorre fare è utilizzare un accoppiamento libero .

L'accoppiamento allentato significa che A conosce B, ma B non conosce A. In altre parole, le due parti coinvolte svolgono ruoli distinti client e server , in cui il client conosce il server, ma il server non conosce il client.

Nel caso dell'interfaccia utente e della logica, il modo migliore per organizzare questo secondo me è vedere la logica come un server e l'interfaccia utente come un client. Quindi, l'interfaccia utente è costruita per la logica, ha conoscenza della logica e invoca la logica, mentre la logica non sa nulla sull'interfaccia utente e risponde semplicemente alle richieste che riceve. (E queste richieste provengono dall'interfaccia utente, ma la logica non lo sa.)

Per dirla in termini più pratici, da nessuna parte all'interno dei file di codice sorgente della logica dovresti trovare istruzioni include / import / using che si riferiscono a file UI, mentre i file di codice sorgente dell'interfaccia utente saranno pieni di include / import / using istruzioni che fanno riferimento a file logici.

Quindi, per tornare al tuo caso, non c'è assolutamente nulla di sbagliato nel fatto che il codice dell'interfaccia utente che popola la casella combinata sia a conoscenza della classe hamburger. Ci sarebbe un problema se la classe di hamburger sapesse qualcosa sulle caselle combinate.

Per inciso, questo design consente un'altra cosa che dovresti aspettarti da un tale sistema: dovrebbe essere possibile collegare tutte le diverse UI che desideri alla logica e il tutto dovrebbe ancora funzionare.


5

Dovresti separare ogni parte del Modello, Vista e Controller, ma non c'è motivo per cui non puoi (ad esempio) passare oggetti Modello tra il Controller e la Vista.

Quindi, nel tuo caso, gli Hamburgeroggetti sarebbero parte del Modello. Quindi utilizzare il controller per recuperare l'elenco richiesto di Hamburgers e passare quegli oggetti alla vista (la casella combinata) per visualizzarli. Quando l'utente ha selezionato quale hamburger, è quindi possibile passare Hamburgernuovamente l' oggetto al controller per l'elaborazione.

Il punto è che è ancora possibile testare la Hamburgerlogica "fetch s" e la logica "process Hamburger" separatamente dalla visualizzazione effettiva degli hamburger.


Capisco. Tuttavia, se modifico la classe Hamburguer, non dovrò modificare anche il codice del modulo che si occupa degli oggetti Hamburguer? Dov'è allora la separazione UI-Logic?
Uri,

2
L'hamburger fa parte del modello. Quando si modifica il modello, si finisce per modificare la vista e il controller. Il modello è la separazione tra UI e logica. Toccarlo ha un costo più elevato, quindi è necessario prestare attenzione durante la progettazione.
Simon Bergot,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.