Come posso separare l'interfaccia utente dalla business logic mantenendo l'efficienza?

16

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

Dato che voglio separare l'interfaccia utente e la logica, dovrei passare al modulo una rappresentazione in formato stringa degli hamburguers per visualizzarli nella casella combinata. Altrimenti, l'interfaccia utente dovrebbe scavare nei campi degli oggetti. Quindi l'utente sceglie un hamburguer dalla casella combinata e lo invia nuovamente al controller. Ora il controllore dovrebbe trovare di nuovo detto hamburguer in base alla rappresentazione della stringa utilizzata dal modulo (forse un ID?).

Non è incredibilmente inefficiente? Hai già avuto gli oggetti da cui vuoi sceglierne uno. Se hai inviato al modulo tutti gli oggetti, e poi hai restituito un oggetto specifico, non dovresti rifarlo in seguito poiché il modulo ha già restituito un riferimento a tale oggetto.

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

    
posta Uri 28.12.2011 - 02:23
fonte

2 risposte

30

Innanzitutto, l'esempio che hai fornito non è incredibilmente inefficiente; è solo leggermente inefficiente; la sua inefficienza è al di sotto del livello percepibile. Ma, in ogni caso, passiamo alla domanda.

Per come la intendo, quando parliamo di separazione di UI e logica , intendiamo evitare l'accoppiamento ravvicinato .

Accoppiamento ravvicinato fa riferimento 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 ravvicinato, non è necessario ricorrere ad abolire del tutto l'accoppiamento. (Questo è ciò che sembra mirare a demolire l'interfaccia tra di loro fino a un'interfaccia di stringa a minimo comune denominatore.) Tutto ciò che si deve fare è utilizzare accoppiamento libero .

Accoppiamento lento significa che A conosce B, ma B non sa A. In altre parole, le due parti coinvolte giocano distinti client e server ruoli, dove il client conosce il server, ma il server non conosce il client.

Nel caso dell'interfaccia utente e della logica, il modo migliore di organizzare questo a mio parere è vedere la logica come server e l'interfaccia utente come client. Quindi, l'interfaccia utente è costruita per la logica, ha conoscenza della logica e invoca la logica, mentre la logica non conosce l'interfaccia utente e risponde semplicemente alle richieste che riceve. (E queste richieste arrivano dall'interfaccia utente, ma la logica non lo sa.)

Per dirla in termini più pratici, da nessuna parte all'interno dei file del codice sorgente della logica dovresti trovare delle istruzioni di inclusione / importazione / uso che fanno riferimento ai file dell'interfaccia utente, mentre i file del codice sorgente dell'interfaccia utente saranno pieni di include / importare / utilizzare istruzioni che si riferiscono a file logici.

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

Per inciso, questo design consente un'altra cosa che dovresti aspettarti da un sistema del genere: dovrebbe essere possibile collegare tante diverse interfacce utente come desideri alla logica, e il tutto dovrebbe comunque funzionare.

    
risposta data 28.12.2011 - 11:49
fonte
4

Devi separare ogni pezzo del modello, Visualizza & Controller, ma non c'è motivo per cui non è possibile (ad esempio) passare gli oggetti del modello tra il controller e la vista.

Quindi nel tuo caso, gli oggetti Hamburger faranno parte del Modello. Quindi si utilizza il controller per recuperare l'elenco richiesto di Hamburger s e passare tali oggetti alla vista (la casella combinata) da visualizzare. Quando il tuo utente ha selezionato quale hamburger, puoi quindi passare di nuovo l'oggetto Hamburger al Controller per l'elaborazione.

Il punto è che puoi ancora testare la logica "recupera Hamburger s" e la logica "processo Hamburger " separatamente dalla visualizzazione effettiva degli hamburger.

    
risposta data 28.12.2011 - 02:35
fonte

Leggi altre domande sui tag