Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Lekcja stylu

4,035 views

Published on

Lekcja Stylu - czy w Javie można jeszcze dostrzec piękno?

Przeglądając listy prezentacji na konferencjach związanych z Javą z ostatnich lat można dostrzec pewien wzorzec. Przedstawia się coraz to bardziej wyrafinowane zręby aplikacji, wskazówki integracyjne dla kolejnych JBusinessComponents oraz zręby aplikacji webowych, gdzie wypisanie "Hello World" zajmuje trzy linijki zamiast pięciu. Czyżby zapomniano już o samym języku Java? Czyżby wszyscy już przesiedli się na Scalę, Groovy lub JRuby?

Swoją prezentacją chcę wrócić do korzeni, do samego języka Java. Będę pokazywał dobre przykłady, jak należy programować, aby czytanie kodu było miłym doświadczeniem. Nie będzie jednak to wykład o wzorcach projektowych, ale o codzienności programisty, który właśnie po wypiciu porannej kawy i otwarciu edytora, pisze pierwszą tego dnia instrukcję warunkową.

Będzie to hołd książce "Implementation Patterns" Kenta Becka. W prezentacji zostaną przedstawione także ułatwiające życie biblioteki takie jak Google Guava, Google Guice oraz Mockito.

  • Be the first to comment

