Programmazione Orientata agli Oggetti in Linguaggio Java

Documenti analoghi
Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Tecnologie di Sviluppo per il Web

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Tecnologie di Sviluppo per il Web

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Introduzione alle reti telematiche

Reti di calcolatori Introduzione al corso

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Procedurale in Linguaggio C++

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Introduzione ai Calcolatori Elettronici

Programmazione Procedurale in Linguaggio C++

Programmazione Procedurale in Linguaggio C++

Tecnologie di Sviluppo per il Web

Programmazione Orientata agli Oggetti in Linguaggio Java

Algoritmi e Strutture di Dati

XML extensible Markup Language

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Introduzione alla rete Internet

Programmazione Orientata agli Oggetti in Linguaggio Java

Introduzione alla rete Internet

Sommario. Introduzione Architettura Client-Server. Server Web Browser Web. Architettura a Due Livelli Architettura a Tre Livelli

Programmazione Orientata agli Oggetti in Linguaggio Java

Tecnologie di Sviluppo per il Web

Tecnologie di Sviluppo per il Web

La nostra finestra dovrebbe essere come mostra la figura: Diamo innanzitutto un occhiata alle componenti principali di input/output:

Programmazione Procedurale in Linguaggio C++

Algoritmi e Strutture di Dati

Tecnologie di Sviluppo per il Web

Applicazioni grafiche e finestre

Il problema dello zaino

Programmazione Procedurale in Linguaggio C++

Prof. Pagani Corrado ESERCITAZIONI JAVA

Programmazione Orientata agli Oggetti in Linguaggio Java

Programmazione Orientata agli Oggetti in Linguaggio Java

Transcript:

Programmazione Orientata agli Oggetti in Linguaggio Java Programmazione Grafica: Organizzazione del Codice Parte b versione 1.0 Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina) G. Mecca Università della Basilicata mecca@unibas.it Programmazione Grafica: Organizzazione del Codice >> Sommario Sommario Riorganizzazione del Codice Raffinamento MVC 2

Riorganizzazione del Codice Le linee guida viste rappresentano un passo in avanti rispetto allo stile Swing ha ancora dei limiti Ma... anche avendo separato la logica applicativa nello strato del modello, resta aperto il problema di organizzare il codice nello strato di interfaccia e controllo 3 Riorganizzazione del Codice Struttura tipica dello strato di interfaccia contiene la maggior parte del codice dell applicazione per via della verbosità di Swing molte classi interne (le azioni) se l applicazione ha un unico schermo visibile (es: Morra Cinese), c è un unica classe Principale che gestisce lo schermo e contiene moltissimo codice 4

Riorganizzazione del Codice Di conseguenza questo stile funziona solo per applicazioni con GUI molto semplici in applicazioni grafiche di medie dimensioni, il codice dello strato di interfaccia e controllo diventa presto impossibile da manutenere Di conseguenza è necessario adottare strumenti per la riorganizzazione del codice 5 Riorganizzazione del Codice Riorganizzazione del codice vogliamo individuare criteri per distribuire le responsabilità nello strato di interfaccia e controllo per renderlo più modulare e quindi più facilmente gestibile e manutenibile Per farlo procediamo ad un refactoring dell applicazione della Morra Cinese 6

Individuiamo le responsabilità evidenti I responsabilità: inizializzare il JFrame e visualizzarlo (creare i menu, impostare i parametri relativi al frame) II responsabilità: gestire i pannelli che corrispondono a visualizzare gli schermi (disporre ed aggiornare i componenti) III responsabilità: gestire le azioni (crearle, abilitarle, disabilitarle, avviare l applicazione) 7 Questo suggerisce il seguente refactoring riorganizziamo il codice della classe Principale in tre componenti separati Vista ha la I responsabilità: inizializzare il JFrame e visualizzarlo SchermoPrincipale ha la II responsabilità: gestire l unico pannello necessario per l unico schermo 8

Terminologia vista = interfaccia; classi della vista = classi che gestiscono l interfaccia vista principale: la classe che gestisce il frame (JFrame) viste secondarie: le classi che gestiscono i pannelli (JPanel) visualizzati sul frame ed eventuali finestre secondarie (JDialog) la vista principale deve tenere riferimenti alle viste secondarie per poterle visualizzare 9 javax.swing.jframe javax.swing.jpanel Vista SchermoPrincipale 999 : Vista SchermoPrincipale p 555 555 : SchermoPrincipale 10

