Programmazione III
universityInfo Corso
- Orari:
- Mar: 9-11
- Gio: 11-13
- Mer: 9-11 (Lab1)
 
- Testi:
- IDE
- IntelliJ IDEA
 
Teoria
Programmazione ad Oggetti
Concetti Base
Secondo Alan Kay (Smalltalk)
- 
Oggetti fornitori di servizi - Stato
- attributi
 
- Tipo/Classe
 
- Stato
- 
Richieste/Metodi - delega al metodo, si conosce l’API non l’implementazione - modificano lo stato
- invio richieste ad altri oggetti
- comunicazione di informazioni
 
- 
Object-oriented Design - progettazione orientato ad O
 
- 
Classe/Istanza - astratto/concreto
- concreto anche in memoria nello Heap
 
 
- astratto/concreto
p. procedurale vs p. oggetti
- Procedurale
- Algoritmi + Strutture Dati
 
- Oggetti
- Oggetti + Collaborazione
si scorporano funzionalitá diverse in oggetti diversi: delega
- dati + algoritmi
- interfacce
 
 
- Oggetti + Collaborazione
si scorporano funzionalitá diverse in oggetti diversi: delega
Gerarchia
- kind-of hierarchy
- part-of hierarchy
- ereditarieta'
- 
polimorfismo - 
Binding Dinamico Binding statico, all’atto della compilazione Binding dinamico, l’esecutore puó controllare i tipi degli oggetti, e decidere a runtime il body del metodo da eseguire - esegue l’implementazione piú specifica possibile
- solo sui metodi, le variabili non vanno a fare overriding
 Estremamente modulare e scalabile, meccanismo di delaga 
 - 
Classi Astratte Utilizzate come interfaccia comune e pubblica, la sottoclasse andrá a implementare i dettagli 
 - 
Interfacce Non possono avere metodi non astratti - non sono soggette all’ereditarietá singola, una classe puó implementare tutte le interfacce di cui ha bisogro
 
 - 
Overloading Definizione di firma alternativa di metodo esistente A tempo statico viene scelta la firma, é bloccante e se ci sono eventuali overloading vengono persi - a runtime si discende solamente la catena di ereditarietá
 
 - 
Overriding Diverso dall’Overloading in quanto le firme sono le stesse 
 
- 
- reflection
Tipi Generici
Introdotti per scrivere codice generico, applicabile a piú tipi di dati
- type checking statico
- il compilatore previa compatibilitá tra tipo attuale e generico, sostituisce il tipo attuale a E
- erasure
 
- vincoli/restrizioni sul tipo T: upperbound al tipo parametrico
- extends Comparable <T>.
- extendsa una singola classe- ma multiple inferfacce
 
 
- 
Raw types Utilizzando Object direttamente, in questo modo peró il compilatore non puó controllare la correttezza dei tipi 
- 
Collezioni Vincoli sintattici per evitare errori a Runtime che non sarebbero rilevati: - quindi le Collectionsono controllate per Nome del tipo, non viene considerata l’ereditarietá- si risolve utilizzando l’upcasting
 
 Per risolvere e definire una Collectiondi qualsiasi cosa- Collection<?>.
- si utilizza la wildcard
- per restringerlo si utilizza anche in questo caso extends
 
- per restringerlo si utilizza anche in questo caso 
 
- quindi le 
Interfacce
- Collection
- Add()
 
- Iterator
- hasNext()
- next()
 
Classi e Interfacce innestate
Innestando una classe dentro l’altra si facilita il codice mantenendo i contenenti privati
- questo vale sia dalla classe interna che quella estesna
Per information hiding la classe interna puó essere solo meno visibile o uguale a quella esternaPer information hiding la classe interna puó essere solo meno visibile o uguale a quella esternanon puó sempre rispondere
- le classe INhanno un puntatoreouterThische permette di fare riferemento al contenitore- tramite quello hanno accesso come fossero locali
 
- 
Classi innestate in interfacce - Interfaccia publica
- classe statica che rappresenta l’implementazione di default dell’Iterfaccia
 
- si puó estendere oppure
 Possibile avere classi nested anonime definendo in line - return new Iteratore(){ ... }
 Posso essere ancora piú sintetico utilizzando le lambda expression- ovviamente non deve esserci ambiguitá per quanto riguarda i parametri, un’interfaccia con metodi non ambigui e con poche righe di codice si presta ad una lambda
- inoltre é possibile omette i tipi dei parametri se sono inferibili
- é possibile omettere graffe e returnse si tratta di una singola istruzione, deve essere una funzione (restituire un valore)
- se il paremetro é uno si possono omettere le parentesi tonde
 
- Interfaccia publica
Pattern Architetturali
Una classe Kernel che utilizza una Interfaccia Modulo cui poi si sceglierá una implementazione con una Implementazione del Modulo
- Observer-Observable
- Model View Controller
- Facade- lavorare in upcasting quando permesso
- utilizzare interfacce e non classi specifiche per parti la cui implementazione puó variare
 