Lekcja stylu

  1. 1. LEKCJA STYLU czy w Javie można jeszcze dostrzec piękno? Wiktor Gworek • Javarsovia 2010 • Google
  2. 2. @wwiktorr ^wwiktorr wiktorgworek.com blog.mocna-kawa.com
  3. 3. PIĘKNO KODU definicja dla Javy
  4. 4. czytelność boilerplate łatwe testowanie PIĘKNO KODU definicja dla Javy statyczne narzędzia typowanie
  5. 5. NARZĘDZIA • Google Guava • http://code.google.com/p/guava-libraries/ • Google Guice • http://code.google.com/p/google-guice/ • Mockito • http://code.google.com/p/mockito/
  6. 6. Czytelność Funkcyjność
  7. 7. POPRAWIANIE CZYTELNOŚCI http://www.flickr.com/photos/jleveque/2151484964
  8. 8. “Jejku, ten kod wygląda, jakby go pisał sam Steven King. Horror, aż strach przejść na kolejną stronę.” – anonimowy programista
  9. 9. if (GOOGLE) { CODE.STYLE(); }
  10. 10. 100 znaków if (GOOGLE) { CODE.STYLE(); }
  11. 11. 100 znaków if (GOOGLE) { t CODE.STYLE(); }
  12. 12. 100 znaków if (GOOGLE) { t CODE.STYLE(); } 2 znaki
  13. 13. 100 znaków if (GOOGLE) { t CODE.STYLE(); } 2 znaki
  14. 14. KODOWANIE DEFENSYWNE http://www.flickr.com/photos/mosca27/166707333/
  15. 15. KODOWANIE DEFENSYWNE public void analyze(String msg) { if (msg == null) { throw NullPointerException(); } if (msg.length() > 160) { throw IllegalArgumentException( “Tak długa wiadomość?”); } // analiza wiadomości }
  16. 16. KODOWANIE DEFENSYWNE public void analyze(String msg) { Preconditions.checkNotNull(msg); Preconditions.checkArgument( msg.length() <= 160, “Tak długa wiadomość?”); // analiza wiadomości }
  17. 17. ZBĘDNY KOD
  18. 18. KOLEKCJE com.google.common.collect Map<String, List<User, Role>> map = new HashMap<String, List<User, Role>>;
  19. 19. KOLEKCJE com.google.common.collect Map<String, List<User, Role>> map = new HashMap<String, List<User, Role>>; Map<String, List<User, Role>> m = Maps.newHashMap(); List<Long> l = Lists.newArrayListWithExpectedSize(3); Set<Pair<String, User>> set = Sets.newHashSet(); Set<String> set = Sets.newHashSet(“a”, “b”, “c”);
  20. 20. NIEMODYFIKOWANE OBIEKTY
  21. 21. NIEMODYFIKOWANE OBIEKTY public void setName(String newName); private final Address address;
  22. 22. NIEMODYFIKOWANE OBIEKTY public void setName(String newName); private final Address address; // Wykorzystanie Protocol Buffers Post newPost = post.toBuilder() .setTitle(newTitle) .build();
  23. 23. KOLEKCJE com.google.common.collect List<String> list = new ArrayList<String>(); list.add(“a”); list.add(“b”); list.add(“c”); public static final Set<Integer> LUCKY_NUMBERS; static { Set<Integer> set = new LinkedHashSet<Integer>; set.add(4); set.add(7); set.add(42); LUCKY_NUMBERS = Collections.unmodifiableSet(set); }
  24. 24. KOLEKCJE com.google.common.collect public static final Set<Integer> LUCKY_NUMBERS = Collections.unmodifiableSet( new LinkedHashSet<Integer>( Arrays.asList(4, 7, 42)));
  25. 25. KOLEKCJE com.google.common.collect
  26. 26. KOLEKCJE com.google.common.collect List<String> list = ImmutableList.of(“a”, “b”, “c”);
  27. 27. KOLEKCJE com.google.common.collect List<String> list = ImmutableList.of(“a”, “b”, “c”); static final Set<Integer> LUCKY_NUMBERS = ImmutableSet.of(4, 7, 42);
  28. 28. KOLEKCJE com.google.common.collect List<String> list = ImmutableList.of(“a”, “b”, “c”); static final Set<Integer> LUCKY_NUMBERS = ImmutableSet.of(4, 7, 42); static final Map<String, String> FORBIDDEN = ImmutableMap.of(“key1”, “val1”, “key2”, “val2”);
  29. 29. ZNOWU TO SAMO... http://www.flickr.com/photos/nifmus/2385966735/
  30. 30. KOLEKCJE com.google.common.collect Map<String, List<String>> map = Maps.newHashMap(); for (Pair<String, String> pair : input) { if (map.containsKey(pair.fst)) { map.get(pair.fst).add(pair.snd); } else { map.put(pair.fst, Lists.newArrayList(pair.snd)); } } List<String> result = map.get(“Kasia”);
  31. 31. KOLEKCJE com.google.common.collect Map<String, List<String>> map = Maps.newHashMap(); for (Pair<String, String> pair : input) { if (map.containsKey(pair.fst)) { map.get(pair.fst).add(pair.snd); } else { map.put(pair.fst, Lists.newArrayList(pair.snd)); } } List<String> result = map.get(“Kasia”);
  32. 32. KOLEKCJE com.google.common.collect Map<String, List<String>> map = Maps.newHashMap(); for (Pair<String, String> pair : input) { if (map.containsKey(pair.fst)) { map.get(pair.fst).add(pair.snd); } else { map.put(pair.fst, Lists.newArrayList(pair.snd)); } } List<String> result = map.get(“Kasia”);
  33. 33. KOLEKCJE com.google.common.collect Map<String, List<String>> map = Maps.newHashMap(); for (Pair<String, String> pair : input) { if (map.containsKey(pair.fst)) { map.get(pair.fst).add(pair.snd); } else { map.put(pair.fst, Lists.newArrayList(pair.snd)); } } List<String> result = map.get(“Kasia”);
  34. 34. KOLEKCJE com.google.common.collect Map<String, List<String>> map = Maps.newHashMap(); for (Pair<String, String> pair : input) { if (map.containsKey(pair.fst)) { map.get(pair.fst).add(pair.snd); } else { map.put(pair.fst, Lists.newArrayList(pair.snd)); } } List<String> result = map.get(“Kasia”);
  35. 35. KOLEKCJE com.google.common.collect Map<String, List<String>> map = Maps.newHashMap(); for (Pair<String, String> pair : input) { if (map.containsKey(pair.fst)) { map.get(pair.fst).add(pair.snd); } else { map.put(pair.fst, Lists.newArrayList(pair.snd)); } } List<String> result = map.get(“Kasia”);
  36. 36. KOLEKCJE com.google.common.collect Multimap<String, String> multimap = ArrayListMultimap.create(); for (Pair<String, String> pair : input) { multimap.put(pair.fst, pair.snd); } List<String> result = multimap.get(“Kasia”);
  37. 37. KOLEKCJE com.google.common.collect Multimap<String, String> multimap = ArrayListMultimap.create(); for (Pair<String, String> pair : input) { multimap.put(pair.fst, pair.snd); } List<String> result = multimap.get(“Kasia”);
  38. 38. KOLEKCJE com.google.common.collect Multimap<String, String> multimap = ArrayListMultimap.create(); for (Pair<String, String> pair : input) { multimap.put(pair.fst, pair.snd); } List<String> result = multimap.get(“Kasia”);
  39. 39. KOLEKCJE com.google.common.collect Multimap<String, String> multimap = ArrayListMultimap.create(); for (Pair<String, String> pair : input) { multimap.put(pair.fst, pair.snd); } List<String> result = multimap.get(“Kasia”);
  40. 40. KOLEKCJE com.google.common.collect Multimap<String, String> multimap = ArrayListMultimap.create(); for (Pair<String, String> pair : input) { multimap.put(pair.fst, pair.snd); } List<String> result = multimap.get(“Kasia”);
  41. 41. FLUENT INTERFACE com.google.common.base.Joiner
  42. 42. FLUENT INTERFACE com.google.common.base.Joiner String s = Joiner.on(",").join(episodes); String s = Joiner.on(“|”).skipNulls().join(users);
  43. 43. FLUENT INTERFACE com.google.common.base.Joiner String s = Joiner.on(",").join(episodes); String s = Joiner.on(“|”).skipNulls().join(users); StringBuffer sb = ...; Joiner.on(“|”) .useForNull("[user removed]") .appendTo(sb, users);
  44. 44. FLUENT INTERFACE com.google.common.base.Joiner String s = Joiner.on(",").join(episodes); String s = Joiner.on(“|”).skipNulls().join(users); StringBuffer sb = ...; Joiner.on(“|”) .useForNull("[user removed]") .appendTo(sb, users); Joiner.on(“;”) .userForNull(“NODATA”) .withKeyValueSeparator(“:”) .join(ImmutableMap.of(“key”, “value”, ...));
  45. 45. ZABAWA Z FUNKCYJNOŚCIĄ http://www.flickr.com/photos/infrarad/182786930
  46. 46. WEJŚCIE: lista loginów w serwisie WYJŚCIE: posortowana lista użytkowników, którzy mają więcej niż 18 lat
  47. 47. logins .map{ |login| User.select_by_login(login)} .find_all{ |user| user != nil && user.age > 18 } .sort_by{ |user| [user.surname, user.name] }
  48. 48. logins .map{ |login| User.select_by_login(login)} .find_all{ |user| user != nil && user.age > 18 } .sort_by{ |user| [user.surname, user.name] }
  49. 49. logins .map{ |login| User.select_by_login(login)} .find_all{ |user| user != nil && user.age > 18 } .sort_by{ |user| [user.surname, user.name] }
  50. 50. logins .map{ |login| User.select_by_login(login)} .find_all{ |user| user != nil && user.age > 18 } .sort_by{ |user| [user.surname, user.name] }
  51. 51. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  52. 52. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  53. 53. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  54. 54. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  55. 55. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  56. 56. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  57. 57. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  58. 58. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  59. 59. PIERWSZA PRÓBA List<String> logins = ...; List<User> users = new ArrayList(); for (String login : logins) { if (!Strings.isNullOrEmpty(login)) { User user = userDao.selectByLogin(login); if (user != null && user.getAge() >= 18) { users.add(user); } } } Collections.sort(users, new Comparator<User>() { @Override public int compare(User u1, User u2) { int result = u1.getSurname().compareTo(u2.getSurname()); if (result != 0) { return result; } return u1.getName().compareTo(u2.getName()); }});
  60. 60. FUNKCJE com.google.common.base.Function public interface Function<F, T> { T apply(@Nullable F from); }
  61. 61. FUNKCJE com.google.common.base.Function static class FetchUsers implements Function<String, User> { private final UserDao userDao; public FetchUsers(UserDao userDao) { this.userDao = userDao; } @Override public User apply(String login) { if (Strings.isNullOrEmpty(login)) { return null; } return userDao.selectByLogin(login); } }
  62. 62. FUNKCJE com.google.common.base.Function static class FetchUsers implements Function<String, User> { private final UserDao userDao; public FetchUsers(UserDao userDao) { this.userDao = userDao; } @Override public User apply(String login) { if (Strings.isNullOrEmpty(login)) { return null; } return userDao.selectByLogin(login); } }
  63. 63. FUNKCJE com.google.common.base.Function static class FetchUsers implements Function<String, User> { private final UserDao userDao; public FetchUsers(UserDao userDao) { this.userDao = userDao; } @Override public User apply(String login) { if (Strings.isNullOrEmpty(login)) { return null; } return userDao.selectByLogin(login); } }
  64. 64. FUNKCJE com.google.common.base.Function static class FetchUsers implements Function<String, User> { private final UserDao userDao; public FetchUsers(UserDao userDao) { this.userDao = userDao; } @Override public User apply(String login) { if (Strings.isNullOrEmpty(login)) { return null; } return userDao.selectByLogin(login); } }
  65. 65. FUNKCJE com.google.common.base.Function static class FetchUsers implements Function<String, User> { private final UserDao userDao; public FetchUsers(UserDao userDao) { this.userDao = userDao; } @Override public User apply(String login) { if (Strings.isNullOrEmpty(login)) { return null; } return userDao.selectByLogin(login); } }
  66. 66. PREDYKATY com.google.common.base.Predicate public interface Predicate<T> { boolean apply(@Nullable T input); }
  67. 67. PREDYKATY com.google.common.base.Predicate static final Predicate<User> OVER_18 = new Predicate<User>() { @Override public boolean apply(User user) { return user.getAge() >= 18; } };
  68. 68. PREDYKATY com.google.common.base.Predicate static final Predicate<User> OVER_18 = new Predicate<User>() { @Override public boolean apply(User user) { return user.getAge() >= 18; } };
  69. 69. PREDYKATY com.google.common.base.Predicate static final Predicate<User> OVER_18 = new Predicate<User>() { @Override public boolean apply(User user) { return user.getAge() >= 18; } };
  70. 70. PREDYKATY com.google.common.base.Predicate static final Predicate<User> OVER_18 = new Predicate<User>() { @Override public boolean apply(User user) { return user.getAge() >= 18; } };
  71. 71. ŁADNY KOMPARATOR com.google.common.collect.ComparisonChain static final Comparator<User> NAME_ASC = new Comparator<User>() { @Override public int compare(User u1, User u2) { return ComparisonChain.start() .compare(u1.getSurname(), u2.getSurname()) .compare(u1.getName(), u2.getName()) .result(); } };
  72. 72. ŁADNY KOMPARATOR com.google.common.collect.ComparisonChain static final Comparator<User> NAME_ASC = new Comparator<User>() { @Override public int compare(User u1, User u2) { return ComparisonChain.start() .compare(u1.getSurname(), u2.getSurname()) .compare(u1.getName(), u2.getName()) .result(); } };
  73. 73. ŁADNY KOMPARATOR com.google.common.collect.ComparisonChain static final Comparator<User> NAME_ASC = new Comparator<User>() { @Override public int compare(User u1, User u2) { return ComparisonChain.start() .compare(u1.getSurname(), u2.getSurname()) .compare(u1.getName(), u2.getName()) .result(); } };
  74. 74. ŁADNY KOMPARATOR com.google.common.collect.ComparisonChain static final Comparator<User> NAME_ASC = new Comparator<User>() { @Override public int compare(User u1, User u2) { return ComparisonChain.start() .compare(u1.getSurname(), u2.getSurname()) .compare(u1.getName(), u2.getName()) .result(); } };
  75. 75. ŁADNY KOMPARATOR com.google.common.collect.ComparisonChain static final Comparator<User> NAME_ASC = new Comparator<User>() { @Override public int compare(User u1, User u2) { return ComparisonChain.start() .compare(u1.getSurname(), u2.getSurname()) .compare(u1.getName(), u2.getName()) .result(); } };
  76. 76. ŁADNY KOMPARATOR com.google.common.collect.ComparisonChain static final Comparator<User> NAME_ASC = new Comparator<User>() { @Override public int compare(User u1, User u2) { return ComparisonChain.start() .compare(u1.getSurname(), u2.getSurname()) .compare(u1.getName(), u2.getName()) .result(); } };
  77. 77. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  78. 78. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  79. 79. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  80. 80. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  81. 81. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  82. 82. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  83. 83. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  84. 84. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  85. 85. DRUGA PRÓBA com.google.common.collect.Iterables import static com.google.common.collect.Iterables.*; Iterable<User> users = transform(logins, new FetchUsers(userDao)); Iterable<User> notNullUsers = filter(users, Predicates.notNull()); Iterable<User> matureUsers = filter(notNullUsers, OVER_18); List<User> result = com.google.common.collect.Ordering .from(NAME_ASC) .reverse() .immutableSortedCopy(matureUsers);
  86. 86. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  87. 87. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  88. 88. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  89. 89. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  90. 90. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  91. 91. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  92. 92. TRZECIA PRÓBA ImmutableList<User> result = FluentIterable .with(logins) .transform(new FetchUsers(userDao)) .filter(Predicates.notNull()) .filter(OVER_18) .sort(NAME_DESC) .immutableCopy();
  93. 93. Czytelność Funkcyjność
  94. 94. Pytania? Wiktor Gworek • Javarsovia 2010 • Google

×