Concretamente l'approccio ha il solo scopo di mostrare trait, classi e interazioni tra queste due.
La forma usata ha tuttavia un suo senso.
Come hai notato, il fatto di avere il magazzino che esegue delle operazioni porta a includere nel magazzino i metodi che poi usano le operazioni. Che senso ha? Nessuno, a meno che le operazioni non inizino a diventare un po' più numerose e sostanziose. A quel punto entra in gioco la composizione nel senso che capita che quelle tante e grosse operazioni non siano altro che la combinazione di operazioni più piccole. Le operazioni più piccole sono definite come metodi dell'operando Magazzino, le combinazioni sono contenute negli operatori-funzione. Così ti ritrovi ad avere un magazzino con un contratto relativamente costante a fronte di un numero variabile di possibili interazioni (il principio open-closed).
Ad esempio, supponiamo di avere uno scarico ammissibile solo se lo stock non vada in negativo. Non è necessario cambiare la definizione di magazzino per ottenerlo, basta combinare i suoi metodi quantità e rimuovi:
Codice:
class ScaricoNonNegativo(val prodotto: Prodotto, val quantità: BigDecimal) {
def apply(m: Magazzino) = {
val stock = m.quantità(prodotto)
if(stock.isEmpty) {
System.out.println("Prodotto non immagazzinato")
} else {
val v = stock.get
if((v - quantità).signum < 0) {
System.out.println("Impossibile rimuovere la quantità richiesta (quantità disponibile " + v + ")")
} else {
m.rimuovi(prodotto, quantità)
}
}
}
}