È pratica accettabile dare a un oggetto un puntatore a "il mondo"?

5

Spesso mi trovo in situazioni in cui gli oggetti devono comunicare tra loro. Ad esempio, un pulsante potrebbe aver bisogno di parlare con varie caselle di testo. Sarebbe corretto semplicemente costruire ogni widget con un puntatore al contenitore per tutti loro? Sarebbe meglio dargli un puntatore a una mappa del contenitore di risorse in cui l'oggetto può individuare un altro oggetto per stringa o qualcosa del genere? Questa zona è sempre stata molto vaga per me. Potrei facilmente implementare tutto ciò che voglio fare se ho appena costruito oggetti con puntatori a contenitori di ogni altro oggetto, ma ciò sembra sbagliato. Nel caso di un widget, sarebbe effettivamente più appropriato se il widget non conoscesse nulla del mondo esterno e invece i suoi listener di azioni fossero costruiti con accesso alle risorse?

Grazie

Capisco che sia una cattiva idea, ma quali sono alcune soluzioni in queste situazioni, ad esempio: buoni schemi di progettazione per il software orientato alla GUI?

Se il clic di un pulsante deve scrivere un file, come può essere fatto in modo pulito? Ascoltatori d'azione? Ma da dove vengono creati e da cosa?

    
posta jmasterx 19.05.2011 - 06:21
fonte

3 risposte

4

È meglio se si separano la logica aziendale dal codice generato dallo stato / dalla UI. Se si aggiunge la logica biz direttamente agli ascoltatori di azione generati, si tratta di un anti-pattern. Finirai con una logica molto frammentata che diventa più difficile da mantenere man mano che aggiungi altri pulsanti.

Crea la tua logica aziendale di base come se modellassi qualsiasi problema software. Aggiungi GUI in cima a questo come attivatore. Negli scenari peggiori è possibile interrogare la GUI per capire lo stato corrente delle caselle di controllo, ecc., Ma idealmente dovresti mantenere questo stato nel tuo livello di logica biz. Disaccoppiare in questo modo ti farà risparmiare molto dopo. Leggi informazioni sui modelli MVC.

Una volta che avrai percorso questo percorso, scoprirai che non hai bisogno di un puntatore del mondo, ma solo un puntatore nell'oggetto controller che può dirti tutto ciò di cui hai bisogno.

    
risposta data 19.05.2011 - 07:02
fonte
0

Un sacco di domande diverse qui, sarebbe stato meglio chiedere questo in 2 o 3 post separati, ma vediamo cosa succede ...

1) "il mondo", suppongo sia un termine relativo. Non darei un valore puntatore a "il mondo", ma sulla base del tuo esempio, direi di andare avanti perché non considererei un contenitore di un widget "il mondo". D'altra parte, se hai creato un insieme di oggetti basato su richiesta client esterna e poi invece di identificatori univoci, puntatori usati direttamente come identificatori, darebbe un puntatore alla memoria interna al mondo. Eviterei di farlo.

2) Considero gli oggetti (oi widget) che contengono puntatori ad altri oggetti (o widget) per essere automaticamente design errato. Ovviamente vuoi mantenere le cose il più liberamente accoppiate possibile, ma posso vedere alcune situazioni, dove questo sarebbe accettabile. Abbastanza sciolto significa semplicemente che vuoi che ognuno dei tuoi oggetti (o widget) sappia solo quanto sugli altri come assolutamente necessario (e non fare ipotesi sulle implementazioni interne)

3) Ho realizzato numerosi progetti in cui hai un contenitore genitore e un gruppo di bambini. Una cosa che cerco sempre di fare è evitare le dipendenze circolari dove l'oggetto A sa che B e B conoscono A. In genere, quando lo fai, stai cercando dei problemi. Invece definirei un child (la nostra classe widget) e accanto ad esso definirò l'interfaccia "IWidgetOwner" o "IWidgetKeeper" (ghostbusters reference). Quindi il genitore implementa questa interfaccia e passa un puntatore a ogni bambino. Ora hai una relazione gerarchica molto chiara. Il tuo contenitore conosce i widget che contiene, ma i widget non sanno nulla del tuo contenitore specifico. Invece, possono essere inseriti in qualsiasi contenitore che implementa la tua interfaccia di "custode".

4) Detto questo, se si sta facendo un lavoro specifico sull'interfaccia utente, starei lontano dall'aggiungere troppa logica di business all'interno dei controlli della GUI (widget) stessi. Invece, avrei un layer separato (classe) che configurerebbe le sottoscrizioni sui gestori di eventi e definirò quale azione dovrebbe essere intrapresa quando determinati eventi vengono lanciati. In questo modo il codice del tuo widget rimane generico e riutilizzabile e tutta la logica di business è racchiusa in un unico posto, quindi quando devi andare a cambiarlo, non è necessario cercare in tutto il tuo codice.

5) Un pulsante mai "necessario" per scrivere un file. Invece, l'applicazione deve scrivere un file in risposta a un clic dell'utente. Separerei sempre il codice che "funziona" dall'interfaccia utente il più possibile. Pensa allo scenario in cui desideri un secondo pulsante o un tasto di scelta rapida globale per scrivere lo stesso file? O se vuoi aggiungere automazione e devi scrivere lo stesso file ma senza alcuna GUI. Quando avvii un progetto con un'interfaccia utente, inizia definendo una linea molto chiara tra la tua GUI e il tuo lavoro. Potrebbe sembrare un sovraccarico, ma è solo un esercizio mentale e dopo averlo fatto un paio di volte, diventerà molto più naturale, quindi il sovraccarico quasi scomparirà. Ma scriverò codice che è più liberamente accoppiato e posizionato meglio per l'espansione futura.

    
risposta data 19.05.2011 - 07:11
fonte
0

Dipende dallo scopo della tua applicazione. Se stai parlando di un'utilità rapida e sporca con un pubblico limitato, certo, andrebbe bene. Con un pubblico più vasto, è possibile che le funzionalità e i miglioramenti si accumulino rapidamente.

Mettere un middle manager tra le azioni dell'utente e le viste dei dati può essere uno sforzo utile per mantenere il codice estensibile in tali circostanze. Un modo stabilito per fare ciò è seguire un modello / modello Visualizza / Controller. Oppure, se stai usando WPF, guarda in un pattern MVVM usando ViewModel, associazione dati e comandi. Andare avanti così presto è un lavoro in più, ma ti farà anticipare la curva evitando i refactori più tardi.

Infine, solo per notare, quando il codice ha riferimenti ai controlli, avere un uomo medio fornisce solo una protezione profonda della pelle da hacker. In Win32, WinForms e WPF (e praticamente tutti i framework dell'interfaccia utente) è possibile percorrere l'albero dei controlli. Quindi i tuoi controlli e il loro codice associato avranno sempre la possibilità di accedere a tutti gli altri, anche con un'architettura MVC o MVVM.

    
risposta data 19.05.2011 - 09:03
fonte

Leggi altre domande sui tag