Estratto del documento

Java attributi

Final, Static e Interface

Final: Fa diventare l'attributo immutabile. Per i metodi, blocca l'ereditarietà (non possono essere ereditati).

Static: Fa diventare l'attributo condiviso tra le varie istanze della classe.

Interface: Sono metodi astratti, non posso istanziarla.

Binding classi e gerarchie

Classi statiche e dinamiche

Padre x = new Figlio(); OK!
Figlio x = new Padre(); NO!

Overriding e overloading

Overriding: Sovrascrive una funzione.

Overloading: Cambio tipi parametri (parametro = classe Figlio).

Binding dinamico

Nel binding dinamico vengono considerati i tipi dinamici di chiamante e parametri.

Estendibilità e principio di Liskov

L'estendibilità tramite ereditarietà

È garantita solo se possiamo sostituire oggetti della sottoclasse a quelli della classe padre.

Principio di sostituzione di Liskov

Gli oggetti della sottoclasse devono rispettare il contratto della sovraclasse, ma il contratto può essere esteso per coprire ulteriori casi.

Regole

  • Regola della segnatura: Un sottotipo deve avere tutti i metodi del sovratipo e segnature compatibili.
  • Regola dei metodi: Le chiamate ai metodi del sottotipo devono comportarsi in modo compatibile a quelle del sovratipo.
  • Regola delle proprietà: Il sottotipo deve preservare tutti i public invarianti.

Testing

Coverage

  • Statements: Tutte le istruzioni.
  • Edge Coverage: Tutti i rami.
  • Path Coverage: Tutti i rami con ogni combinazione logica e tutte le possibili combinazioni di percorsi.

Sono tagliate le condizioni: (False || Ex), (True && Faux) → Ex ritorna ignorato.
Anche le condizioni d'uscita dei cicli sono decisioni.

Collezioni in Java

Dichiarazione e metodi

List <Tipo> Nome = new ArrayList<Tipo>();

Metodo Descrizione
public boolean add(Object element) Inserisce un elemento nella collezione.
Object get(int index) Ritorna l'elemento alla posizione specificata nella collezione.
public boolean addAll(Collection c) Inserisce gli elementi della collezione specificata nella collezione invocante.
public boolean remove(Object element) Elimina un elemento dalla collezione.
public int size() Ritorna il numero totale di elementi nella collezione.
public void clear() Rimuove tutti gli elementi dalla collezione.
public boolean contains(Object element) Cerca un elemento nella collezione.
public boolean containsAll(Collection c) Cerca la collezione specificata nella collezione.
public Iterator iterator() Ritorna un iteratore.
public boolean isEmpty() Controlla se la collezione è vuota.
public boolean equals(Object element) Confronta due collezioni.

Metodi di ArrayList

  • indexOf(value): Ritorna il primo indice dove il valore dato è trovato nella lista (-1 se non trovato).
  • toString(): Ritorna una rappresentazione in stringa della lista, ad esempio "[3, 42, -7, 15]".

Programmazione funzionale

Sintassi e metodi

Obj. method(Type Par1, Type Par2) → { funzione }

Posso trasformare la collection in uno stream con collection.stream()

Funzioni native

  • forEach(x → fcn) → Esegue fcn per ogni valore dello stream
  • filter(x → condi) → Filtra lasciando nello stream solo gli elementi che rendono vera x
  • map(x → x.*.2etc) → Trasforma i dati dello stream
  • distinct() → Elimina i duplicati
  • sorted() → Ordina
  • reduce(x → acc+o, fcmb(a,b)) → Unisce gli stream risultanti
  • collect(collection.total(x)) → Trasforma lo stream in una collection

Operazioni meno comuni

