the billion dollar mistake

42
THE BILLION DOLLAR MISTAKE

Upload: alvaro-garcia-loaisa

Post on 14-Apr-2017

198 views

Category:

Software


0 download

TRANSCRIPT

Page 1: The billion dollar mistake

T H E B I L L I O N D O L L A R M I S TA K E

Page 2: The billion dollar mistake

Quien soyaloa i sa

Page 3: The billion dollar mistake

• Más decepcionante que los Generics de Java

• Peor que la barra invertida de Windows \

• Más problemático que la comparación en JS ===

• Más común que PHP

• Más lamentable que UTF-16

• Más escandaloso que MongoDB

• Más confuso que el Pre-Compilador de C •El peor error se produjo en 1965!!

Page 4: The billion dollar mistake
Page 5: The billion dollar mistake

No eres un verdadero programador

hasta que no has tenido un NullPointerException

Page 6: The billion dollar mistake

Tony Hoare

“ It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. ”

“I call it my billion-dollar mistake”

Page 7: The billion dollar mistake

Que pasa con los nulls?

Page 8: The billion dollar mistake

Que pasa con los nulls?

• NullPointerException es de lejos la excepción más común en Java

• Empeora la legibilidad llenando todo con chequeos de nulls

• Rompe la filosofía Java de ocultar a los desarrolladores los punteros.

• Es un agujero en el Sistema de Tipos

• No tiene un sentido semántico en particular.

• Es un mal modelo para representar la ausencia de valor para un lenguaje estáticamente tipado.

Page 9: The billion dollar mistake

“La ausencia de señal, nunca debe ser usada como señal”

J. Bigalow 1947

Page 10: The billion dollar mistake

null != Ausencia de valor

Page 11: The billion dollar mistake

Problema típico en POO

Page 12: The billion dollar mistake

Problema típico en POO

• Muchos ordenadores no tienen Soundcard. ¿Que devolvemos entonces?

• Comúnmente y como mala práctica, se suele usar null para indicar la ausencia de SoundCard

• Con lo que el resultado será un NullPointerException en tiempo de ejecución y el programa se parará.

Page 13: The billion dollar mistake
Page 14: The billion dollar mistake

¿Como se ha resuelto en otros lenguajes ??

• Lenguajes como C# o Groovy tienen el “Safe navigation operator” ?.

• A la variable version se le asignará null si computer es null, getSoundCard() devuelve null o getUSB() devuelve null.

• No es necesario escribir código complejo para chequear los null

Page 15: The billion dollar mistake

Groovy - Elvis Operator ?:

• Es usado en casos simples cuando la variable necesita un valor por defecto

• En el caso que .getVersion() nos devolviera null podríamos devolver un valor por defecto de esta forma:

Page 16: The billion dollar mistake

Otros puntos de vista• Haskell: Incluye el tipo Maybe

• Maybe puede contener un valor de un tipo dado o nada, ya que no existe el concepto de nulo

• En esencia encapsula a un Optional

• Scala: Similar con Option[T]• Encapsula la presencia o la ausencia de un valor de un tipo T

• Tenemos que chequear si el valor está presente, lo cual es similar a el chequeo de nulos.

• Fuerza al programador a controlarlo a través del sistema de tipos

Page 17: The billion dollar mistake

Y en Java ??• Solución 1: (Guarrada)

• Desagradable a la vista

• Debemos chequear todos los valores para evitar que nos pase

• Todos estos checks están en medio de la lógica

• Disminuye la legibilidad del programa

Page 18: The billion dollar mistake

Y en Java ??• Solución 2:

Podemos utilizar notaciones para restringir los contratos:

@NotNull y @Nullable (Java 8 > No estandars)

• @Nullable nos recuerda la necesidad de introducir un chequeo de null cuando llamamos a métodos que pueden devolver nulos.

• @NotNull nos establece un contrato por el que el método no puede devolver null - Y sus parámetros no pueden ser pasados como null

Page 19: The billion dollar mistake

Y en Java ??• Solución 3:

Patrón NullObject

• Añade complejidad

• Hay que crear bastantes NullObjects dependiendo de la arquitectura

Page 20: The billion dollar mistake

Y en Java ??• Solución 4: (Otra guarrada)

Devolver Null

• Mala práctica

• Fuente de NullPointerExceptions

• No estamos pensando en el caso de que sea vacío

Page 21: The billion dollar mistake
Page 22: The billion dollar mistake

Que pasa en Java 8 ??• java.util.Optional<T>

• - Inspirado en la idea antes vista de Haskell y Scala

