|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
[OOP] Questione sul pattern MVC
Per chi conosce il pattern MVC...
Mi sta sorgendo un dubbio (pippe mentali?... forse). Mettiamola così, in modo semplice senza andare troppo nello specifico della mia applicazione. Io ho la mia View con un elenco di programmi esterni eseguiti tramite essa. L'elenco è rappresentato da una ListBox di WindowsForm, ma non è importante questo fatto. Qunado un utente esegue tramite la View un programma esterno, secondo il pattern MVC, la chiamata deve essere delegata ad un Controller che nasconde la complessità della logica dell'applicazione. Il problema amletico è questo. La ListBox della View è solo la rappresentazione dei dati, che in questo caso sono dei programmi eseguiti di recente. Ma "sotto", nel Modello, questo elenco deve essere implementato in qualche altro modo, un array, una lista, un hashtable... la ListBox quindi deve solo riflettere lo stato della lista che rappresenta l'elenco no?! Ma quindi questa lista dove deve stare? Come si può effettuare il binding tra la lista dei programmi e la sua rappresentazione nella View? Perchè attualmente mi viene in mente solo che se dalla View chiamo il Controller per eseguire il programma esterno, il Controller esegue questo programma, aggiunge un riferimento al programma nella lista che implementa l'elenco dei programmi recenti (e quindi la lista starebbe dentro al Controller) e richiama la View tramite un suo metodo pubblico fatto ad-hoc per avvertirla del fatto che la lista dei programmi recenti è cambiata, e di conseguenza la View riaggiornerà la ListBox visualizzata. Mi suona pure bene in realtà, se non fosse che questa soluzione non è di certo scalabile. Finché ho una lista e basta nel Controller ok, ma supponiamo che abbia tante View diverse nella mia applicazione, ognuna delle quali visualizza lo stato di alcuni dati, similmente a quanto descritto per l'elenco dei programmi recenti... beh in questo caso non posso creare un metodo di notifica apposito per ogni dato che ogni form necessita di mantenere aggiornato!!! E' pura pazzia dal punto di vista del programmatore! Nella mi mente questa situazione mi ricorda il pattern Observer... però non ne sono convinto. Perchè questo pattern funziona solo nel caso in cui è possibile incapsulare un gruppo di dati omogeneo per il quel un certo numero di View si registra come Observer, e il Controller, ogni volta che modifica lo stato di questo gruppo di dati, andrebbe a notificarlo a tutte le View/Observer registrate. Bellissimo certo, ma nel mio caso sostanzialmente ogni View sarebbe Observer di un dato diverso e la notifica riguarderebbe solo quella View... non ho guadagnato niente in termini di codice da scrivere e mantenere!! Help! |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Nessuno che sa chiarirmi questi dubbi?
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 1451
|
Il pattern MVC è spesso correlato con il pattern observer.
I'observer lo utilizzi per notificare alla view un cambiamento nel suo model. E poi mica è detto che una view deve essere observer di un solo model. La relazione non è assolutamente univoca.
__________________
Ciao ~ZeRO sTrEsS~ |
![]() |
![]() |
![]() |
#4 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
Una View che sia Observer di qualche Model, implementa un'interfaccia comune che è appunto Observer, che sostanzialmente deve esporre un unico metodo astratto: update(). Poi ogni View implementa questo metodo come meglio crede. Se una View necessita di essere Observer di più dati, e potenzialmente di più Model se i dati appartengono a Model diversi fra loro, allora significa che per ogni dato "logicamente autonomo e indipendente" dagli altri, deve esserci un'interfaccia Observer ad-hoc, altrimenti se ce ne fosse solo una di interfaccia, l'unico metodo update() esistente come fa a sapere quale dato o quale gruppo di dati è stato aggiornato? Cosa fa aggiorna tutti i dati della View anche se appartengono a Model diversi? Boh... sono perplesso. Non riesco a capire bene come possa funzionare. Ultima modifica di mcaisco : 31-12-2008 alle 08:51. |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
...non ho capito il tuo dubbio
![]() in java ad esempio (o in C# o in qualsiasi altro linguaggio immagino) tu devi gestire solo il modello e il controller ed eventualmente estendere e/o incapsulare i componenti già pronti. Che tu abbia una lista sola oppure mille non ti cambia assolutamente nulla a te. con il metodo di update le viste sanno esattamente come aggiornarsi e ricaricano i dati dal modello collegato....
__________________
![]() |
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: Mar 2004
Messaggi: 1451
|
Quote:
Quote:
Penso che utilizzando questi, puoi distinguire i diversi aggiornamenti che ti interessano.
__________________
Ciao ~ZeRO sTrEsS~ |
||
![]() |
![]() |
![]() |
#7 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
Faccio un esempio. Se ho un'applicazione di rilevamenti metereologici con una View che visualizza, per esempio, 3 gruppi di dati: - dati dell'utente loggato (nome, cognome, ruolo...) - dati delle rilevazioni (temperatura, pressione...) - dati della zona visualizzata (nome, coordinate, orario scelto...) La cosa fondamentale comunque è che questi gruppi di dati sono indipendenti fra loro, in modo che non possano far parte di una stessa classe di dati. Quindi la View avrà ogni tanto la necessità di aggiornare i 3 gruppi di dati. Per fare questo con il pattern Observer, la View non può essere una semplice classe che implementa l'interfaccia Observer perchè altrimenti avrebbe un solo metodo update() con il quale dovrebbe essere in grado di aggiornare tutti i gruppi di dati. Ma non saprà mai quale sia il vero dato cambiato. Magari c'è una semplice variazione di temperatura (gruppo di dati 2). La chiamata alla update() che fa? Aggiorna tutti i 3 gruppi di dati? Quello che mi viene in mente è di creare 3 interfacce Observer: ObserverUser, ObserverMeteo, ObserverZone. La View dovrebbe quindi implementare tutte e 3 le interfacce, avendo quindi 3 diversi metodi di update(): updateUser(), updateMeteo(), updateZone(). In ogni caso comunque devo sempre creare una classe per ciascun gruppo di dati, ognuna delle quali è un'implementazione dell'interfaccia Observable. Insomma non mi sembra per nulla un sistema di programmazione scalabile. Se ho una View con 10 gruppi di dati diversi? Devo creare 10 interfacce di tipo Observable! E poi in fin dei conti la differenza fra queste interfacce è semplicemente il metodo update() che cambia di nome... Avete capito qual è il mio dubbio quindi? |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
|
![]() |
![]() |
![]() |
#9 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
Quello che mi incasina il cervello è che questo pattern Observer apparentemente funziona in maniera pulita solo se ogni Observer ha esattamente un solo oggetto da osservare. Quando ha più di un oggetto da osservare bisogna trovare un modo per distinguere quale di questi oggetti sotto osservazione è realmente cambiato. E questo non è indicato nelle descrizioni del pattern in letteratura. |
|
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
Una view serve appunto per gestire dei dati omogenei. Detto questo, ancora mi sfugge il problema.. ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#11 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
In questo sito ho trovato un'esauriente trattazione del pattern Observer e indica chiaramente il principio con cui risolvere una situazione come quella descritta da me.
Ecco cosa dice: Quote:
update(Observable subject) Internamente quindi il metodo update di ciascuna View/Observer implementerà un meccanismo per definire quale sia effettivamente l'Observable da aggiornare (ad esempio con una serie di if-else if, o con uno switch). |
|
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
come dicevamo io e tomminno per fare una cosa del genere che hai spiegato nel post precedente non ti serve una sola View, ma un insieme di View. In quel caso verrà variata solo la view che necessita di un update dei dati e le altre resteranno invariate..Ancora non ho capito perchè vuoi far gestire dei dati non-omogenei ed indipendenti ad una sola view.. ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#13 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
Il problema è generale. Non sto cercando una soluzione specifica per una mia applicazione. Il problema è riassumibile così: in una View/Observer come faccio ad accorgermi del cambimento di uno dei dati che la View presenta all'utente? Il problema nasce dal fatto che il pattern Observer utilizza uno specifico metodo update() chiamato proprio da uno dei dati che ha cambiato stato e che quindi deve inviare questo evento a tutte le View/Observer che lo osservano. Dunque se una View osserva un solo dato è ovvio che appena qualcuno chiama il suo metodo update() saprà con certezza che è lo stato da aggiornare è quello relativo all'unico dato che sta osservando. Ma se ci sono più dati da osservare non basta più un semplice metodo update(). Serve un metodo che sappia discriminare quale dato fra i tanti osservati sia stato modificato. Pare quindi che l'unica via sia quella di passare nel metodo update() anche un riferimento all'oggetto aggiornato che la View osserva. Il metodo update() quindi internamente poi potrà discriminare quale sia questo oggetto e fare le opportune azioni. L'unico problema in sé è che questo sistema costringe ad implementare un meccanismo che permetta di discriminare quale oggetto sia stato modificato nel metodo update() a discapito dell'efficienza generale e costringe anche ad avere una visione generale dell'architettura per poter individuare quale sia l'oggetto modificato. Un piccolo appunto. A mio parere una View non presenta dati omogenei fra loro. Presenta solo dati utili e sopratutto necessari allo svolgimento di alcune operazioni da parte dell'utente. Questi dati potrebbero essere di natura totalmente diversa fra loro, ma in quella View cooperano permettendo all'utente di svolgere delle azioni. Per questo motivo sostanzialmente non è detto che tutti i dati di una View si aggiornino insieme. Alcuni potrebbero rimanere fissi, altri cambiare più volte. Perciò una View necessita di sapere con esattezza quali sono i dati che sono cambiati e quali no. |
|
![]() |
![]() |
![]() |
#14 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
|
|
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
|
Quote:
Non puoi associare + modelli ad una view, è concettualmete sbagliato, almeno per come ho sempre visto il paradigma MVC... Per fare quello che vuoi avrai bisogno di diverse View. In un'applicazione normale ad esempio avrai vari pannelli collegati ognuno ad un unico modello.
__________________
![]() |
|
![]() |
![]() |
![]() |
#16 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
Dunque ammettiamo che ci siano diverse classi che rappresentano vari modelli di dati correlati fra loro (i dati utente ad esempio possono stare in un modello). Quello su cui sono poco d'accordo è che in una View debba avere tanti pannelli ognuno collegato ad un proprio modello. Non credo sia così. Il modello generale dei dati sarà formato diciamo da un numero limitato di classi-modello. Le View possono invece essere decine se l'applicazione è complessa, e ciascuna View può avere un numero considerevole di pannelli o simili che raggruppano dati omogenei. Quindi in totale il rapporto fra pannelli (o simili) e classi-modello non può essere 1:1. E comunque non è detto che un pannello contenga dati appartenenti ad un solo modello. Una View potrebbe presentare dei pannelli che contengono dati appartenenti a modelli diversi, ma che in quella View hanno senso presentati insieme. In definitiva quello che mi sembra scorretto è effettuare il binding View-Modello all'interno di un pannello o oggetto grafico simile. Non pensi? |
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Mar 2004
Messaggi: 1451
|
mcaisco, la soluzione che hai trovata è quella che ti avevo suggerito poco prima.
Personalmente, credo sia possibile associare più modelli ad un unica view, il pattern observer lo consente, non vedo, ad eccezione di preferenze personali, perchè limitarsi.
__________________
Ciao ~ZeRO sTrEsS~ |
![]() |
![]() |
![]() |
#18 | |
Member
Iscritto dal: Jun 2006
Messaggi: 117
|
Quote:
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:19.