Operazione Method Signature Tipo di Operazione Descrizione
filter() Stream<T> filter(Predicate<T> predicate) Intermedia Ritorna uno stream di elementi che soddisfano il predicato dato.
map() Stream<R> map(Function<T, R> mapper) Intermedia Ritorna uno stream con risultati dopo aver applicato la funzione data agli elementi dello stream.
distinct() Stream<T> distinct() Intermedia Ritorna uno stream di elementi unici.
sorted() Stream<T> sorted() Intermedia Ordina gli elementi secondo l'ordine naturale.
limit() Stream<T> limit(long maxSize) Intermedia Ritorna uno stream contenente i primi n elementi.
skip() Stream<T> skip(long n) Intermedia Ritorna uno stream dopo aver saltato i primi n elementi.
forEach() void forEach(Consumer<T> action) Terminale Performa un'azione su tutti gli elementi dello stream.
toArray() Object[] toArray() Terminale Ritorna un array contenente gli elementi dello stream.
reduce() T reduce(T identity, BinaryOperator<T> accumulator) Terminale Performa un'operazione di riduzione sugli elementi dello stream usando un valore iniziale e un'operazione binaria.
collect() R collect(Collector<T, ?, R> collector) Terminale Ritorna un contenitore di risultato mutabile come List o Set.
min() Optional<T> min(Comparator<T> comparator) Terminale Ritorna l'elemento minimo in uno stream avvolto in un oggetto Optional.
max() Optional<T> max(Comparator<T> comparator) Terminale Ritorna l'elemento massimo in uno stream avvolto in un oggetto Optional.
count() long count() Terminale Ritorna il numero di elementi in uno stream.
anyMatch() boolean anyMatch(Predicate<T> predicate) Terminale Ritorna true se almeno un elemento dello stream corrisponde al predicato dato.
allMatch() boolean allMatch(Predicate<T> predicate) Terminale Ritorna true se tutti gli elementi dello stream corrispondono al predicato dato.
noneMatch() boolean noneMatch(Predicate<T> predicate) Terminale Ritorna true solo se tutti gli elementi dello stream non corrispondono al predicato dato.
findFirst() Optional<T> findFirst() Terminale Ritorna il primo elemento di uno stream avvolto in un oggetto Optional.
findAny() Optional<T> findAny() Terminale Ritorna casualmente un elemento di uno stream.

Optional

Permette di operare su dati ignorando il fatto che alcuni dati possano essere assenti (NULL).

Creazione

public class Persona {
    private String nome;
    private Optional<String> indirizzo;
    
    public Persona(String nome, String indirizzo) {
        this.nome = nome;
        this.indirizzo = Optional.ofNullable(indirizzo);
    }

    public Persona(String nome) {
        this.nome = nome;
        this.indirizzo = Optional.empty();
    }

    public String getNome() {
        return nome;
    }

    public Optional<String> getIndirizzo() {
        return indirizzo;
    }
}
  • Optional.of(val) = crea un optional con quel valore
  • Optional.empty() = crea un optional vuoto

Utilizzo

Optional<Persona> o = ...
String commenti = o
    .flatMap(p -> p.getIndirizzo())
    .flatMap(i -> i.getCommenti())
    .orElse("no comment");
  1. o.get() (sconsigliato)
  2. o.ifPresent(fun) = esegue una funzione su <T> se dati presenti, la esegue
  3. o.flatMap(m -> Optional<T>) = esegue una funzione da <T> -> Optional<T>
  4. o.orElse(val) = restituisce T/val se esiste

Programmazione concorrente

Creazione e gestione di thread

Come far partire un Thread

Timer timer = new Timer(…);
Thread t = new Thread(timer);
t.start();
public class Timer implements Runnable {
    @Override
    public void run() {
    }
}

Main class

Nel main devo dichiarare un oggetto thread e inizializzarlo dandogli come parametro la classe apposita.
La classe deve implementare la classe runnable e fare l'override del metodo run.

Programmazione funzionale

Runnable r = () -> doSomething();
t = new Thread(r);
t.start();

— Oppure —

Thread t = new Thread( () -> doSomething() );
t.start();

Viene creata una nuova classe che implementa runnable e implementa il metodo run con il metodo "doSomething".

Wait e notify

public void addAccount(String clientName) {
    synchronized(accName) {
        accName.add(clientName);
        if(accName.contains(clientName))
            accName.add(clientName);
            accBalance.add(0.0);
    }
    accName.notifyAll();
}

public double getBalance(String clientName) {
    synchronized(accName) {
        while(!accName.contains(clientName))
            try { accName.wait(); }
            catch(InterruptedException ex) { ex.printStackTrace(); }
        int pos = accName.indexOf(clientName);
        return accBalance.get(pos);
    }
}
  • Uso synchronized per eliminare gli accessi concorrenti.
  • Posso mettere in pausa un Thread con wait() (con try-catch), in questo modo viene rilasciato il lock.
  • I metodi in wait sono svegliati da notifyAll().
  • Posso dichiarare attributi utili: solo come lock = new Object().

In maniera asincrona

Quando l'esercizio chiede di fare qualcosa in "maniera asincrona" rispetto agli altri metodi: dobbiamo creare un nuovo Thread che sia comunque ben "sincronizzato e non causi conflitti" con gli altri Thread.

