Ciao, On Sat, May 16, 2020 at 11:54 AM Francesco Vasco [email protected] [it-torino-java-jug] <[email protected]> wrote: > Durante l'ultimo interessante incontro di Simone, si è affrontato il tema > delle interfacce delle collection con metodi opzionali (qualsiasi cosa questo > voglia dire in OO).
Opzionali nel senso che ci sono, ma poi vengono implementati con "throw new UnsupportedOperationException()". > Il punto che vorrei approfondire è che questa scelta avrebbe semplificato, > altrimenti ci sarebbero state 500 classi (vado a memoria). > Sono curiosi di questa affermazione, poiché mi sembra una esagerazione, Scala > ha una sua implementazione con questa differenziazione, Kotlin differenzia le > interfacce e condivide l'implementazione con Java. Avevo premesso che stavo dicendo numeri a caso (ho menzionato il passaggio da 50 a 500 per enfatizzare il discorso). I numeri più precisi e la discussione sul design si trovano qui: https://docs.oracle.com/javase/8/docs/technotes/guides/collections/designfaq.html Il discorso era che è molto difficile fare un design perfetto per qualcosa usato in modo molto generico e quindi con un sacco di use cases. Si devono accettare dei compromessi. Nelle Java collections hanno accettato i metodi che lanciano UnsupportedOperationException che se guardate su qualsiasi libro di teoria OO vengono descritti come un abominio. E lo hanno fatto per ridurre al minimo il numero di interfacce da "spiegare" ad uno sviluppatore. "When all was said and done, we felt that it was a sound engineering compromise to sidestep the whole issue by providing a very small set of core interfaces that can throw a runtime exception." Ora, non è che mi trovi molto d'accordo. Penso che la soluzione di Kotlin sia un compromesso migliore anche se non è perfetto neanche quello. Per fare un esempio, sia Java che Kotlin hanno List.listIterator(int) che è ovviamente inutilizzabile in ambiente concorrente (l'indice che viene passato come argomento può non essere più valido quando viene chiamato listIterator(int)). Quindi, abbiamo una astrazione abbastanza generica come List che non può essere usata per implementare una List concorrente. L'implementazione può "provare" e sperare che l'indice sia buono - ma rischio di avere non l'elemento che voglio oppure lancio ArrayIndexOutOfBoundsException, oppure lascio stare e lancio UnsupportedOperationException. E allora, vogliamo aggiungere anche le interfacce "NonConcurrent"? Il discorso che facevamo era proprio sui compromessi. -- Simone Bordet --- Finally, no matter how good the architecture and design are, to deliver bug-free software with optimal performance and reliability, the implementation technique must be flawless. Victoria Livschitz