Controllo ha la terza responsabilità: gestisce le azioni Attenzione a questa scelta si tratta di una scelta naturale perchè va nella direzione di separare il codice di interfaccia da quello di controllo ma implica che le azioni non sono più classi interne delle classi di interfaccia dovremo risolvere alcuni problemi di visibilità 11 javax.swing.jframe javax.swing.jpanel Vista SchermoPrincipale Controllo main() 999 : Vista SchermoPrincipale p 555 555 : SchermoPrincipale 4921 111 : Controllo 12

I Problema di visibilità nel codice della vista ho bisogno di accedere alle azioni (es: per creare i componenti) Soluzione la classe Controllo ha una proprietà per ogni azione utilizzata nell applicazione e una serie di metodi get per consentire l accesso alle azioni dall esterno 13 Controllo 222 : AzioneEsci main() 111 : Controllo AzioneEsci azioneesci AzioneIniziaPartita azioneiniziapartita AzioneGiocataCarta azionegiocatacarta... 222 333 444 public AzioneEsci getazioneesci() public AzioneIniziaPartita getazioneiniziapartita() public AzioneGiocataCarta getazionegiocatacarta()... 333 : AzioneIniziaPartita 444 : AzioneGiocataCarta 14

II Problema di visibilità nel codice delle azioni ho bisogno di accedere ai controlli dell interfaccia per acquisirne i valori forniti dall utente e per aggiornarne lo stato a seguito dell evoluzione della logica applicativa Componenti per fornire valori in ingresso tipicamente JTextField, JTextArea, JCheckBox, JRadioButton 15 Soluzione le classi della vista forniscono metodi get per accedere ai valori dei componenti attraverso cui l utente fornisce valori inoltre forniscono metodi di schermo per aggiornarne lo stato a seguito di un azione l azione acquisisce il valore del componente, elabora il valore, poi chiama il metodo di schermo per aggiornare l interfaccia 16

javax.swing.jframe javax.swing.jpanel Vista SchermoPrincipale 999 : Vista SchermoPrincipale p public SchermoPrincipale getschermoprincipale() public voidfinestrapunteggio() public voidfinestrainformazioni() 555 555 : SchermoPrincipale public voidschermoiniziale() public voidschermonuovapartita() public voidschermopartitaincorso() 17 III Problema di visibilità nelle azioni è necessario accedere ai bean del modello per chiamarne i metodi lo stesso vale nella vista, per prelevarne i valori da mostrare sullo schermo ho bisogno da tutte e due le parti di acquisire riferimenti ai bean questi riferimenti possono essere molti nel caso in cui il modello sia complesso 18

Soluzione utilizzo una classe Modello come deposito centralizzato di riferimenti ai bean una proprietà per ciascun bean e metodi get e set per le proprietà ogni volta che un azione crea un bean la salva nel modello chiamando un metodo set successivamente il bean è possibile lavorare con il bean utilizzando il metodo set 19 999 : Vista SchermoPrincipale p 555 101: Gioco Modello 555 : SchermoPrincipale 102: Partita 111 : Controllo 4921 1000 : Modello Gioco gioco Partita partita Mano mano public voidsetgioco() public voidsetpartita() public voidsetmano() public Gioco getgioco() public Partita getpartita() public Mano getmano() 101 102 103 103: Mano 20

Terminologia la classe modello mantiene lo stato della sessione di lavoro ovvero in questo caso lo stato del modello durante lo svolgimento del gioco Stato della sessione è dato dai valori dei componenti del modello presenti nello heap 21 Nota il componente Modello non è indispensabile ma è particolarmente utile per risolvere i problemi di visibilità collegati all accesso ai bean è sufficiente che le classi di vista e di controllo abbiano un riferimento al modello per avere accesso a tutti i bean invece che tanti riferimenti a ciascun bean 22

Riassumendo tre nuove classi significative Controllo che mantiene lo stato delle azioni Vista (con le relative sottoviste) che mantiene lo stato della gui Modello che mantiene lo stato dei bean 23 Questi tre componenti rappresentano l infrastruttura fondamentale di un applicazione con interfaccia grafica Relazione tra i tre componenti il controllo mantiene un riferimento alla vista ed uno al modello la vista mantiene un riferimento al controllo ed uno al modello 24