IO
- Flussi di byte
- InputStream
- OutputStream
- PrintStream
 
- File
- FileReader
- FileWriter
 
Utile comporre stream
Buffered Reader in = new BufferedReader(new FileReader(“es.txt”))
Per scrivere e leggere dati primitivi:
- DataInputStream
- DataOutputStream
Per scrivere e leggere oggetti (Serializable)
- ObjectInputStream
- ObjectOutputStream
- file testuali
- Scanner
- File
- PrintWriter
 
- file binari
- FileInputStream
- FileOutputStream
 
Da File
GUI
- AWT- Abstact Window Toolkit
- SWING- JFrame
- JApplet
- JDialog
 
Programmazione ad Eventi
Event-Driven Programming
Differentemente da un classico programma, che ad un input restituisce un output seguendo un suo flusso di controllo e solo raramente si attende input dal utente, questa metodologia consiste in procedure che rispondono a certi eventi
- event handlers
- events
Si distinguono due fasi:
- Ciclo di individuazione degli eventi
- Gestione degli eventi
Dopo essere stati creati gli event-handlers devono essere associati come listener ad un evento di una specifica sorgente, componente la GUI
- 
Eventi In JavaOggetti derivati dalla classeEventObject- eventi semantici
- su componenti virtuali dell’interfaccia
 
- eventi low-level
- eventi fisici relativi al mouse o tastiera
 
 Sono gestiti con un meccanismo di delega - la sorgente, generato un evento, passa un oggetto che descrive l’evento ad un listener
- registrato presso la sorgente
- il passaggio dell’evento cousa l’invocazione di un metodo del listener
 
 
- eventi semantici
- 
Sorgenti I diversi componenti dell’interfaccia - JButton
- JTextField
- Component
- Window
 
- 
Listener O event-handler, istanza di una classe che contiene metodi per gestire gli eventi Per ogni tipo di evento é definita una interfaccia che il listener deve implementare - ActionListener- void addActionListener(ActionListener I)
 
- MouseListener
- MouseMotionListener
- WindowListener
 Per non dover implementare tutti i metodi dell’interfaccia che ci interessa sono state introdotte le classi filtro - 
implementazioni di default delle interfacce dei listener - metodi che non fanno nulla
- si fa overriding solamente dei metodi di gestione che ci servono
 
- 
WindowListener→WindowAdapter
 
Organizzazione e uso GUI
Model View Controller
MVC
- Model
- memorizza e recupera i dati
- mantiene lo stato dell’applicazione
 
- View
- gestisce l’interfaccia
- visualizza i dati del Model
- gestisce l’interazione con l’utente
 
- Controller
- interpreta l’input dell’utente
- istruisce il Model in base all’input
 
Separa le implementazioni, in questo modo sono indipendenti e facilmente sostituibili
- solitamente il legame principale é tra controller e modello e controller e view
- il legame diretto tra modello e vista é contemplato solo in situazioni piú semplici
- il refresh della vista é automatizzato dal modello Observer-Observable- al cambiamento il model segnala il cambiamento agli osservatori
 
 
- il refresh della vista é automatizzato dal modello 
JavaFX
Il successore di SWING
- separa il contenuto dalla sua visualizzazione tramite stylesheet CSS
- permette il binding di property dei Model con elementi dell’interfaccia utente aggiornando automaticamente le viste
- offre classi/interface che implementano Observer Observable
- permette anche di scrivere interfacce in XML
- 
Componenti - Stage
- finestra
 
- Scene
- una principale
 
- Panels
- Buttons
 
- Stage
- Scene Builder
Programmazione Multithread
Stesso processo - Esecuzione concorrente di istruzioni Piú leggeri rispetto ai processi concorrenti
- in JFrameviene attivato un thread di interfaccia utente- contiene tutti i listener dell’interfaccia
 
Si utilizzano classi in estensione a Thread
- si creano in memoria con la new
- si lanciano in parallelo il metodo run()con il metodostart()
- si puó inserire lo start()all’interno del costruttore
Questo ha il problema dell’ereditarietá singola.
Per separare logicamente Thread (esecutore) e ció che va eseguito esiste l’interfaccia Runnable
- contengono il metodo run()
- eseguibile con new Thread(Runnable r)
I Thread possono eseguire il metodo join(Thread t) per aspettare che t abbia terminato run() per continuare la propria esecuzione
Deamon
Un Thread puó essere dichiarato come Deamon
- utilizzato per servizi
In particolare termina solo quando tutti i Thread parenti terminano
Sincronizzazione
Necessaria su oggetti con accesso condiviso
- in particolare quando le operazioni eseguite non sono atomiche
Le sezione critiche possono essere gestite con:
- Semaphore(int n)- acquire()
- release()
 
In Java peró ogni Object é dotato di lock
- ogni istanza possiede un semaforo binario lock
- questo é utilizzato con la dichiarazione del metodo synchronized
- il locké sulla singola instanza dell’oggetto, quindi la sincronizzazione avviene su piú esecuzioni di metodosynchronizeddello stesso oggetto
- sincronizzazione server side
- i client chiamano senza preoccuparsi, della sincronizzazione se ne occupa il server
 
