Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Like this? Share it with your network

Share

[PL] O klasycznej, programistycznej elegancji

on

  • 951 views

This presentation is only in Polish.

This presentation is only in Polish.

Slajdy z prezentacji grupy JUG, 25 listopada 2010

Statistics

Views

Total Views
951
Views on SlideShare
910
Embed Views
41

Actions

Likes
0
Downloads
3
Comments
0

2 Embeds 41

http://www.linkedin.com 30
https://www.linkedin.com 11

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

[PL] O klasycznej, programistycznej elegancji Presentation Transcript

  • 1. O klasycznej programistycznej elegancji http://my.opera.com/rato53/albums/
  • 2. Jakub MarchwickiTechnical ConsultantJava, Lua, PHPi tak od 9latmarchwicki.pl/blog@kubamarchwicki
  • 3. Kanon piękna? © vitra
  • 4. „Any fool can write code that a computer can understand. Good programmers write code that humans can understand“Refactoring: Improving the Design of Existing Code, 1999
  • 5. Martin Fowler jeszcze raz
  • 6. Joshua Bloch
  • 7. Effective Java I sure wish I had this book ten years ago James Gosling
  • 8. Kent Beck„Many peopledon’t realize howreadable codecan be and howvaluable thatreadability is.Kent has taughtme so...“ Martin Fowler
  • 9. Implementation patterns Communication Simplicity FlexibilityA wszystko dlatego żenajwiększym kosztem oprogramowania będzie i tak jego utrzymanie
  • 10. Kryteria dobrego kodu © http://www.agileadvisor.com/
  • 11. Nie będzie Eclipsa...private static boolean isOlderExtremeVersion(String d1, String d2) { String[] dateOneA = dateOne.split("-"); String[] dateTwoA = dateTwo.split("-"); if ((Integer.valueOf(dateOneA[0]).intValue() > Integer.valueOf(dateTwoA[0]).intValue()) || (Integer.valueOf(dateOneA[0]).intValue() == Integer.valueOf(dateTwoA[0]).intValue() && Integer.valueOf(dateOneA[1]).intValue() > Integer.valueOf(dateTwoA[1]).intValue()) || (Integer.valueOf(dateOneA[0]).intValue() == Integer.valueOf(dateTwoA[0]).intValue() && Integer.valueOf(dateOneA[1]).intValue() == Integer.valueOf(dateTwoA[1]).intValue() && Integer.valueOf(dateOneA[2]).intValue() > Integer.valueOf(dateTwoA[2]).intValue())) { return false; } return true;}
  • 12. Wyobraźmy sobie model...public class Person { private String firstName; private String lastName; private long birthDate;}public class Student extends Person { private int year;}public class Professor extends Person { private String[] specjalities;}public class Lecture { private String title; private Professor professor; private Student[] students;}
  • 13. A teraz piszemy...public boolean equals(Object o) { if (!(o instanceof Person)) return false; final Person p = (Person) o; return firstName.equals(p.firstName) && lastName.equals(p.lastName) && birthDate == p.birthDate;}public int hashcode() { int result = 17; result = 37*result + firstName.hashCode(); result = 37*result + lastName.hashCode(); result = 37*result + (int)(birthDate ^ birthDate >>> 32); return result;}
  • 14. lub generujemy...public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(specjalities); return result;}public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (!(obj instanceof Professor)) { return false; } Professor other = (Professor) obj; if (!Arrays.equals(specjalities, other.specjalities)) { return false; } return true;}
  • 15. to samo tyczy się toString()apublic String toString() { return "Professor [specjalities=" + Arrays.toString(specjalities) + "]";}
  • 16. ale przy setce encji się nie chciećpublic boolean equals(Object o) { if (o == null) { return false; } if (o == this) { return true; } if (o.getClass() != getClass()) { return false; } final Student s = (Student) o; return new EqualsBuilder() .appendSuper(super.equals(o)).append(year, s.year) .isEquals();}public int hashcode() { return new HashCodeBuilder(17, 37) .appendSuper(super.hashcode()).append(year) .toHashCode();}public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()).append("year", year) .toString();}
  • 17. albo mniej fundamentalniepublic boolean equals(Object o) { if (o instanceof Lecture) { Lecture l = (Lecture) o; return Objects.equal(professor, l.professor) && Objects.equal(students, l.students) && Objects.equal(title, l.title); } return false;}public int hashcode() { return Objects.hashCode(title, professor, students);}public String toString() { return Objects.toStringHelper(this) .add("professor", professor) .add("students", students) .toString();}
  • 18. defensive programmingpublic void addLectureWithCommons(Lecture lecture, Venue venue, int dayOfTheWeek, int hour) { Validate.isTrue(dayOfTheWeek > 0 && dayOfTheWeek <= 7, "There are only 7 days of the week"); Validate.isTrue(hour >= 0 && hour < 23, "Day has only 24hours"); Validate.notNull(lecture != null, "Lecture cannot be null"); Validate.notNull(venue != null, "Venue cannot be null"); // reminder omitted}public void addLectureWithGuava(Lecture lecture, Venue venue, int dayOfTheWeek, int hour) { Preconditions.checkArgument(dayOfTheWeek > 0 && dayOfTheWeek <= 7, "There are only 7 days of the week"); Preconditions.checkArgument(hour >= 0 && hour < 23, "Day has only 24hours"); Preconditions.checkArgument(lecture != null, "Lecture cannot be null"); Lecture localLecture = Preconditions.checkNotNull(lecture); Venue localVenue = Preconditions.checkNotNull(venue); // reminder omitted}
  • 19. a później zawsze trafimy na StringaString[] csv;for (String line : csv) { String[] elements = line.split(","); // reminder omitted}for (String line : csv) { String[] r = StringUtils.split(line, ","); r = StringUtils.stripAll(r);}for (String line : csv) { Splitter.on(",") .trimResults() .omitEmptyStrings() .split(line);}
  • 20. a później zawsze trafimy na StringaString[] csv;for (String line : csv) { String[] elements = line.split(","); // reminder omitted}for (String line : csv) { String[] r = StringUtils.split(line, ","); r = StringUtils.stripAll(r);}for (String line : csv) { Splitter.on(",") .trimResults() .omitEmptyStrings() .split(line);}
  • 21. i kilka operacji biznesowychpublic interface LectureService { public Student[] getStudentsByYear(int year); public Student[] getStudentsOlderThan(int age); public Student[] getStudentsByBirthDate(Date date);}
  • 22. które sprowadzają się...public Student[] getStudentsByYear(int year) { final List<Student> students = new ArrayList<Student>(); for (Student s : lecture.getStudents()) { if (s.getYear() == year) { students.add(s); } } return students.toArray(new Student[] {});}
  • 23. ... do niemal ...public Student[] getStudentsByBirthDate(Date date) { final List<Student> students = new ArrayList<Student>(); for (Student s : lecture.getStudents()) { Calendar studentBirth = Calendar.getInstance(); studentBirth.setTimeInMillis(s.getBirthDate()); Calendar desiredDate = Calendar.getInstance(); desiredDate.setTime(date); if (studentBirth.get(Calendar.YEAR) == desiredDate.get(Calendar.YEAR) && studentBirth.get(Calendar.MONTH) == desiredDate.get(Calendar.MONTH) && studentBirth.get(Calendar.DATE) == desiredDate.get(Calendar.DATE)) { students.add(s); } } return students.toArray(new Student[] {});}
  • 24. ... tego samego.public Student[] getStudentsOlderThan(int age) { final List<Student> students = new ArrayList<Student>(); for (Student s : lecture.getStudents()) { Calendar c = Calendar.getInstance(); c.setTimeInMillis(s.getBirthDate()); c.add(Calendar.YEAR, age); Calendar now = Calendar.getInstance(); now.setTime(new Date()); if (c.before(now)) { students.add(s); } } return students.toArray(new Student[] {});}
  • 25. i abstahując od użycia JodaTimepublic Student[] getStudentsOlderThan(int age) { final List<Student> students = new ArrayList<Student>(); for (Student s : lecture.getStudents()) { DateMidnight dt = new DateMidnight() .withMillis(s.getBirthDate()) .plusYears(age); if (dt.isBeforeNow()) { students.add(s); } } return students.toArray(new Student[] {});}
  • 26. Dont Repeat Yourselfprivate Student[] getStudents(Predicate predicate) { final List<Student> students = new ArrayList<Student>(); for (Student s : lecture.getStudents()) { if (predicate.evaluate(s)) { students.add(s); } } return students.toArray(new Student[] {});}
  • 27. No a ten predykat?Predicate predicate = new Predicate() { @Override public boolean evaluate(Object arg0) { if (arg0 instanceof Student) { Student s = (Student) arg0; DateMidnight dt = new DateMidnight() .withMillis(s.getBirthDate()) .plusYears(age); if (dt.isBeforeNow()) { return true; } } return false; }};
  • 28. No a ten predykat? (2)Predicate<Student> predicate = new Predicate<Student>() { @Override public boolean apply(Student input) { DateMidnight dt = new DateMidnight() .withMillis(input.getBirthDate()) .plusYears(age); if (dt.isBeforeNow()) { return true; } return false; }};
  • 29. No i już w ogóle ślicznieprotected Student[] getStudents(Predicate<Student> predicate) { Iterable<Student> students = Iterables .filter(Arrays.asList(lecture.getStudents()), predicate); return Iterables.toArray(students, Student.class);}
  • 30. Jak już jest prawie funkcyjnie...Student[] students = service.promoteStudents(2);Predicate<Student> predicate = new Predicate<Student>() { public boolean apply(Student input) { if (input.getYear() == year) { return true; } return false; }};Function<Student,Student> function = new Function<Student,Student>(){ public Student apply(Student input) { input.setYear(year + 1); return input; }};Iterables.filter();Iterables.transform();
  • 31. nie tylko <generics> © Kevin Bourrillion, Google, Inc.
  • 32. kiedyś było tak...private Map<Student, List<Lecture>> classes = new HashMap<Student, List<Lecture>>();// ...for (Lecture lecture : lectures) { for (Student student : lecture.getStudents()) { if (service.classes.containsKey(student)) { service.classes.get(student).add(lecture); } else { List<Lecture> l = new ArrayList<Lecture>(); l.add(lecture); service.classes.put(student, l); } }}
  • 33. ... a teraz witamy Multimap i Multiset private Multimap<Student, Lecture> classes = ArrayListMultimap.create(); // ... for (Lecture lecture : lectures) { for (Student student : lecture.getStudents()) { service.classes.put(student, lecture); } }Map<Student, Collection<Lecture>> map = classes.asMap();Collection<Lecture> lectures = classes.values();Set<Student> students = classes.keySet();for (Map.Entry<Student, Lecture> entry : classes.entries()) {}
  • 34. Multimap i Multiset (2)Map<Student, Collection<Lecture>> map = classes.asMap();"JM" => {"Fizyka", "Chemia", "Matematyka"}, "TD" => {"Chemia", Biologia"}Collection<Lecture> lectures = classes.values();{"Fizyka", "Matematyka", "Chemia", "Biologia"}Set<Student> students = classes.keySet();{"JM", "TD"}for (Map.Entry<Student, Lecture> entry : classes.entries()) {}{"JM"=>"Fizyka", "JM"=>"Matematyka", "JM"=>"Chemia", "TD"=>"Biologia", ...}Collection<Lecture> lectures = classes.get("JM");{"Fizyka", "Chemia", "Matematyka"}
  • 35. ImmutabilityImmutableSet<Student> students = ImmutableSet.copyOf(service.getStudentsByYear(2));Set<Student> students = Collections.unmodifiableSet( new LinkedHashSet<Student>( Arrays.asList(service.getStudentsByYear(2))));
  • 36. Immutability with buildersnew Person("Ridge", "Forrster");Person person = new Person.Builder() .withName(“Ridge”) .withSurname(“Forrester”) .build();
  • 37. Dziękuje http://marchwicki.pl/blog @kubamarchwickihttp://www.delicious.com/kuba.marchwicki/beautifulcodehttp://www.assembla.com/code/km_jug/subversion/nodes