O klasycznej programistycznej elegancji
http://my.opera.com/rato53/albums/
Jakub Marchwicki
Technical Consultant
Java, Lua, PHP
i tak od 9lat
marchwicki.pl/blog
@kubamarchwicki
Kanon piękna?
© vitra
Kanon piękna?
„Any fool can
write code that a
computer can
understand. Good
programmers
write code that
humans can
understand“
Refactori...
Martin Fowler jeszcze raz
Joshua Bloch
Effective Java
I sure wish I had
this book ten
years ago
James Gosling
Kent Beck
„Many people
don’t realize how
readable code
can be and how
valuable that
readability is.
Kent has taught
me so....
Implementation patterns
Communication
Simplicity
Flexibility
A wszystko dlatego że
największym kosztem
oprogramowania
będz...
Kryteria dobrego kodu
© http://www.agileadvisor.com/
private static boolean isOlderExtremeVersion(String d1, String d2) {
String[] dateOneA = dateOne.split("-");
String[] date...
public class Person {
private String firstName;
private String lastName;
private long birthDate;
}
public class Student ex...
public boolean equals(Object o) {
if (!(o instanceof Person))
return false;
final Person p = (Person) o;
return firstName....
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(specjalities);
ret...
public String toString() {
return "Professor [specjalities=" +
Arrays.toString(specjalities) + "]";
}
to samo tyczy się to...
public boolean equals(Object o) {
if (o == null) { return false; }
if (o == this) { return true; }
if (o.getClass() != get...
public boolean equals(Object o) {
if (o instanceof Lecture) {
Lecture l = (Lecture) o;
return Objects.equal(professor, l.p...
public void addLectureWithCommons(Lecture lecture, Venue venue,
int dayOfTheWeek, int hour) {
Validate.isTrue(dayOfTheWeek...
String[] csv;
for (String line : csv) {
String[] elements = line.split(",");
// reminder omitted
}
for (String line : csv)...
public interface LectureService {
public Student[] getStudentsByYear(int year);
public Student[] getStudentsOlderThan(int ...
public Student[] getStudentsByYear(int year) {
final List<Student> students = new ArrayList<Student>();
for (Student s : l...
public Student[] getStudentsByBirthDate(Date date) {
final List<Student> students = new ArrayList<Student>();
for (Student...
public Student[] getStudentsOlderThan(int age) {
final List<Student> students = new ArrayList<Student>();
for (Student s :...
public Student[] getStudentsOlderThan(int age) {
final List<Student> students = new ArrayList<Student>();
for (Student s :...
private Student[] getStudents(Predicate predicate) {
final List<Student> students = new ArrayList<Student>();
for (Student...
Predicate predicate = new Predicate() {
@Override
public boolean evaluate(Object arg0) {
if (arg0 instanceof Student) {
St...
Predicate<Student> predicate = new Predicate<Student>() {
@Override
public boolean apply(Student input) {
DateMidnight dt ...
private Student[] getStudents(Predicate predicate) {
final List<Student> students = new ArrayList<Student>();
for (Student...
protected Student[] getStudents(Predicate<Student> predicate) {
Iterable<Student> students = Iterables
.filter(Arrays.asLi...
Student[] students = service.promoteStudents(2);
Predicate<Student> predicate = new Predicate<Student>() {
public boolean ...
Guava to nie tylko <generics>
© Kevin Bourrillion, Google, Inc.
private Map<Student, List<Lecture>> classes =
new HashMap<Student, List<Lecture>>();
// ...
for (Lecture lecture : lecture...
private Multimap<Student, Lecture> classes =
ArrayListMultimap.create();
// ...
for (Lecture lecture : lectures) {
for (St...
Map<Student, Collection<Lecture>> map = classes.asMap();
"JM" => {"Fizyka", "Chemia", "Matematyka"}, "TD" => {"Chemia", Bi...
ImmutableSet<Student> students =
ImmutableSet.copyOf(service.getStudentsByYear(2));
Set<Student> students =
Collections.un...
new Person("Ridge", "Forrster");
Person person = new Person.Builder()
.withName(“Ridge”)
.withSurname(“Forrester”)
.build(...
Dziękuje
http://marchwicki.pl/blog
@kubamarchwicki
http://www.delicious.com/kuba.marchwicki/beautifulcode
http://www.assem...
Upcoming SlideShare
Loading in...5
×

[PL] O klasycznej, programistycznej elegancji

805

Published on

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
805
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

[PL] O klasycznej, programistycznej elegancji

  1. 1. O klasycznej programistycznej elegancji http://my.opera.com/rato53/albums/
  2. 2. Jakub Marchwicki Technical Consultant Java, Lua, PHP i tak od 9lat marchwicki.pl/blog @kubamarchwicki
  3. 3. Kanon piękna? © vitra
  4. 4. Kanon piękna?
  5. 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. 6. Martin Fowler jeszcze raz
  7. 7. Joshua Bloch
  8. 8. Effective Java I sure wish I had this book ten years ago James Gosling
  9. 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. 10. Implementation patterns Communication Simplicity Flexibility A wszystko dlatego że największym kosztem oprogramowania będzie i tak jego utrzymanie
  11. 11. Kryteria dobrego kodu © http://www.agileadvisor.com/
  12. 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. 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. 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. 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. 16. public String toString() { return "Professor [specjalities=" + Arrays.toString(specjalities) + "]"; } to samo tyczy się toString()'a
  17. 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. 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. 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. 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. 21. public interface LectureService { public Student[] getStudentsByYear(int year); public Student[] getStudentsOlderThan(int age); public Student[] getStudentsByBirthDate(Date date); } i kilka operacji 'biznesowych'
  22. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 32. Guava to nie tylko <generics> © Kevin Bourrillion, Google, Inc.
  33. 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. 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. 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. 36. ImmutableSet<Student> students = ImmutableSet.copyOf(service.getStudentsByYear(2)); Set<Student> students = Collections.unmodifiableSet( new LinkedHashSet<Student>( Arrays.asList(service.getStudentsByYear(2)))); Immutability
  37. 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. 38. Dziękuje http://marchwicki.pl/blog @kubamarchwicki http://www.delicious.com/kuba.marchwicki/beautifulcode http://www.assembla.com/code/km_jug/subversion/nodes
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×