interfaccia 555 : SchermoPrincipale >> morracineseswing.refactoring sottoviste 999 : Vista 101: Gioco SchermoPrincipale p Modello modello Controllo controllo 555 1000 111 111 : Controllo public getschermoprincipale() // metodi di schermo Vista vista Modello modello AzioneEsci azioneesci AzioneGiocataCarta azionecarta... 999 1000 222 444 1000 : Modello Gioco gioco Partita partita Mano mano // get e set per i Bean 101 102 103 bean 102: Partita // get per le Azioni 222 : AzioneEsci 444 : AzioneGiocataCarta infrastruttura MVC 103: Mano azioni controllo modello 25 Riassumendo per organizzare le responsabilità e semplificare la scrittura del codice abbiamo adottato un infrastruttura standard fatta delle classi Modello, Vista e Controllo Modello: coordina l accesso ai bean Vista: coordina l accesso alle sottoviste Controllo: coordina l accesso alle azioni 26

Nota negli esempi le azioni continuano ad essere classi interne al controllo questo però per pura comodità (accedono ai riferimenti al modello e alla vista) sarebbe però possibile facilmente trasferirli in classi esterne fornendo nel costruttore il riferimento al controllo 27 Raffinamento Un altro esempio it.unibas.indovinaswing Caratteristiche dell applicazione complessità comparabile alla Morra Cinese ma ci sono alcune differenze necessità di effettuare convalide dei dati due schermi (nome e poi partita) utilizzo di gestori di layout 28

Raffinamento Dimensioni delle due versioni versione console: 360 linee di codice versione swing: 744 linee di codice (+52%) Il package it.unibas.indovinaswing.gui complessivamente 454 linee di codice organizzato secondo l infrastruttura MVC con un raffinamento 29 Raffinamento Raffinamento dell infrastruttura separiamo le azioni dalla classe di controllo introduzione di mappe di riferimenti al posto dei metodi get/set Separiamo le azioni le azioni non sono più classi interne al controllo ricevono un riferimento al controllo attraverso il costruttore e quindi anche a vista e modello 30

package it.unibas.indovinaswing.controllo; public class AzioneInformazioni extends javax.swing.abstractaction { private Controllo controllo; public AzioneInformazioni(Controllo controllo) { this.controllo = controllo; this.putvalue(javax.swing.action.name, "Informazioni sul gioco"); this.putvalue(javax.swing.action.short_description, "Informazioni sul gioco"); this.putvalue(javax.swing.action.mnemonic_key, new Integer(java.awt.event.KeyEvent.VK_M)); } } public void actionperformed(java.awt.event.actionevent e) { this.controllo.getvista().finestrainformazioni(); } 31 Raffinamento Mappe dei riferimenti i bean nel modello possono essere molti le azioni nel controllo possono essere molte le sottoviste nella vista possono essere molte per ciascuna dovrei definire un metodo get (e nel modello anche il metodo set) codice lungo e noioso da manutenere 32

Raffinamento Soluzione sostituisco i riferimenti ordinari con una mappa di riferimenti nel modello i metodi get/set diventano Object getbean(string nome) void putbean(string nome, Object bean) nella vista Object getsottovista(string nome) nel controllo Action getazione(string nome) ATTENZIONE a inizializzare le mappe 33 vista 555 : HashMap sottoviste DAORecord persistenza 999 : Vista Map mappasottoviste Modello modello Controllo controllo + Object getsottovista(string nome) 555 1000 111 DAOException 111 : Controllo Vista vista Modello modello Map mappaazioni 999 1000 555 + Object getazione(string nome) + void setazione(string nome, Action azione) 1000 : Modello Map mappabean 102 + Object getbean(string nome) + void setbean(string nome, Object bean) 555 : HashMap azioni bean 102: HashMap controllo modello 34

Raffinamento Inizializzazione del controllo crea tutte le azioni e le aggiunge alla mappa // Controllo.java private void inizializzaazioni() { mappaazioni.put("azioneesci", new AzioneEsci(this)); mappaazioni.put("azionerecord", new AzioneRecord(this)); mappaazioni.put("azioneabout", new AzioneInformazioni(this)); mappaazioni.put("azionenuovapartita", new AzioneNuovaPartita(this));... } 35 Raffinamento La gerarchia delle viste in questo caso, a differenza che nel precedente, ho due diversi schermi che vengono visualizzati all utente Vista: gestisce il frame principale SchermoIniziale: pannello che corrisponde allo schermo iniziale (per fornire il nome) SchermoPartita: pannello che corrisponde allo schermo su cui si gioca la partita 36