• - Es una clase que encapsula un valor opcional

Page 23: The billion dollar mistake

Optional• Un Optional puede ser visto como un contenedor de un solo

valor que puede contener un valor o no.

Page 24: The billion dollar mistake

Optional

• Computer puede tener o no soundCard

• SoundCard puede tener o no puerto USB

Page 25: The billion dollar mistake

Optional

• Este nuevo modelo refleja si un valor dado puede estar ausente

• Establece la intención del API

• Optional no es para reemplazar cada referencia nula

• Es para ayudarnos a hacer un diseño más comprensible

• Con la firma del método podemos saber si es un valor opcional

• Te obliga a hacer frente a la posible ausencia de valor

Page 26: The billion dollar mistake

Y ahora qué ??

Page 27: The billion dollar mistake

Creando Optionals

• Si soundCard fuera null se lanzaría un NullPointerException

• Si soundcard fuera null el resultado del Optional sería empty

Page 28: The billion dollar mistake

.ifPresent()• Ejecuta algo si el Opcional contiene algún valor

Antes:

Ahora:

Page 29: The billion dollar mistake

.isPresent()

• Devuelve true o false dependiendo si contiene o no valor

• Podemos usarlos de esta forma para evitar excepciones

• Este no es el mejor uso, ya que no es mucho mejor al chequeo de nulos

Page 30: The billion dollar mistake

.get()

• Nos devuelve el valor contenido en el Optional

• Si no hay valor almacenado, dará un NoSuchElementException

• Podemos usarlos de esta forma para evitar excepciones

• Este no es el mejor uso, ya que no es mucho mejor al chequeo de nulos

Page 31: The billion dollar mistake

.orElse()Patrón típico:

• Usando un objeto Optional podemos escribir este código usando orElse()

• Este método provee un valor por defecto si el Optional está vacío.

Page 32: The billion dollar mistake

.orElseGet()

• orElse() ejecuta siempre el contenido y lo devuelve si es el caso, a no ser que sea un lambda

• orElseGet() solo ejecuta el código si le toca actuar

• Puede dar un NullPointerException si lo que ejecuta devuelve null

Page 33: The billion dollar mistake

.orElseThrow()

- Lanza la excepción que le digamos si el Optional está vacío.

Page 34: The billion dollar mistake

.filter()

•El método filter() coge el valor como argumento

•Si el valor está presente en el Optional y la comprobación es true, el método filter() devuelve el propio Optional

•Si el valor es vacío, devuelve un objeto Optional vacío

Antes:

Ahora:

Page 35: The billion dollar mistake

.map()

• El valor dentro del Optional es pasado como argumento al método getUSB()

• Mientras que no pasa nada si está vacío

Antes:

Ahora:

Page 36: The billion dollar mistake

.flatMap()

• getUSB() devuelve un objeto de tipo Optional<USB> • Esto significa que el resultado de la primera operación map es un

objeto de tipo Optional<Optional<USB>>

• Como resultado, la llamada a getVersion() es inválida

Antes:

Ahora:

Page 37: The billion dollar mistake

.flatMap()• El propósito es aplicar el método de transformación sobre el valor del Optional y

"aplanar" el resultado de dos niveles de Optional en uno solo.

Page 38: The billion dollar mistake

.flatMap()

• flatMap se utiliza para métodos que devuelven Optionals

• flatMap devuelve un Optional<USB> en lugar de un Optional<Optional<USB>>

• Podemos llamar a map() ya que getVersion() devuelve un String en vez de un objeto Optional

Antes:

Ahora:

Page 39: The billion dollar mistake
Page 40: The billion dollar mistake

• El propósito de Optional NO es reemplazar cada referencia nula en el código

• El propósito de Opcional es el poder diseñar mejores APIs

• Nos fuerza a extraer su valor y gestionarlo en el caso de su ausencia

• Nos protege de nullPointerExceptions

• Simplifica el código

• Un nullPointerException en producción puede hacerte perder mucha pasta!!

Conclusiones:

Page 41: The billion dollar mistake

Recurso shttp://www.oracle.com/technetwork/articles/

java/java8-optional-2175753.html

http://es.slideshare.net/Stephan.Schmidt/better-

strategies-for-null-handling-in-java

http://es.slideshare.net/Yokomark/17-50372457

http://www.slideshare.net/mariofusco/monadic-java

https://www.jetbrains.com/help/idea/15.0/

nullable-and-notnull-annotations.html

https://www.lucidchart.com/techblog/2015/08/31/

the-worst-mistake-of-computer-science/

Page 42: The billion dollar mistake