public void setAllAsync(long val) {
    new Thread() {
        public void run() {
            synchronized(data) {
                code;
                data.notifyAll();
            }
        }
    }.start();
}

JML

Invariante e astrazione

Formalizzazione di una proprietà: astrazione di una classe.

Osservatore

Sono metodi puri che restituiscono informazioni sullo stato. Posso avere JML solo su metodi attributi pubblici e puri.

Indicatori

  • Requires: Pre-condizione
  • Ensures: Post-condizione
  • Signals (Exc): Eccezioni Bc condizione Eccezionale
  • Also: Specifica sotto metodo
  • forall: (forall type x; range; condizione)
  • Exist: (Exist type x; condizione;)
  • Result: \Result indica il valore di ritorno del metodo
  • Old: \Old (old) mem lo stato dell'istanza prima del metodo
  • Contains: reso x ∈ Struttura
  • num_of: (Num_of int i; P(i, a[i]) n° di i che rendono vera Pi0 ≤ a[i]0

I metodi

"Puri" non modificano lo stato.
Ricade di esplicitare che lo stato non cambia quando serve.

Tips

  • Devo mettere le condizioni negli ENSURES che escludono i SIGNAL
  • I SIGNAL non escludono i REQUIRES

UML

Tipi di diagrammi

  • Struttura: Diagrammi di classi e oggetti
  • Comportamento: Diagrammi dei casi d'uso
  • Interazione: Diagrammi di sequenza

Diagramma di classi

Classi

Attributi → [visibilità] [nome] : [tipo]
Metodi → [visibilità] [nome (lista parametri)] : [tipo restituito]
[visibilità]: + = public, - = private, # = protected, ~ = friendly

Associazioni

Indicano una relazione tra le classi. Nell'implementazione delle classi viene aggiunto un numero di istanze della classe in relazione con quella da implementare.

Aggregazioni

Forma particolare di associazione. Una parte è in relazione con l'oggetto. Tutte le parti esistono "singolarmente".

Composizioni

Aggregazione forte. Le parti componenti non esistono senza il contenitore. In JAVA Aggregazione ≠ Composizione.

Ereditarietà

Padre <|-- Figlio. Viene implementata con "class Figlio extends Padre".

Interfaccia

Non posso istanziare un'interfaccia.

Dipendenze

La classe persona ha bisogno della classe libro per funzionare. Lo indico in questo modo.

Diagramma d'interazione

Descrivono il comportamento dinamico di un gruppo di "oggetti" che interagiscono per risolvere il problema.

Tipi di messaggi

  • Sincrono -->
  • Asincrono ->
  • Risposta - - >(metodi) Termine L.imoTerminizazione oggetto

Pattern

Tipi di pattern

  • Creazionali: riguardano il processo di creazione di oggetti.
  • Strutturali: riguardano composizione di classi e oggetti.
  • Comportamentali: riguardano interazioni tra oggetti e si distribuiscono responsabilità.

Factory Method

Serve per disaccoppiare il codice che fa uso di un tipo da quello che ne implementa il costruttore.

  1. L'interfaccia che viene chiamata per costruire il prodotto esatto.
  2. La classe factory, che decide quale costruttore usare.
  3. I costruttori reali.

Singleton

Viene usato quando si vuole una sola istanza (quindi non si vuole rendere pubblico il costruttore). Un metodo statico dà accesso alla sola istanza.

Adapter

Serve per far interagire 2 diversi sistemi. Viene creata una classe che converte le chiamate ai metodi dell'altra classe.

Proxy

Postpone e estrai la istanziazione di oggetti “pesanti”. Si interpone il proxy tra chiamante e chiamato con la stessa interfaccia dell'oggetto pesante. Il proxy può fare preprocessing o rendere le chiamate più facili.

Observer

Più oggetti si mettono in “ascolto” e vengono informati nel caso il Subject cambia stato.

Anteprima
Vedrai una selezione di 3 pagine su 10
Appunti Ingegneria del software Pag. 1 Appunti Ingegneria del software Pag. 2
Anteprima di 3 pagg. su 10.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 6
1 su 10
D/illustrazione/soddisfatti o rimborsati
Acquista con carta o PayPal
Scarica i documenti tutte le volte che vuoi
Dettagli
SSD
Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Joseph22ITA di informazioni apprese con la frequenza delle lezioni di Ingegneria del software e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Politecnico di Milano o del prof Margherita Alessandro.
Appunti correlati Invia appunti e guadagna

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community