Raffinamento Inoltre vengono visualizzate varie finestre di dialogo (finestre secondarie) standard attraverso metodi di JOptionPane Inizializzazione della mappa è indispensabile che la vista inizializzi correttamente la mappa inserendo i riferimenti a tutte le sottoviste ed inizializzandole opportunamente 37 Raffinamento // Vista.java public void inizializza() { this.mappasottoviste.put("schermoiniziale", new SchermoIniziale(this)); this.mappasottoviste.put("schermopartita", new SchermoPartita(this)); this.getcontentpane().setbackground(new Color(255, 241, 167)); creaframe(); creamenu(); this.pannelloprincipale = (JPanel)getContentPane(); } 38

Raffinamento Un metodo interessante il metodo schermoavviagioco() è il metodo attraverso il quale viene sostituito lo schermo Idea viene eseguito dalla vista principale rimuove dal content pane il pannello iniziale e lo sostituisce con l altro al termine richiama il metodo pack() 39 // Vista.java public void schermoiniziale() { SchermoIniziale schermoiniziale = (SchermoIniziale)this.mappaSottoViste.get("schermoIniziale"); this.getcontentpane().add(schermoiniziale); this.pack(); this.setvisible(true); } public void schermoavviagioco() { SchermoIniziale schermoiniziale = (SchermoIniziale)this.mappaSottoViste.get("schermoIniziale"); SchermoPartita schermopartita = (SchermoPartita)this.mappaSottoViste.get("schermoPartita"); this.getcontentpane().remove(schermoiniziale); this.getcontentpane().add(schermopartita); schermopartita.schermonuovapartita(); this.pack(); // this.repaint(); NON E INDISPENSABILE: forza il frame a ridisegnarsi } 40

Raffinamento Rapporto tra vista e controllo in questo caso, a differenza che nel precedente, le azioni devono leggere i valori forniti dall utente (nome e tentativo) è necessario che la vista fornisca metodi opportuni String gettestonome() in SchermoIniziale String gettestotentativo() in SchermoPartita 41 999 : Vista Map mappasottoviste Modello modello Controllo controllo 555 + Object getsottovista(string nome) + void inizializza() + void schermoiniziale() + void schermoiniziogioco() // NOTA + void finestrarecord(string record) + void finestrainformazioni() + void finestraerrore(string messaggio) >> it.unibas.indovinaswing 555 : HashMap : SchermoIniziale : SchermoPartita + void inizializza() + String gettestonome() + void inizializza() + String gettestotentativo() + void schermonuovapartita() + void schermofinepartita() + void schermopartitainterrotta() + void schermoaggiornapartita() 42

Programmazione Grafica: Organizzazione del Codice >> MVC MVC Riassumendo abbiamo separato completamente i quattro strati fondamentali dell architettura Architettura Modello-Vista-Controllo architettura in cui il codice dei tre strati di modello, interfaccia e controllo è separato può esserci un ulteriore strato di persistenza (che può anche essere accorpato al modello) 43 Programmazione Grafica: Organizzazione del Codice >> MVC MVC utilizza Vista (schermi) esegue utilizza esegue Controllo (azioni) utilizza crea utilizza Modello (JavaBeans) crea utilizza Persistenza (DAO) Memoria Persistente Servizi di Base 44

Programmazione Grafica: Organizzazione del Codice >> MVC MVC Vantaggi della separazione degli strati utile in applicazioni di dimensioni medio/grandi e di struttura articolata (es: Swing; con la console sarebbe inutile) aiuta ad organizzare il codice riduce l accoppiamento tra gli strati se vengono rispettate le regole e quindi semplifica la manutenzione 45 Programmazione Grafica: Organizzazione del Codice >> MVC MVC Ma... la separazione tra vista e controllo che abbiamo sviluppato è imperfetta i due strati restano fortemente accoppiati (unico caso di frecce di comunicazione bidirezionali) sarà necessario intervenire ulteriormente 46

Programmazione Grafica: Organizzazione del Codice >> Sommario Riassumendo Riorganizzazione del Codice Raffinamento MVC 47 Termini della Licenza Termini della Licenza This work is licensed under the Creative Commons Attribution- ShareAlike License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. Questo lavoro viene concesso in uso secondo i termini della licenza Attribution-ShareAlike di Creative Commons. Per ottenere una copia della licenza, è possibile visitare http://creativecommons.org/licenses/by-sa/1.0/ oppure inviare una lettera all indirizzo Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. 48