Anche l’oggetto Class relativo ha un lock
- relativo a tutto ció che statico
Per dichiarare sezioni critiche solamente sezioni di metodi si utilizza il metodo:
- synchronized(Object o)
Per i puntatori o contatori esiste AtomicInteger
- 
Thread I Threadpossono attendere lo stato giusto della risorsa con il metodo:- wait()- sbloccati attraverso notifica
- notifyAll()
- notify()- risvegli il primo della coda di wait
 
- risvegli il primo della coda di 
 
 Le due situazioni che si possono creare con un utilizzo errato della sincronizzazione: - deadlock
- starvation
 Tra Threadla comunicazione puó essere gestita facilmente con lePipe
- 
BlockingQueue Interfaccia generica 
- 
Lock e Condition Ogni oggetto ha un lock implicito. Per usare lock espliciti si utilizza l’interfaccia LockImplementata ad esempio inReentrantLock- newCondition()- restituisce un oggetto di tipo Condition- await()
- signal()
- signalAll()
 
 
- restituisce un oggetto di tipo 
 ReadWriteLock- Lock readLock()
- Lock writeLock()
 
Pool
Thread Pool
Si creano un numero di Thread in un colpo solo a cui sono poi assegnati man mano i compiti da eseguire.
- sono dotati di coda in cui sono inserite le task man mano
- il Poolsi auto gestisce le code bilanciandole
- 
Executor ExecutorInterface- ExecutorService newFixedThreadPool(int n)
- ScheduleExecutorService newScheduledThreadPool(int n)
- ScheduleAtFixedRate
 shutdown()
Runnable
Task che corrisponde a un metodo con ritorno void
Callable<T>
Task che é parametrizzato con T generico
- public T call()
- 
Future<T> Futuretask(Callabre<T> task)- isDone()
- get()- sospende in caso non abbia ancora terminato la computazione
 
 
Programmazione in Rete
Architettura Client-Server
Socket
Pipe per applicativi su macchine diverse
- l’unica differenza e' la connessione remota
Il package Java che permettono l’uso di queste funzionalita' e' java.net
import java.net;
try {
    String ip = "time-c.nist.gov";
    int port = 14;
    Socket s = new Socket(ip, port);
} catch (IOException e) {
    e.pringStackTrace();
} finally {
    s.close();
}
Server Socket
Con l’uso di accept() ci si mette in attesa di una richiesta di connessione da un socket client
try {
   ServerSocket server = new ServerSocket(port);
   Socket client = s.accept();
   try {
       InputStream in = client.getInputStream();
       OutputStream out = client.getOutputStream();
   } catch (IOException e) {
       e.pringStackTrace();
   }
} catch (IOException e){
    e.pringStackTrace();
} finally {
    try {
        client.close();
        server.close();
    } catch (IOException e) {
        e.pringStackTrace();
    }
}
Per servire piu' client:
while (true){
    Socket incoming = s.accept();
    Runnable r = new ThreadedEchoHandler(incoming);
    Thread t = new Thread(r);
    t.start();
}
Polimorfismo
Il polimorfismo viene mantenuto ma il client deve disporre delle definizioni necessarie
Questo tipo di operazione crea problemi di sicurezza e Loader
- se si utilizzano classi definite da noi
- ma queste classi non sono controllate
- se le classi devono essere scaricate da rete dinamicamente esiste
- Security Manager- specificati permessi
- IPspecifici
- tipo di connessioni
 
- permette l’uso di class loaderdinamico
 
- specificati permessi
 
Polimorfismo
Esecuzione Distribuita
Laboratorio
MVC
- <~/Uni/III/ProgIII/L/MVC/org/prog3/lab/week6/es1/es1_svolto/Exercise1.java>
- <~/Uni/III/ProgIII/L/MVC/org/prog3/lab/week6/es2/ProverbsApp.java>
Progetto
- Server
- ha una interfaccia grafica con il log delle operazioni client-server
 
- Modello
- mail
- account
- ben formata
 
- lista di messaggi - inbox
- eventualmente vuota se non ha messaggi
- List di Classe EMail- ID
- mittente
- destinatario / destinatari
- soggetto
- testo
- data
- …
 
 
 
- account
 
- mail
- Client
- associato ad un account
- Intefaccia grafica
- creazione / invio mail
- lettura messaggi inbox
- rispondere a un messaggio
- forward di un messaggi
- rimozione messaggi
- aggiornata
- notifica nuovi messaggi
 
 
- lo stato dell’Inbox mantenuto lato server
- attendere riscontro docenti
 
- il client dovrebbe funzionare anche se ci sono problemi di connessione con il server
- avvertendo il client
 
 
- Multithreading
- se una operazione puó essere parallelizzata allora deve esserlo
 
- Properties / Java Beans- per l’implementazione della View
- consigliato
 
- per l’implementazione della