Jako opiekun praktyk, stażów, mentor młodszych kolegów i koleżanek z zespołu, osoba odpowiedzialna za rekrutację techniczną, a także programista, który każdego dnia pracuje z oprogramowaniem dane mi było widzieć wiele błędów, złych zachowań i pomyłek w podejściu do tworzenia czystego kodu. Chciałbym się z Wami podzielić tymi najczęstszymi wpadkami w pracy z językiem Java. To nie będzie zwyczajna pogawędka! Zobaczycie kod źródłowy i ostry refaktoring. Zobaczycie, jak proste zmiany i lepsze zrozumienie samego języka mogą poprawić wydajność i czytelność Waszych aplikacji. Na podstawie całkiem prostych fragmentów kodu pokażę, na co zwrócić uwagę, żeby - to zabrzmi banalnie - być lepszym. Prezentacja dla wszystkich, którzy są na początku (i nie tylko) wspaniałej przygody z programowaniem (i zawrotnej kariery!).
9. final class Book {
private String name;
private String isbn;
private Collection<String> authors;
public Book(String name,
String isbn,
Collection<String> authors) {
this.name = name;
this.isbn = isbn;
this.authors = authors;
}
// getters
}
10. final class Book {
final private String name;
final private String isbn;
final private Collection<String> authors;
public Book(String name,
String isbn,
Collection<String> authors) {
this.name = name;
this.isbn = isbn;
this.authors = authors;
}
// getters
}
11. List<String> author = new ArrayList<>();
author.add("J.R.R. Tolkien");
Book lotr = new Book(
"Lord of the rings",
"9780007117116",
author
);
lotr.getAuthors().add("Daniel Pokusa"); // HAHA! Hacked!
12. final class Book {
private final String name;
private final String isbn;
private final Collection<String> authors;
public Book(String name,
String isbn,
Collection<String> authors) {
this.name = name;
this.isbn = isbn;
this.authors = new ArrayList<>(authors);
}
public Collection<String> getAuthors() {
return Collections.unmodifiableCollection(authors);
}
// other getters
13. final class Book {
private final String name;
private final String isbn;
private final Collection<String> authors;
public Book(String name,
String isbn,
Collection<String> authors) {
this.name = name;
this.isbn = isbn;
this.authors = new ArrayList<>(authors);
}
public Collection<String> getAuthors() {
return Collections.unmodifiableCollection(authors);
}
// other getters
14. final class Book {
private final String name;
private final String isbn;
private final Collection<String> authors;
public Book(String name,
String isbn,
Collection<String> authors) {
this.name = name;
this.isbn = isbn;
this.authors = new ArrayList<>(authors);
}
public Collection<String> getAuthors() {
return unmodifiableCollection(authors);
}
// other getters
34. public int calculateFriendsQuantityFor(Person person);
public boolean isPopular(Person person) {
return calculateFriendsQuantityFor(person)
> MIN_FRIENDS_QUANTITY_FOR_POPULAR_PERSONS;
}
35. public int calculateFriendsQuantityFor(Person person);
public boolean isPopular(Person person) {
return calculateFriendsQuantityFor(person)
> MIN_FRIENDS_QUANTITY_FOR_POPULAR_PERSONS;
}
public static final int
MIN_FRIENDS_QUANTITY_FOR_POPULAR_PERSONS = 50;
37. I will take it! I will take the Ring to Mordor. Though… I do not know the way.
- Frodo
38. public class ShoppingBag {
public Collection<Item> items = new ArrayList<>();
public static final BigDecimal MULTI_DISCOUNT = new BigDecimal(0.2); // 20%
public static final BigDecimal OVERAL_DISCOUNT = new BigDecimal(0.1); // 10%
public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = (int) (item.getQuantity() / 2);
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (r.getFinalPrice().compareTo(new BigDecimal(100)) > 0) {
r.addPosition(new Item("Overall discount", r.getFinalPrice().multiply(OVERAL_DISCOUNT).negate(), 1));
}
saveReceipt(r);
return r;
}
// Other methods
}
39. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = (int) (item.getQuantity() / 2);
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (r.getFinalPrice().compareTo(new BigDecimal(100)) > 0) {
r.addPosition(new Item("Overall discount", r.getFinalPrice().multiply(OVERAL_DISCOUNT).negate(), 1));
}
saveReceipt(r);
return r;
}
40. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = (int) (item.getQuantity() / 2);
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (isOverallDiscountAwarded(r.getFinalPrice())) {
r.addPosition(new Item("Overall discount", r.getFinalPrice().multiply(OVERAL_DISCOUNT).negate(), 1));
}
saveReceipt(r);
return r;
}
41. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = getNumberOfMultiDiscountsPromotionsFor(item.getQuantity());
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (isOverallDiscountAwarded(r.getFinalPrice())) {
r.addPosition(new Item("Overall discount", r.getFinalPrice().multiply(OVERAL_DISCOUNT).negate(), 1));
}
saveReceipt(r);
return r;
}
42. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = getNumberOfMultiDiscountsPromotionsFor(item.getQuantity());
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (isOverallDiscountAwarded(r.getFinalPrice())) {
r.addPosition(new Item("Overall discount", r.getFinalPrice().multiply(OVERAL_DISCOUNT).negate(), 1));
}
return r;
}
43. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = getNumberOfMultiDiscountsPromotionsFor(item.getQuantity());
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (isOverallDiscountAwarded(r.getFinalPrice())) {
r.addPosition(getOveralDiscountFor(r.getFinalPrice()));
}
return r;
}
44. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = getNumberOfMultiDiscountsPromotionsFor(item.getQuantity());
if (promotions > 0) {
r.addPosition(getMultiDiscountFor(item.getPrice(), promotions)));
}
}
if (isOverallDiscountAwarded(r.getFinalPrice())) {
r.addPosition(getOverallDiscountFor(r.getFinalPrice()));
}
return r;
}
45. public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = getNumberOfMultiDiscountsPromotionsFor(item.getQuantity());
if (promotions > 0) {
r.addPosition(getMultiDiscountFor(item.getPrice(), promotions)));
}
}
if (isOverallDiscountAwarded(r.getFinalPrice())) {
r.addPosition(getOverallDiscountFor(r.getFinalPrice()));
}
return r;
}
51. public class ShoppingBag {
public Collection<Item> items = new ArrayList<>();
public static final BigDecimal MULTI_DISCOUNT = new BigDecimal(0.2); // 20%
public static final BigDecimal OVERAL_DISCOUNT = new BigDecimal(0.1); // 10%
public Receipt calculate() {
Receipt r = new Receipt();
for (Item item : items) {
r.addPosition(item);
int promotions = (int) (item.getQuantity() / 2);
if (promotions > 0) {
r.addPosition(new Item("More than one promotion!", item.getPrice().multiply(MULTI_DISCOUNT).negate(),
promotions));
}
}
if (r.getFinalPrice().compareTo(new BigDecimal(100)) > 0) {
r.addPosition(new Item("Overall discount", r.getFinalPrice().multiply(OVERAL_DISCOUNT).negate(), 1));
}
saveReceipt(r);
return r;
}
// Other methods
}
55. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
56. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
57. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
● Pamiętaj o regule Demeter
58. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
● Pamiętaj o regule Demeter
● Nazewnictwo jest bardzo ważne
59. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
●Pamiętaj o regule Demeter
● Nazewnictwo jest bardzo ważne
● SOLID, ale zacznij od porządnego zrozumienia SRP :)
60. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
●Pamiętaj o regule Demeter
● Nazewnictwo jest bardzo ważne
● SOLID, ale zacznij od porządnego zrozumienia SRP :)
● Jeśli korzystasz z jakiegoś frameworka- spróbuj zrozumieć jego
podstawowe mechanizmy
● Pisz testy.
● Programuj tak jakby Code Review mał zrobić Ci socjopata, który zna
Twój adres domowy :)
61. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
●Pamiętaj o regule Demeter
● Nazewnictwo jest bardzo ważne
● SOLID, ale zacznij od porządnego zrozumienia SRP :)
● Jeśli korzystasz z jakiegoś frameworka- spróbuj zrozumieć jego
podstawowe mechanizmy
62. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
●Pamiętaj o regule Demeter
● Nazewnictwo jest bardzo ważne
● SOLID, ale zacznij od porządnego zrozumienia SRP :)
● Jeśli korzystasz z jakiegoś frameworka- spróbuj zrozumieć jego
podstawowe mechanizmy
● Pisz testy.
63. ● NIE ignoruj podstaw języka
● Zrozum istotę klas niemodyfikowalnych i klas wartości
● Znaj przynajmniej podstawy GC
●Pamiętaj o regule Demeter
● Nazewnictwo jest bardzo ważne
● SOLID, ale zacznij od porządnego zrozumienia SRP :)
● Jeśli korzystasz z jakiegoś frameworka- spróbuj zrozumieć jego
podstawowe mechanizmy
● Pisz testy.
● Programuj tak jakby Code Review mał zrobić Ci socjopata, który zna
Twój adres domowy :)