Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
Alonso Torres @alotor
Design Patterns
“
”
Cada patrón describe un problema recurrente en nuestro
entorno, así como la solución a ese problema, de tal modo que s...
Los patrones definen:
soluciones a problemas frecuentes
¿
?
Son las soluciones con Java 8 las
mismas que con versiones anteriores
λ
Alonso Torres
@alotor
mobro.co/alotor
El camino hacia
1996
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
1994
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
1998 - J2SE 1.2
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
Adopción masiva del
lenguaje
2004 - J2SE 5.0
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
Genéricos
Anotaciones
Enumerados
Nueva sintaxis
Concu...
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
2011 - Java SE 7
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
InvokeDynamic
NIO 2
Nueva concurrencia
2014 - Java SE 8
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
Java 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Java 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Las lambdas son lo mejor que le ha
pasado a Java desde….
Las lambdas son lo mejor que le ha
pasado a Java.
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
C#
1990 1995 2000 2005 2010 2015
1.0 1.2 1.4 5 6 7 81.3
ActionScript Groovy Perl
C# Haskell PHP
C++ JavaScript Python
Clojure Lisp R
Curl Logtalk Racket
D Lua Ruby
Dart Mathemati...
Fortran
C
Ada
Cobol
Fortran 1957
C 1969
Ada 1977
Cobol 1989
15%
20%
Features
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Lambdas: funciones anónimas
public Integer addition(Integer x, Integer y) {
return x + y;
}
public void sayHello(String name) {
System.out.println("He...
public Integer addition(Integer x, Integer y) {
return x + y;
}
public void sayHello(String name) {
System.out.println("He...
(Integer x, Integer y) -> {
return x + y;
};
(String name) -> {
System.out.println("Hello" + name);
};
() -> {
return 3.15...
(Integer x, Integer y) -> x + y;
(String name) -> {
System.out.println("Hello" + name);
};
() -> 3.15f
(Integer x, Integer y) -> x + y;
(String name) -> {
System.out.println("Hello" + name);
};
() -> 3.15f
PARÁMETROS CUERPO
(parameters) -> body;
(Integer x, Integer y) -> x + y;
(String name) -> System.out.println("Hello" + name);
() -> 3.15f
Thread th = new Thread(new Runnable(){
@Override
public void run() {
System.out.println(">> Another thread"));
}
});
th.st...
Thread th = new Thread(() ->
System.out.println(">> Another thread"));
th.start();
Creando hilos
Me váis a llamar loco
pero…
…en ocasiones veo
patrones
Thread th = new Thread(() ->
System.out.println(">> Another thread"));
th.start();
Creando hilos
Client Invoker
Receiver
+action()
ConcreteCommand
+execute()
Command
+execute()
Command
PATRÓN
new Invoker().addCommand(new Command() {
@Override
public void execute() {
receiver.action();
}
});
new Transaction().doWithTransaction(new Command() {
@Override
public void execute() {
myBusinessLogic.calculateInterests()...
new Context().doAsync(new Command() {
@Override
public void execute() {
networkManager.downloadFile();
}
});
Client Invoker
Receiver
+action()
ConcreteCommand
+execute()
Command
+execute()
Client Invoker
Receiver
+action()
ConcreteCommand
+execute()
Command
+execute()
Lambda
new Invoker().addCommand(new Command() {
@Override
public void execute() {
receiver.action();
}
});
new Invoker().addCommand(new Command() {
@Override
public void execute() {
receiver.action();
}
});
new Invoker().addCommand(
() -> receiver.action();
);
surely,
we
can
do
better
new Invoker().addCommand(
receiver::action
);
Method Reference
Method Reference:
Transformar un método en una
lambda
() -> receiver.action()
(el) -> el.toString()
() -> Runtime.getInstance()
() -> new Receiver()
() -> receiver.action()
(el) -> el.toString()
() -> Runtime.getInstance()
() -> new Receiver()
() -> receiver.action() receiver::action
(el) -> el.toString() Object::toString
() -> Runtime.getInstance() Runtime::getIn...
Instance method reference
(objeto concreto)
Instance method reference
(cualquier objeto)
Static method reference
Construct...
(Integer x, Integer y) ->
receiver.action(x, y)
(Integer x, Integer y) ->
Math.max(x, y)
(String str) ->
new String(str)
(Integer x, Integer y) ->
receiver.action(x, y)
receiver::action
(Integer x, Integer y) ->
Math.max(x, y)
Math::max
(Strin...
new Transaction().doWithTransaction(
myBusinessLogic::calculateInterests
);
new ThreadPool().doInThread(
networkManager::d...
Client Invoker
Receiver
+action()
ConcreteCommand
+execute()
Command
+execute()
Client Invoker
Receiver
+action()
ConcreteCommand
+execute()
Command
+execute()
Client Invoker
Receiver
+action()
Command
+execute()
(Integer x, Integer y) -> x + y;
(String name) -> System.out.println("Hello" + name);
() -> 3.15f
¿Qué TIPO tienen las lam...
Object addition =
(Integer x, Integer y) -> x + y;
Object sayHello =
(String name) -> System.out.println("Hello" + name);
...
The target type of this expression must be a
functional interface
Java 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
(Integer x, Integer y) -> x + y;
(String name) -> System.out.println("Hello" + name);
() -> 3.15f
(Integer x, Integer y) -> x + y;
(String name) -> System.out.println("Hello" + name);
() -> 3.15f
Integer addition(Integer...
Functional interfaces
public interface Addition {
Integer addition(Integer x, Integer y);
}
public interface SayHello {
vo...
Functional interfaces
public interface Addition {
public Integer addition(Integer x, Integer y);
}
1 sólo método
Functional interfaces
public interface Addition {
public Integer addition(Integer x, Integer y);
}
Addition addition =
(In...
public interface Addition {
public Integer addition(Integer x, Integer y);
}
public interface Operation<T extends Number> ...
PROBLEMA
Sólo funciona con interfaces
● NO pueden ser clases
● NI clases abstractas
Java 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Default Methods
public interface Addition {
public Integer addition(Integer x, Integer y);
default Integer substraction(In...
public interface Addition {
public Integer addition(Integer x, Integer y);
}
Addition addition =
(Integer x, Integer y) ->...
Java 8
viene con las interfaces más comunes
DE SERIE
import java.util.function.*
BiConsumer<T,U> IntBinaryOperator LongUnaryOperator
BiFunction<T,U,R> IntConsumer ObjDoubleCon...
(Integer x, Integer y) -> x + y;
(String name) -> System.out.println("Hello" + name);
() -> 3.15f
¿Qué TIPO tienen?
public...
BiConsumer<T,U> IntBinaryOperator LongUnaryOperator
BiFunction<T,U,R> IntConsumer ObjDoubleConsumer<T>
BinaryOperator<T> I...
BinaryOperator<Integer> addition =
(Integer x, Integer y) -> x + y;
Consumer<String> sayHi =
(String name) -> System.out.p...
BinaryOperator<Integer> addition =
(x, y) -> x + y;
Consumer<String> sayHi =
(name) -> System.out.println("Hello" + name);...
Thread th = new Thread(() ->
System.out.println(">> Another thread"));
th.start();
java.lang.Runnable
JButton button = new JButton("Button");
button.addActionListener((event) ->
System.out.println("Mouse: " + event);
);
java...
Observer
PATRÓN
ConcreteObserverA
+notify()
ConcreteObserverB
+notify()
Observer
+notify()
ObservedClass
+registerObserver()
+unregisterOb...
@FunctionalInterface
public static interface Observer {
public void notify(Object change);
}
@FunctionalInterface
public static interface Observer {
public void notify(Object change);
}
@FunctionalInterface
public static interface Observer {
public void notify(Object change);
}
El compilador fallará si no
c...
@FunctionalInterface
public static interface Observer {
public void notify(Object change);
}
El compilador fallará si no
c...
public static class ObservedClass {
private List<Observer> observers = new LinkedList<>();
public void addObserver(Observe...
public static class ObservedClass {
private List<Observer> observers = new LinkedList<>();
public void addObserver(Observe...
public static class ObservedClass {
private List<Observer> observers = new LinkedList<>();
public void addObserver(Observe...
observed.addObserver((change) -> {
new Thread(UIThread::update).start()
});
sbj.notifyChange("Change");
Hipótesis
¿Puede haber un patrón de más alto nivel?
new Invoker().addCommand(receiver::action);
observed.addObserver(receiver::action);
Pasar comportamiento como argumentos
● El comportamiento se ejecutará en otro contexto
● “Separation of concerns”
● Tambié...
List<Person> personList = new LinkedList<>();
Collections.sort(
personList,
(p1, p2) -> p1.age - p2.age
);
java.lang.Compa...
List<Person> personList = new LinkedList<>();
Collections.sort(
personList,
(p1, p2) -> p1.age - p2.age
);
java.lang.Compa...
Strategy
PATRÓN
Collections.sort(
list,
(p1, p2) -> p1.getAge() - p2.getAge());
Collections.sort(
list,
(p1, p2) -> p1.getName().compareTo...
Reusing lambdas
class PersonSortCriterias {
public static int sortByAge(Person p1, Person p2) {
return p1.getAge() - p2.ge...
Collections.sort(
list,
PersonSortCriterias::sortByAge);
Collections.sort(
list,
PersonSortCriterias::sortByName);
Collect...
Set<Person> = new TreeSet<>(
PersonSortCriterias::sortByAge
);
Person theOlder = Collections.max(
list,
PersonSortCriteria...
Java 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Java 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Iterator
PATRÓN
for (String str : list) {
System.out.println(str);
}
for (String str : list) {
if (str.length <= 5) {
System.out.println(str);
}
}
for (String str : Collections.sort(list)) {
if (str.length <= 5) {
System.out.println(str);
}
}
for (String str : Collections.sort(list).sublist(0, 10)) {
if (str.length <= 5) {
System.out.println(str);
}
}
for (String str : Collections.sort(list).sublist(0, 10)) {
if (str.length <= 5) {
System.out.println(str.toUpperCase());
}...
Problemas
● Susceptible a errores
● Difícil de razonar
● Difícil de reutilizar
Streams
● Interfaz fluida
● Evaluación perezosa
● Iterable
● Aprovechan toda la expresividad de las
lambdas
list.stream()
.forEach(System.out::println);
list.stream()
.filter(s -> s.length <= 5)
.forEach(System.out::println);
list.stream()
.filter(s -> s.length <= 5)
.sorted()
.forEach(System.out::println);
list.stream()
.filter(s -> s.length <= 5)
.sorted()
.limit(10)
.forEach(System.out::println);
list.parallelStream()
.filter(s -> s.length <= 5)
.sorted()
.limit(10)
.forEach(System.out::println);
Funciones importantes
● Map
● Filter
● Reduce
MAP - FILTER - REDUCE
list.stream()
.map(String::toUpperCase)
"banana"
"apple"
"pear"
"pineapple"
"lemon"
"mango"
"raspber...
MAP - FILTER - REDUCE
list.stream()
.filter(s -> s.length <= 5)
"banana"
"apple"
"pear"
"pineapple"
"lemon"
"mango"
"raspb...
MAP - FILTER - REDUCE
list.stream()
.reduce("", (acc, elem) -> acc + ", " + elem);
"banana"
"apple"
"pear"
"pineapple"
"le...
Chain of
responsibility
PATRÓN
HANDLER HANDLER HANDLER HANDLER HANDLER
request
HANDLER HANDLER HANDLER HANDLER HANDLERrequest
HANDLER HANDLER HANDLER HANDLER HANDLERrequest
HANDLER HANDLER HANDLER HANDLER HANDLER
request
@FunctionalInterface
public interface Handler {
public Request handleRequest(Request req);
}
@FunctionalInterface
public interface Handler extends Function<Request, Request> {
}
List<Handler> chain = new LinkedList<>();
chain.add(Request::session);
chain.add(Request::securityCheck);
chain.add(Reques...
List<Handler> chain = new LinkedList<>();
chain.add(Request::session);
chain.add(Request::securityCheck);
chain.add(Reques...
List<Handler> chain = new LinkedList<>();
chain.add(Request::session);
chain.add(Request::securityCheck);
chain.add(Reques...
List<Handler> chain = new LinkedList<>();
chain.add(Request::session);
chain.add(Request::securityCheck);
chain.add(Reques...
HANDLER HANDLER HANDLER HANDLER HANDLER
request
HANDLER HANDLER HANDLER HANDLER HANDLER
request
CHAIN (HANDLER)
List<Handler> filters = new LinkedList<>();
filters.add(Request::session);
filters.add(Request::securityCheck);
filters.ad...
List<Handler> filters = new LinkedList<>();
filters.add(Request::session);
filters.add(Request::securityCheck);
filters.ad...
List<Handler> filters = new LinkedList<>();
filters.add(Request::session);
filters.add(Request::securityCheck);
filters.ad...
List<Handler> filters = new LinkedList<>();
filters.add(Request::session);
filters.add(Request::securityCheck);
filters.ad...
System.out.println("nProcessing request 1");
Request r1 = chain.apply(new Request());
System.out.println("nProcessing requ...
¯_(ツ)_/¯
Java SE 8
● Lambda expressions
● Functional interfaces
● Default methods
● Streams
Patrones
● Command
● Strategy
● Observer
● Iterator
● Chain of responsibility
Los patrones definen:
soluciones a problemas frecuentes
Problema
● El comportamiento y el contexto son diferentes
● Encapsular los datos
● Composición de comportamiento
Solución
...
Las lambdas son lo mejor que le ha
pasado a Java.
Sobre los hombros de gigantes
Mario Fusco Venkat Subramaniam Samir Talwar
https://youtu.be/K6BmGBzIqW0 https://vimeo.com/1...
@alotor
mobro.co/alotor
¿Preguntas?
@alotor
Referencias
● https://en.wikipedia.org/wiki/Java_version_history
● http://www.studytrails.com/java/java8/Java8_Lambdas_Fun...
Referencias
● http://j2objc.org/blog/2015/08/07/lambdas-in-java-8-dysfunctional-interfaces.html
● http://gafter.blogspot.c...
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
[Codemotion 2015] patrones de diseño con java8
Próxima SlideShare
Cargando en…5
×

[Codemotion 2015] patrones de diseño con java8

2.996 visualizaciones

Publicado el

Presentada en el Codemotion Madrid 2015.

Abstract:
Han pasado más de 20 años desde la publicación del famoso libro "Patrones de diseño" por el grupo conocido como "Gang of Four".

Durante años, estos patrones han mantenido su actualidad por ser lo suficientemente genéricos para todo tipo de software y resolver problemas comunes de diseño de las aplicaciones que desarrollamos a diario.

Pero algo ha cambiado con Java 8.

Con las nuevas características de Java 8, y en especial las lambdas, es necesario revisitar estos famosos patrones para adaptarlos a sus nuevas funcionalidades.

En esta charla repasaremos algunos de los famosos patrones viendo como adaptarlos a las nuevas características de Java. Además, podremos ver como mejorar nuestro tradicional diseño orientado a objetos gracias a las lambdas y a la programación funcional.

Publicado en: Tecnología

[Codemotion 2015] patrones de diseño con java8

  1. 1. Alonso Torres @alotor Design Patterns
  2. 2. “ ” Cada patrón describe un problema recurrente en nuestro entorno, así como la solución a ese problema, de tal modo que se pueda aplicar esta solución un millón de veces, sin hacer lo mismo dos veces. - Christopher Alexander, A Pattern Language
  3. 3. Los patrones definen: soluciones a problemas frecuentes
  4. 4. ¿ ? Son las soluciones con Java 8 las mismas que con versiones anteriores
  5. 5. λ
  6. 6. Alonso Torres @alotor mobro.co/alotor
  7. 7. El camino hacia
  8. 8. 1996
  9. 9. 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  10. 10. 1994 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  11. 11. 1998 - J2SE 1.2 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3 Adopción masiva del lenguaje
  12. 12. 2004 - J2SE 5.0 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3 Genéricos Anotaciones Enumerados Nueva sintaxis Concurrencia
  13. 13. 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  14. 14. 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  15. 15. 2011 - Java SE 7 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3 InvokeDynamic NIO 2 Nueva concurrencia
  16. 16. 2014 - Java SE 8 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  17. 17. Java 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  18. 18. Java 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  19. 19. Las lambdas son lo mejor que le ha pasado a Java desde….
  20. 20. Las lambdas son lo mejor que le ha pasado a Java.
  21. 21. 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  22. 22. C# 1990 1995 2000 2005 2010 2015 1.0 1.2 1.4 5 6 7 81.3
  23. 23. ActionScript Groovy Perl C# Haskell PHP C++ JavaScript Python Clojure Lisp R Curl Logtalk Racket D Lua Ruby Dart Mathematica Scala Dylan Maple Scheme Erlang Matlab Smalltalk Elixir Maxima Standard ML F# OCaml TypeScript Go Object Pascal Tcl Gosu Objective-C VisualBasic .NET
  24. 24. Fortran C Ada Cobol
  25. 25. Fortran 1957 C 1969 Ada 1977 Cobol 1989
  26. 26. 15% 20%
  27. 27. Features ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  28. 28. Lambdas: funciones anónimas
  29. 29. public Integer addition(Integer x, Integer y) { return x + y; } public void sayHello(String name) { System.out.println("Hello " + name); } public Float giveMePi() { return 3.15f; }
  30. 30. public Integer addition(Integer x, Integer y) { return x + y; } public void sayHello(String name) { System.out.println("Hello " + name); } public Float giveMePi() { return 3.15f; }
  31. 31. (Integer x, Integer y) -> { return x + y; }; (String name) -> { System.out.println("Hello" + name); }; () -> { return 3.15f; };
  32. 32. (Integer x, Integer y) -> x + y; (String name) -> { System.out.println("Hello" + name); }; () -> 3.15f
  33. 33. (Integer x, Integer y) -> x + y; (String name) -> { System.out.println("Hello" + name); }; () -> 3.15f PARÁMETROS CUERPO
  34. 34. (parameters) -> body;
  35. 35. (Integer x, Integer y) -> x + y; (String name) -> System.out.println("Hello" + name); () -> 3.15f
  36. 36. Thread th = new Thread(new Runnable(){ @Override public void run() { System.out.println(">> Another thread")); } }); th.start(); Creando hilos
  37. 37. Thread th = new Thread(() -> System.out.println(">> Another thread")); th.start(); Creando hilos
  38. 38. Me váis a llamar loco pero…
  39. 39. …en ocasiones veo patrones
  40. 40. Thread th = new Thread(() -> System.out.println(">> Another thread")); th.start(); Creando hilos
  41. 41. Client Invoker Receiver +action() ConcreteCommand +execute() Command +execute()
  42. 42. Command PATRÓN
  43. 43. new Invoker().addCommand(new Command() { @Override public void execute() { receiver.action(); } });
  44. 44. new Transaction().doWithTransaction(new Command() { @Override public void execute() { myBusinessLogic.calculateInterests(); } });
  45. 45. new Context().doAsync(new Command() { @Override public void execute() { networkManager.downloadFile(); } });
  46. 46. Client Invoker Receiver +action() ConcreteCommand +execute() Command +execute()
  47. 47. Client Invoker Receiver +action() ConcreteCommand +execute() Command +execute() Lambda
  48. 48. new Invoker().addCommand(new Command() { @Override public void execute() { receiver.action(); } });
  49. 49. new Invoker().addCommand(new Command() { @Override public void execute() { receiver.action(); } });
  50. 50. new Invoker().addCommand( () -> receiver.action(); );
  51. 51. surely, we can do better
  52. 52. new Invoker().addCommand( receiver::action ); Method Reference
  53. 53. Method Reference: Transformar un método en una lambda
  54. 54. () -> receiver.action() (el) -> el.toString() () -> Runtime.getInstance() () -> new Receiver()
  55. 55. () -> receiver.action() (el) -> el.toString() () -> Runtime.getInstance() () -> new Receiver()
  56. 56. () -> receiver.action() receiver::action (el) -> el.toString() Object::toString () -> Runtime.getInstance() Runtime::getInstance () -> new Receiver() Reciver::new
  57. 57. Instance method reference (objeto concreto) Instance method reference (cualquier objeto) Static method reference Constructor reference receiver::action Object::toString Runtime::getInstance Reciver::new
  58. 58. (Integer x, Integer y) -> receiver.action(x, y) (Integer x, Integer y) -> Math.max(x, y) (String str) -> new String(str)
  59. 59. (Integer x, Integer y) -> receiver.action(x, y) receiver::action (Integer x, Integer y) -> Math.max(x, y) Math::max (String str) -> new String(str) String::new
  60. 60. new Transaction().doWithTransaction( myBusinessLogic::calculateInterests ); new ThreadPool().doInThread( networkManager::downloadFile ); new Transaction().doWithTransaction( networkManager::downloadFile ); new ThreadPool().doInThread( myBusinessLogic::calculateInterests );
  61. 61. Client Invoker Receiver +action() ConcreteCommand +execute() Command +execute()
  62. 62. Client Invoker Receiver +action() ConcreteCommand +execute() Command +execute()
  63. 63. Client Invoker Receiver +action() Command +execute()
  64. 64. (Integer x, Integer y) -> x + y; (String name) -> System.out.println("Hello" + name); () -> 3.15f ¿Qué TIPO tienen las lambdas?
  65. 65. Object addition = (Integer x, Integer y) -> x + y; Object sayHello = (String name) -> System.out.println("Hello" + name); Object giveMePi = () -> 3.15f ¿Qué TIPO tienen las lambdas?
  66. 66. The target type of this expression must be a functional interface
  67. 67. Java 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  68. 68. (Integer x, Integer y) -> x + y; (String name) -> System.out.println("Hello" + name); () -> 3.15f
  69. 69. (Integer x, Integer y) -> x + y; (String name) -> System.out.println("Hello" + name); () -> 3.15f Integer addition(Integer x, Integer y) void sayHello(String name) Float giveMePi()
  70. 70. Functional interfaces public interface Addition { Integer addition(Integer x, Integer y); } public interface SayHello { void sayHello(String name); } public interface GiveMePi { Float giveMePi(); }
  71. 71. Functional interfaces public interface Addition { public Integer addition(Integer x, Integer y); } 1 sólo método
  72. 72. Functional interfaces public interface Addition { public Integer addition(Integer x, Integer y); } Addition addition = (Integer x, Integer y) -> x + y;
  73. 73. public interface Addition { public Integer addition(Integer x, Integer y); } public interface Operation<T extends Number> { public T do(T x, T y); } Operation<Integer> addition = (Integer x, Integer y) -> x + y;
  74. 74. PROBLEMA Sólo funciona con interfaces ● NO pueden ser clases ● NI clases abstractas
  75. 75. Java 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  76. 76. Default Methods public interface Addition { public Integer addition(Integer x, Integer y); default Integer substraction(Integer x, Integer y) { return addition(x, -y); } }
  77. 77. public interface Addition { public Integer addition(Integer x, Integer y); } Addition addition = (Integer x, Integer y) -> x + y; Si tenemos que definir una “Functional Interface” por cada lambda... ¿Qué hemos ganado?
  78. 78. Java 8 viene con las interfaces más comunes DE SERIE
  79. 79. import java.util.function.* BiConsumer<T,U> IntBinaryOperator LongUnaryOperator BiFunction<T,U,R> IntConsumer ObjDoubleConsumer<T> BinaryOperator<T> IntFunction<R> ObjIntConsumer<T> BiPredicate<T,U> IntPredicate ObjLongConsumer<T> BooleanSupplier IntSupplier Predicate<T> Consumer<T> IntToDoubleFunction Supplier<T> DoubleBinaryOperator IntToLongFunction ToDoubleBiFunction<T,U> DoubleConsumer IntUnaryOperator ToDoubleFunction<T> DoubleFunction<R> LongBinaryOperator ToIntBiFunction<T,U> DoublePredicate LongConsumer ToIntFunction<T> DoubleSupplier LongFunction<R> ToLongBiFunction<T,U> DoubleToIntFunction LongPredicate ToLongFunction<T> DoubleToLongFunction LongSupplier UnaryOperator<T> DoubleUnaryOperator LongToDoubleFunction Function<T,R> LongToIntFunction
  80. 80. (Integer x, Integer y) -> x + y; (String name) -> System.out.println("Hello" + name); () -> 3.15f ¿Qué TIPO tienen? public Integer addition(Integer x, Integer y) public void sayHello(String name) public Float giveMePi()
  81. 81. BiConsumer<T,U> IntBinaryOperator LongUnaryOperator BiFunction<T,U,R> IntConsumer ObjDoubleConsumer<T> BinaryOperator<T> IntFunction<R> ObjIntConsumer<T> BiPredicate<T,U> IntPredicate ObjLongConsumer<T> BooleanSupplier IntSupplier Predicate<T> Consumer<T> IntToDoubleFunction Supplier<T> DoubleBinaryOperator IntToLongFunction ToDoubleBiFunction<T,U> DoubleConsumer IntUnaryOperator ToDoubleFunction<T> DoubleFunction<R> LongBinaryOperator ToIntBiFunction<T,U> DoublePredicate LongConsumer ToIntFunction<T> DoubleSupplier LongFunction<R> ToLongBiFunction<T,U> DoubleToIntFunction LongPredicate ToLongFunction<T> DoubleToLongFunction LongSupplier UnaryOperator<T> DoubleUnaryOperator LongToDoubleFunction Function<T,R> LongToIntFunction import java.util.function.*
  82. 82. BinaryOperator<Integer> addition = (Integer x, Integer y) -> x + y; Consumer<String> sayHi = (String name) -> System.out.println("Hello" + name); Supplier<Float> giveMePi = () -> 3.15f
  83. 83. BinaryOperator<Integer> addition = (x, y) -> x + y; Consumer<String> sayHi = (name) -> System.out.println("Hello" + name); Supplier<Float> giveMePi = () -> 3.15f
  84. 84. Thread th = new Thread(() -> System.out.println(">> Another thread")); th.start(); java.lang.Runnable
  85. 85. JButton button = new JButton("Button"); button.addActionListener((event) -> System.out.println("Mouse: " + event); ); java.awt.ActionListener
  86. 86. Observer PATRÓN
  87. 87. ConcreteObserverA +notify() ConcreteObserverB +notify() Observer +notify() ObservedClass +registerObserver() +unregisterObserver() +notifyObservers() Functional Interface Lambdas!
  88. 88. @FunctionalInterface public static interface Observer { public void notify(Object change); }
  89. 89. @FunctionalInterface public static interface Observer { public void notify(Object change); }
  90. 90. @FunctionalInterface public static interface Observer { public void notify(Object change); } El compilador fallará si no cumple con las condiciones de una FI.
  91. 91. @FunctionalInterface public static interface Observer { public void notify(Object change); } El compilador fallará si no cumple con las condiciones de una FI. Tu yo del futuro te lo agradecerá
  92. 92. public static class ObservedClass { private List<Observer> observers = new LinkedList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyChange(Object change) { observers.forEach((o) -> o.notify(change)); } }
  93. 93. public static class ObservedClass { private List<Observer> observers = new LinkedList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyChange(Object change) { observers.forEach((o) -> o.notify(change)); } } Una estructura de datos que guarda lambdas.
  94. 94. public static class ObservedClass { private List<Observer> observers = new LinkedList<>(); public void addObserver(Observer observer) { observers.add(observer); } public void removeObserver(Observer observer) { observers.remove(observer); } public void notifyChange(Object change) { observers.forEach((o) -> o.notify(change)); } } Nuevo método de Java 8
  95. 95. observed.addObserver((change) -> { new Thread(UIThread::update).start() }); sbj.notifyChange("Change");
  96. 96. Hipótesis ¿Puede haber un patrón de más alto nivel?
  97. 97. new Invoker().addCommand(receiver::action); observed.addObserver(receiver::action);
  98. 98. Pasar comportamiento como argumentos ● El comportamiento se ejecutará en otro contexto ● “Separation of concerns” ● También conocido como: High Order Functions new Invoker().addCommand(receiver::action); observed.addObserver(receiver::action);
  99. 99. List<Person> personList = new LinkedList<>(); Collections.sort( personList, (p1, p2) -> p1.age - p2.age ); java.lang.Comparable<T>
  100. 100. List<Person> personList = new LinkedList<>(); Collections.sort( personList, (p1, p2) -> p1.age - p2.age ); java.lang.Comparable<T> DATOS COMPORTAMIENTO
  101. 101. Strategy PATRÓN
  102. 102. Collections.sort( list, (p1, p2) -> p1.getAge() - p2.getAge()); Collections.sort( list, (p1, p2) -> p1.getName().compareTo(p2.getName())); Collections.sort( list, (p1, p2) -> -p1.getName().compareTo(p2.getName()));
  103. 103. Reusing lambdas class PersonSortCriterias { public static int sortByAge(Person p1, Person p2) { return p1.getAge() - p2.getName(); } public static int sortByName(Person p1, Person p2) { return p1.getName().compareTo(p2.getName()); } public static int sortByNameReverse(Person p1, Person p2) { return -p1.getName().compareTo(p2.getName()); } }
  104. 104. Collections.sort( list, PersonSortCriterias::sortByAge); Collections.sort( list, PersonSortCriterias::sortByName); Collections.sort( list, PersonSortCriterias::sortByNameReverse);
  105. 105. Set<Person> = new TreeSet<>( PersonSortCriterias::sortByAge ); Person theOlder = Collections.max( list, PersonSortCriterias::sortByAge ); list.sort(PersonSortCriterias::sortByAge);
  106. 106. Java 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  107. 107. Java 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  108. 108. Iterator PATRÓN
  109. 109. for (String str : list) { System.out.println(str); }
  110. 110. for (String str : list) { if (str.length <= 5) { System.out.println(str); } }
  111. 111. for (String str : Collections.sort(list)) { if (str.length <= 5) { System.out.println(str); } }
  112. 112. for (String str : Collections.sort(list).sublist(0, 10)) { if (str.length <= 5) { System.out.println(str); } }
  113. 113. for (String str : Collections.sort(list).sublist(0, 10)) { if (str.length <= 5) { System.out.println(str.toUpperCase()); } }
  114. 114. Problemas ● Susceptible a errores ● Difícil de razonar ● Difícil de reutilizar
  115. 115. Streams ● Interfaz fluida ● Evaluación perezosa ● Iterable ● Aprovechan toda la expresividad de las lambdas
  116. 116. list.stream() .forEach(System.out::println);
  117. 117. list.stream() .filter(s -> s.length <= 5) .forEach(System.out::println);
  118. 118. list.stream() .filter(s -> s.length <= 5) .sorted() .forEach(System.out::println);
  119. 119. list.stream() .filter(s -> s.length <= 5) .sorted() .limit(10) .forEach(System.out::println);
  120. 120. list.parallelStream() .filter(s -> s.length <= 5) .sorted() .limit(10) .forEach(System.out::println);
  121. 121. Funciones importantes ● Map ● Filter ● Reduce
  122. 122. MAP - FILTER - REDUCE list.stream() .map(String::toUpperCase) "banana" "apple" "pear" "pineapple" "lemon" "mango" "raspberry" "melon" "BANANA" "APPLE" "PEAR" "PINEAPPLE" "LEMON" "MANGO" "RASPBERRY" "MELON"
  123. 123. MAP - FILTER - REDUCE list.stream() .filter(s -> s.length <= 5) "banana" "apple" "pear" "pineapple" "lemon" "mango" "raspberry" "melon" "apple" "pear" "lemon" "mango" "melon"
  124. 124. MAP - FILTER - REDUCE list.stream() .reduce("", (acc, elem) -> acc + ", " + elem); "banana" "apple" "pear" "pineapple" "lemon" "mango" "raspberry" "melon" "banana,apple,pear,pineapple,...
  125. 125. Chain of responsibility PATRÓN
  126. 126. HANDLER HANDLER HANDLER HANDLER HANDLER request
  127. 127. HANDLER HANDLER HANDLER HANDLER HANDLERrequest
  128. 128. HANDLER HANDLER HANDLER HANDLER HANDLERrequest
  129. 129. HANDLER HANDLER HANDLER HANDLER HANDLER request
  130. 130. @FunctionalInterface public interface Handler { public Request handleRequest(Request req); }
  131. 131. @FunctionalInterface public interface Handler extends Function<Request, Request> { }
  132. 132. List<Handler> chain = new LinkedList<>(); chain.add(Request::session); chain.add(Request::securityCheck); chain.add(Request::cookies); chain.add(Request::getParameters);
  133. 133. List<Handler> chain = new LinkedList<>(); chain.add(Request::session); chain.add(Request::securityCheck); chain.add(Request::cookies); chain.add(Request::getParameters); Request req = new Request(); Request processed = chain.stream() .reduce(initial value, accumulation function)
  134. 134. List<Handler> chain = new LinkedList<>(); chain.add(Request::session); chain.add(Request::securityCheck); chain.add(Request::cookies); chain.add(Request::getParameters); Request req = new Request(); Request processed = chain.stream() .reduce(req, accumulation function)
  135. 135. List<Handler> chain = new LinkedList<>(); chain.add(Request::session); chain.add(Request::securityCheck); chain.add(Request::cookies); chain.add(Request::getParameters); Request req = new Request(); Request processed = chain.stream() .reduce(req, (old, handler) -> handler.apply(old))
  136. 136. HANDLER HANDLER HANDLER HANDLER HANDLER request
  137. 137. HANDLER HANDLER HANDLER HANDLER HANDLER request CHAIN (HANDLER)
  138. 138. List<Handler> filters = new LinkedList<>(); filters.add(Request::session); filters.add(Request::securityCheck); filters.add(Request::cookies); filters.add(Request::getParameters); Handler filterChain = filters.stream() .reduce( initial value, accumulation function);
  139. 139. List<Handler> filters = new LinkedList<>(); filters.add(Request::session); filters.add(Request::securityCheck); filters.add(Request::cookies); filters.add(Request::getParameters); Handler filterChain = filters.stream() .reduce( (r) -> r, accumulation function);
  140. 140. List<Handler> filters = new LinkedList<>(); filters.add(Request::session); filters.add(Request::securityCheck); filters.add(Request::cookies); filters.add(Request::getParameters); Handler filterChain = filters.stream() .reduce( (r) -> r, (f1, f2) -> f1.andThen(f2));
  141. 141. List<Handler> filters = new LinkedList<>(); filters.add(Request::session); filters.add(Request::securityCheck); filters.add(Request::cookies); filters.add(Request::getParameters); Handler filterChain = filters.stream() .reduce( Function.identity(), Function::andThen);
  142. 142. System.out.println("nProcessing request 1"); Request r1 = chain.apply(new Request()); System.out.println("nProcessing request 2"); Request r2 = chain.apply(new Request()); Processing request 1 >> process session >> process securityCheck >> process cookies >> process getParameters Processing request 2 >> process session >> process securityCheck >> process cookies >> process getParameters
  143. 143. ¯_(ツ)_/¯
  144. 144. Java SE 8 ● Lambda expressions ● Functional interfaces ● Default methods ● Streams
  145. 145. Patrones ● Command ● Strategy ● Observer ● Iterator ● Chain of responsibility
  146. 146. Los patrones definen: soluciones a problemas frecuentes
  147. 147. Problema ● El comportamiento y el contexto son diferentes ● Encapsular los datos ● Composición de comportamiento Solución ● High order functions (Lambdas)
  148. 148. Las lambdas son lo mejor que le ha pasado a Java.
  149. 149. Sobre los hombros de gigantes Mario Fusco Venkat Subramaniam Samir Talwar https://youtu.be/K6BmGBzIqW0 https://vimeo.com/122645679https://youtu.be/8qcHPEyLkPE
  150. 150. @alotor mobro.co/alotor ¿Preguntas? @alotor
  151. 151. Referencias ● https://en.wikipedia.org/wiki/Java_version_history ● http://www.studytrails.com/java/java8/Java8_Lambdas_FunctionalProgramming.jsp ● https://blog.idrsolutions.com/2015/02/java-8-method-references-explained-5-minutes/ ● http://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood ● http://www.javaworld.com/article/2078675/core-java/design-patterns--the-big-picture--part-2--gang- of-four-classics-revisited.html ● http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries ● https://www.questers.com/sites/all/themes/questers/sec_presentation/java8lambdas.html ● http://www.slideshare.net/jaxlondon2012/lambda-a-peek-under-the-hood-brian-goetz ● http://www.infoq.com/presentations/lambda-invokedynamic? utm_source=infoq&utm_medium=videos_homepage&utm_campaign=videos_row1 ● http://www.slideshare.net/DaewonJeong/scala-is-java8next ● http://programmers.stackexchange.com/questions/173441/what-triggered-the-popularity-of-lambda- functions-in-modern-mainstream-programmi ● http://www.infoq.com/presentations/A-Brief-History-of-the-Java-World
  152. 152. Referencias ● http://j2objc.org/blog/2015/08/07/lambdas-in-java-8-dysfunctional-interfaces.html ● http://gafter.blogspot.com.es/2006/08/closures-for-java.html ● http://www.javaworld.com/article/2077569/core-java/java-tip-68--learn-how-to-implement-the- command-pattern-in-java.html ● http://www.slideshare.net/mariofusco/fp-in-java-project-lambda-and-beyond?qid=11ae9463-c2e3- 4c54-842f-b228ce109200&v=default&b=&from_search=12 ● http://www.norvig.com/design-patterns/design-patterns.pdf ● http://www.techempower.com/blog/2013/03/26/everything-about-java-8/ ● http://www.oracle.com/technetwork/server-storage/ts-4961-159222.pdf ● http://talks.samirtalwar.com/design-patterns-in-the-21st-century.html

×