Your SlideShare is downloading. ×
0
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
[PL] O klasycznej, programistycznej elegancji
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

[PL] O klasycznej, programistycznej elegancji

783

Published on

This presentation is only in Polish. …

This presentation is only in Polish.

Slajdy z prezentacji grupy JUG, 25 listopada 2010

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
783
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. O klasycznej programistycznej elegancji http://my.opera.com/rato53/albums/
  • 2. Jakub Marchwicki Technical Consultant Java, Lua, PHP i tak od 9lat marchwicki.pl/blog @kubamarchwicki
  • 3. Kanon piękna? © vitra
  • 4. Kanon piękna?
  • 5. „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
  • 6. Martin Fowler jeszcze raz
  • 7. Joshua Bloch
  • 8. Effective Java I sure wish I had this book ten years ago James Gosling
  • 9. Kent Beck „Many people don’t realize how readable code can be and how valuable that readability is. Kent has taught me so...“ Martin Fowler
  • 10. Implementation patterns Communication Simplicity Flexibility A wszystko dlatego że największym kosztem oprogramowania będzie i tak jego utrzymanie
  • 11. Kryteria dobrego kodu © http://www.agileadvisor.com/
  • 12. 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; } Nie będzie Eclipsa...
  • 13. 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; } Wyobraźmy sobie model...
  • 14. 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; } A teraz piszemy...
  • 15. 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; } lub generujemy...
  • 16. public String toString() { return "Professor [specjalities=" + Arrays.toString(specjalities) + "]"; } to samo tyczy się toString()'a
  • 17. 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(); } ale przy setce encji się nie chcieć
  • 18. public 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(); } albo mniej fundamentalnie
  • 19. public 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 } defensive programming
  • 20. String[] 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); } a później zawsze trafimy na String'a
  • 21. public interface LectureService { public Student[] getStudentsByYear(int year); public Student[] getStudentsOlderThan(int age); public Student[] getStudentsByBirthDate(Date date); } i kilka operacji 'biznesowych'
  • 22. 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[] {}); } które sprowadzają się...
  • 23. 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[] {}); } ... do niemal ...
  • 24. 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[] {}); } ... tego samego.
  • 25. public 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[] {}); } i abstahując od użycia JodaTime
  • 26. private 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[] {}); } Don't Repeat Yourself
  • 27. 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; } }; No a ten predykat?
  • 28. 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; } }; No a ten predykat? (2)
  • 29. private 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[] {}); } i jeszcze na koniec, zamiast...
  • 30. protected Student[] getStudents(Predicate<Student> predicate) { Iterable<Student> students = Iterables .filter(Arrays.asList(lecture.getStudents()), predicate); return Iterables.toArray(students, Student.class); } ... może być w ogóle ślicznie
  • 31. 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(); Jak już jest prawie funkcyjnie...
  • 32. Guava to nie tylko <generics> © Kevin Bourrillion, Google, Inc.
  • 33. 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); } } } kiedyś było tak...
  • 34. 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()) {} ... a teraz witamy Multimap i Multiset
  • 35. 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"} Multimap i Multiset (2)
  • 36. ImmutableSet<Student> students = ImmutableSet.copyOf(service.getStudentsByYear(2)); Set<Student> students = Collections.unmodifiableSet( new LinkedHashSet<Student>( Arrays.asList(service.getStudentsByYear(2)))); Immutability
  • 37. new Person("Ridge", "Forrster"); Person person = new Person.Builder() .withName(“Ridge”) .withSurname(“Forrester”) .build(); Immutability with builders http://www.marchwicki.pl/blog/2010/11/building-a-pojo-in-an-elegant-way/
  • 38. Dziękuje http://marchwicki.pl/blog @kubamarchwicki http://www.delicious.com/kuba.marchwicki/beautifulcode http://www.assembla.com/code/km_jug/subversion/nodes

×