GET.NET - Osiołkowi w żłobie dano, czyli o tym jak hostować aplikacje na Mic...
university day 1
1. Who am I ?
Name : Sławek Borowiec
Solution Architect & java frameworks trainer
Since 2005 – until now
@przodownikR1
Blog: http://przewidywalna-java.blogspot.com
Hobby : Sport bikes & boxing & software
engineering
2. Agenda
Miękkie wprowadzenie do zasad dobrego programowania.
Wstęp do efektywnego programowania w Javie
Omówienie podstawowych narzędzi środowiska
developerskiego jak i narzędzie poprawiających jakość i
efektywność kodowania
Konfiguracja środowisk ciągłej integracji
Omówienie wybranych wzorców projektowych,
architektonicznych oraz dobrych praktyk.
5. Efektywne wytwarzanie aplikacji
internetowych
Zaprojektowanie i omówienie warstw :
- danych (Entity, Domain Objects)
- dostępu do danych (DAO)
- serwisów biznesowych (Transaction)
- web (MVC)
Aspekty bezpieczeństwa (Security)
Wprowadzenie do testowania
Prototypowanie
AOP
8. Mój wybór
Ubuntu - bo uważam , że wiele rzeczy mogę zrobić szybko i łatwo. → Shell też jest dużo lepszy niż konsola
windows (teraz używam fish'a) wcześniej był to bash .
STS - bo używam springa a jednocześnie mam spore doświadczenie w eclipsie. → Poza tym ma Insight +
tcServer - a to już sporo daje :)
Gradle + Maven - frameworki Spring czy Hibernate.
Jenkins - bo po prostu jest najlepszy ;)
Nexus - tu wybór był również nie duży . Ale jestem przekonany do Nexusa bardziej niż do Artifactory.
GIT - bez dyskusyjne jest najlepszy z pośród VCS . W szczególności jak robisz dużo branch'y i merge'y. Jak
daje radę z jądrem linuxa to tym bardziej da radę z moimi wypocinami.
●
W STS używam eGit dla mnie jest jak najbardziej ok . Używam go głównie do przeglądania różnic podczas
operacji merge. Z konsoli wystarcza mi git + czasem odpalam gitk.
● Sonar - chce wiedzieć przynajmniej poglądowo jak wygląda od strony QA mój kod .
●
JMeter , Grinder - testuje sobie wydajność
●
SoapUI - testuje WS i REST , w pewnym sensie też JMeter to potrafi.
●
Gerrit - to jest w trakcie testów . W każdym razie jest to code review tool.
●
Scala - w trybie REPL ( programowanie eksperymentami)
● JVISUALVM dawniej visualvm - monitoring JVM
● JConsole - monitoring JVM
●
Jstat , Jmap , Jhat - używam do wykrywania problemów wydajności
●
Selenium - testy UAT
●
Luke - indeksy lucene
● Portecle - generacja i zarządzanie kluczami i cerfyfikatami
● RestClient-UI - testowanie dla REST
●
Swagger – REST API CLIENT
13. Cele ?
Wykorzystać język Java do granic możliwości.
Nie zamykać się na inne technologie i
rozwiązania.
Szybkie wytwarzanie softu.
Jakość.
Utrzymanie.
Minimalizacja błędów.
14. Założenia ?
Poznać metody i praktyki skutecznego
wytwarzania.
Dobrać odpowiednie narzędzia.
Wybrać technologie.
Rozwój zawodowy.
Pieniądze i statysfakcja z pracy.
15. Wiedza ?
Rzetelna ocena swoich umiejętności.
Zdobywanie doświadczenia.
Uczenie się na błędach innych.
Komfort psychiczny.
Elastyczność.
17. Java 1.5 – 1.8
Java 5
Generics, AutoBoxing, Enum , Executors - new language feature
Java 7
String w wyrażeniu switch - new language feature
Podkreślenia w cyfrach ułatwiające czytelność - Syntactic sugar
long debitCard = 1222_5648_68758_7332L;
float amount = 2_450F;
byte b = (byte)0b10_111_110;
Try-with-resources – ulepszenie obsługi sytuacji wyjątkowych
oraz łatwiejsza obsługa zasobów (AutoCloseable) - new language feature
Multiple exception - new language feature
Join/Fork - new language feature
Re-throwing exceptions
The diamond operator - Syntactic sugar
Invokedynamic - JVM feature
Java 8
... Date & Time API, Lambda, Stream, usunięcie PermGen
19. Manifest Agile source:blog.kiandra.com.au
Ludzi i interakcje ponad procesy i narzędzia.
Działające oprogramowanie ponad obszerną dokumentację.
Współpracę z klientem ponad formalne ustalenia.
Reagowanie na zmiany ponad podążanie za planem.
21. Manifest Craftsmanship
1. Nie tylko działające oprogramowanie, ale
również dobrze napisane oprogramowanie
2. Nie tylko reagowanie na zmiany, ale również
ciągłe zwiększanie wartości
3. Nie tylko osoby i interakcje, ale również
społeczność profesjonalistów
4. Nie tylko współpraca z klientem, ale również
produktywne partnerstwo
26. XP
- eliminacja wielkiego projektowania na samym
początku prac nad systemem
- kodujemy najbardziej potrzebne funkcje
- elastyczne zmiany
-kodowanie w parach to poprawienie
kreatywności oraz skupienie się na ciężkich
problemach
28. Pragmatyzm
Cechy pragmatycznego programisty :
- odwaga (do przyznania się do popełnionych błędów)
- branie odpowiedzialności na siebie
- proponowanie rozwiązań, zamiast kiepskich wymówek
- nie akceptowanie wybitej szyby
- śmiałe propozycje ulepszeń
- inwestowanie w wiedzę
- krytyczne myślenie
- dociekliwość
- gotowość do nowych wyzwań
Link : http://przewidywalna-java.blogspot.com/2014/01/pragmatyzm-wedug-mnie-czesc-
1.html
33. CI – Continous Integration
Jenkins, Bamboo, Team City etc
Instalacja
Konfiguracja
Wykorzystanie
Zastosowanie
Dobre praktyki
34. Continuous Integration
CI jest to technika służąca ochronie i poprawie
pracy nad projektem. Pomaga usprawnić
proces wytwarzania i czyni ten proces mniej
ryzykownym i bardziej przejrzystym oraz
większa higienę w projekcie. Ciągłe łączenie
zmian wprowadzanych przez różne osoby w
projekcie to również CI.
36. CI
Nie stosowanie dobrych praktyk CI i CD skutkuje
zjawiskiem zwanym piekłem integracji (integration hell)
czyli co może pójść niezgodnie z przewidywaniami :
- błędy ludzkie
- problemy z komunikacją w zespole
- różnice w środowiskach (np inne wersje JDK czy
przeglądarek)
- błędy i różnice w plikach konfiguracyjnych
37. CI : Cykl życia
- instalacja i konfiguracja
- zdefiniowanie build'u oraz polityki pobierania i kompilacji
- testowanie (unit test , integration test etc)
- raporty oraz metryki
- budowanie paczki
- uruchamianie paczki na serwerze testowym oraz
odpalanie testów UAT
- dostarczanie paczki do klienta (zdalny deploy , sftp , etc)
38. Fowler a CI
Automatyzacja budowy
Samo-testowalność
Każda zmiana w repo skutkuje wyzwoleniem procesu integracji
Częsta synchronizacja z source repo, częste commit'y
Wszyscy wiedzą co się dzieje
build musi być szybki
testowanie w klonie środowiska produkcyjnego
łatwy dostęp do arefaktów
automatyczny deployment
39. Maturity CI
Install & configure
Automated build
Unit & integration test
Reporting & metrics
Distributed Builds
Functional Test
Continuous Delivery
40. CI : Cel 1
Chcemy, żeby nasze build'y były możliwie
szybkie.
- Ograniczamy i selekcjonujemy testy np
poprzez lifecycle procesów z mavena lub
profile.
- Wyznaczymy inną ścieżkę budowy w naszym
CI (rozdzielany buildy)
- Stosujemy pipeline.
41. CI : Cel 2
Chcemy poprawić testowalość (testablility) naszej
aplikacji :
- automatyczne testy (regresja - daje nam
pewność, że wcześniej dostarczona funkcjonalność
nadal działa pomimo wprowadzenia nowych zmian)
- separacja testów
- monitoring czasu wykonywania testów
- monitoring pokrycia testami (test coverage)
42. CI : Cel 3
Skrócenie procesu wytwarzania i czasu wydania release'a
CI sprawia , że prawie przez cały czas dysponujemy działającą
wersją aplikacji, którą możemy pokazać testerom , a potem po
ich akceptacji zmienić wersję z snapshot na release po czym
otagować ją w repozytorium ponownie.
Ewentualne defekty poprawia osoba, które je wprowadziła
ponieważ ma największą wiedzę z dziedziny problemu oraz
kontekstu.
Dostajemy również łatwy dostęp do najnowszego artefaktu, a
także każdego artefaktu historycznego.
43. CI : Cel 4
Zawsze dążymy do automatyzacji, bo proces
ten jest odporny na ludzkie błędy
Pośpiech jest złym doradcą
44. CI : Cel 5
Wsparcie dla zwinnych metodyk wytwarzania
Continuous Delivery (CD) sprawia, że proces wytwarzania staje się
faktycznie i praktycznie procesem zwinnym (agile). Cały cykl iteracyjny
wytwarzania ma odzwierciedlenie CD.
Kompilacja - Testy - Budowanie - (Testy) - Dostarczanie.
Użytkownik końcowy jak i tester są bliżej wprowadzanych zmian i
poprawek niż kiedykolwiek przedtem.
Przez to mają lepszy obraz funkcjonalności i faktycznego postępu co z
kolei definiuje szybki feedback z ich strony.
Klient faktycznie widzi jak z każdą iteracją aplikacji rozwija się co
przekłada się na polepszenie obustronnego zaufania i zaciśnięcie
obustronnej współpracy.
45. CI : Cel 6
Każdy członek zespołu umie wyprodukować produkt końcowy łącznie z
zainstalowaniem go na dedykowanym do tego serwerze.
Poprawa komunikacji (team collaboration) oraz Collective Ownership
(własność wspólna)
Częste commit'y oraz wspólny kod sprzyja manifestowi Agile oraz poprawia
komunikacje w zespole. Nie istnieją "bogowie build'ow" czyli takie osoby,
które jako jedyne są w stanie zbudować i dostarczyć paczkę dla klienta.
Taka wiedza powinna należeć do całego zespołu. Dzięki CI ten proces
obywa się automatycznie (scheduled process) lub na żądanie wystarczy
wcisnąć (play-> tzn build) w jenkinsie.
Wszyscy widzą co się dzieje - (M.Fowler), każdy jest w stanie określić w
jakim stadium znajduje się projekt oraz określić jakie zmiany do niego
wprowadzono.
46. CI : Cel 7
Poprawa jakości wytwarzanego oprogramowania
Podpięcie testów wspomaga przyszły refaktoring. Podpięcie narzędzi do statycznej analizy kody zwiększa higienę kodu,
oraz eliminuje część złych praktyk oraz potencjalnych bug'ów.
Dzięki temu przechodzimy do pojęcia (Continuous inspection) ciągła inspekcja, dzięki której możemy wytwarzać
oprogramowanie lepszej jakości (sonar - timeline)
Definicja polityki pokrycia testami , tu możemy zakończyć proces budowy jeśli okaże się, że pokrycie testów (test
coverage) nie pokrywa np 60% całości. Tak samo działa polityka wykrywania wszelkiego rodzaju nieprawidłowości w
kodzie np : build kończy się niepowodzeniem jeśli system wykrył ponad 20 nowych problemów (issue)
Można zdefiniować repozytorium tzn staging dzięki któremu możemy wprowadzić funkcjonalność typu code review (np
gerrit) co zwiększa kontrolę oraz jeszcze bardziej poprawia jakoś finalnego kodu. Ponieważ kod, który znajdzie się
docelowo we właściwym repozytorium musi być sprawdzony i zatwierdzony przez członka zespołu o największych
umiejętnościach i wiedzy w danej dziedzinie.
Gramy w leader board - czyli stosujemy licznik i wprowadzamy zasady punktacji np : za każdy dobry deploy +1 punkt,
za każde issue +3 punkty , za każdy TODO + 3punkt, za każdy nieudany build -1punkt, za wygenerowanie nowego
issue -3 punkty itd.
CI wspomaga tworzenie soft TDD (Test Driven Development) - piszesz najpierw testy które z początku nie działają, a
podczas budowania cała funkcjonalność musi przejść te testy. (JUnit , TestNG) -> mvn test
BDD (Behavior Driven Development) - zespół opisuje poprzez testy scenariusze i ustala warunki i wynik ich wykonania.
(jbehave, Cucumber) -> mvn verify
47. CI : Cel 8
Mniejszy poziom stresu dla całego zespołu, większa kontrola,
dostarczanie produktu na czas.
Jako podsumowanie naszym poprzednich 7 punktów przychodzi
następująca konkluzja:
- wiedza, że mam większą kontrolę na całością cyklu wytwarzania.
- odpowiednie osoby dostają odpowiednie raporty
- wiedza czy wytwarzanie projektu idzie w dobrym kierunku
- dbanie o higienę kodu - bardziej to CI to na Tobie wymusza
- natychmiastowe dostarczenie nowego produktu
- minimalizacja błędów - wyeliminowanie do min czynnika ludzkiego.
48. CI : konfiguracja
- konfiguracja global properties
- konfiguracja jdk
- konfiguracja jednego z wybranych narzędzi budowy np: maven
- konfiguracja systemu kontroli wersji np: git
- konfiguracja mail serwera do wysyłki wiadomości oraz potencjalnych
odbiorców
- instalacja potrzebnych wtyczek
- dodanie użytkowników oraz uprawnień
- ewentualna konfiguracja proxy
- zdefiniowanie ewentualnych pre, post procesorów
- zdefiniowanie końcowych serwerów
49. CI : best practices
- osobne konta w CI
- wprowadzenie polityki (zarządzanie i konfiguracja oraz dostęp do artefaktów)
- wszechobecne wiki
- polityka archiwizacji build'ów (harmonogram prac konserwacyjnych)
- korzystanie w różnych rodzajów systemów operacyjnych , dzięki czemu można
testy integracyjne lub funkcjonalne na kilku różnych przeglądarkach.
-wirtualizacja CI
-polityka kopii zapasowych artefaktów.(murphy laws , backup plugin)
-monitoring zasobów : pamięć, procesor (javaMelody plugin), oraz wykorzystania dysków (disk usage plugin)
- zdefiniowanie właściwych parametrów MAVEN_OPTS
- przeglądanie logów budowy paczki (Log Parser Plugin) - pozwala nam to między innymi zagregować logi
poziomem błędów.
- plugin do firefox - pozwalający na wgląd w stan aplikacji oraz pokazuje na bieżąco ich status (rss)
- integracja z groovy - pozwala na wykonywanie skryptów .groovy
- automatyczny deploy na zdalne repozytorium z udziałem ustawień znajdujących się w settings.xml mavena.
- slave axis - rozproszenie obciążenia na różne maszyny. Umożliwia stworzenie macierzy rozwiązań tzn
mogę uruchamiać i budować wersją pod różnymi systemami oraz testować na różnych przeglądarkach
(Selenium, UAT test) lub wykorzystać różne instancje baz danych.
- oraz wiele innych ciekawych wtyczek które są opisane tutaj.
50. Sonar
Dzięki sonarowi możemy spojrzeć w głąb naszego kodu,
poznać go, odkryć potencjalne pułapki programistyczne,
sprawdzić jakoś kodu oraz zdobyć wiedzę co jak
programować lepiej.
Dostajemy klasyczne metryki jak :
- linie kodu w projekcie
- udokumentowane API
- złożoność i złożoność cykliczną
- pokrycie oraz statystyki testów
- wykrywanie duplikacji w kodzie
51. Sonar,a siedem grzechów
Duplication
Lack of unit tests
No coding standards
Not enough or too many comments
potencial bugs
spaghetti desing
bad distribution of complexity
59. Sonar
Sprawdzi jakoś projektu i jego architektury (Design and architecture)(Quality,Clean
code)
Kolor czerwony wskazuje na potencjalne problemy cyklomatyczne między pakietami.
Red > Yellow > Green
Najbardziej odpowiedni kolor dla naszego projektu to zielony.Każda zmiana barwy w
stronę czerwonego oznacza kłopoty:)
(np: brak dokumentacji (API) jest oznaczany kolorem czerwonym)
60. Sonar : Complexity
Generalnie complexity określa złożoność kodu. Jest to tak naprawdę ilość ścieżek
którymi może przejść proces w kodzie.
Co to znaczy dla programisty? Jeśli złożoność wynosi np 4 to obowiązkiem
programisty jest przetestować potencjalnie każdą z nich oznacza to cztery testy
jednostkowe.
Ponadto zajmuje czas developera potrzebny do zrozumienia kodu oraz powoduje
pewien rodzaje regresji gdyż jak wyżej napisałem istnieje wiele możliwych ścieżek
przejścia danego procesu - przez co testowanie jest bardziej skomplikowane.
Keywords incrementing the complexity: if, for, while, case, catch, throw, return (that is
not the last statement of a method), &&, ||, ?
Notes:
else, default, and finally keywords do not increment the complexity.
a simple method with a switch statement and a huge block of case statements
can have a surprisingly high complexity value (still it has the same value when
converting a switch block to an equivalent sequence of if statements).
accessors are not considered as methods and so do not increment the
complexity
62. Sonar : RFC
RFC stands for Response For Class.
Oblicza złożoność klas w odniesieniu do metod.
I tak:
+1 dla każdej metody w klasie
+1 dla odwołania każdej metody w obrębie
zasobu (getter i setter nie jest brany pod uwagę)
63. Sonar : LCOM4
LCOM4 - sprawdza czy nie tworzymy klasy
która ma za dużą odpowiedzialność.
(solid - SRP). Pozwala określić nam czy
możemy rozbić klasę na n.. innych czyli rozbić
funkcjonalność.
64. Sonar : tags
Quick wins:
Font size: wszystkie linie kodu
Color: pokrycie testami ; czerwony (0 procent) do niebieskiego (100 procent)
Top risk :
Font size: średnia złożoność na metodę
Color: Pokrycie kodu testami; -> czerwony (0 procent) do niebieskiego (100 procent)
Clouds
Pokazuje w formie tagów klasy czy komponenty systemu.
Obrazuje w ten sposób ich pokrycie testami i naruszenia polityki kontroli jakości (Rules compliance).
Tak naprawdę dostaje cztery wymiary danych :
Coverage: kolor jest bardziej czerwony gdy pokrycie testami jest marne:)
Rules Compliance: kolor jest bardziej czerwony gdy naruszeń jest więcej
Quick wins: wielkość czcionki jest proporcjonalny do linii kodu
Top Risk: wielkość czcionki jest proporcjonalny do złożoności
65. Sonar : Best practices
- używaj filtrów do filtrowania interesujących Cię statystyk czy metryk.
- skomponuj swój własny dashboard - pokaż rzeczy które naprawdę są
dla Ciebie ważne w projekcie
- utwórz swoje własne reguły (own violations create)
- zainstaluj plugin sonara do swojego IDE (eclipse taki posiada)
- włącz powiadomienia
- włącz automatyczne alerty
- technical dept - określ współczynniki dla kosztów refaktoringu
- Useless Code Tracker plugin - wykrywany nieużywany kod
- pełna integracja z CI (jenkins, sonar plugin)
66. Clean code ~ Uncle Bob
- Czytanie a rozumienie kodu = tracony czas
Impakt na :
- koszty utrzymania,
- niezadowolenie deweloperów
- znaczne zwolnienie tempa rozwoju projektu
- Standaryzacja kodu : ide , eclipse , sonar , narzędzia statycznej analizy
- formatowanie kodu
- native2Ascii
- utf8 properties files
- analiza statyczna wyszukiwanie antipatterns.
- pokrycie testami , pittest , etc
68. Ciągła refaktoryzacja
- zatrzymaj się i coś popraw
- testuj - refaktoring wymaga testów
- pokusa refaktoringu wszyskiego
- zasada małych kroków
- nowa technologia nie musi być impulsem do zmian i
refaktoryzacji
- nieintuicyjne nazywanie zmiennych i metod
69. Clean code
Zasada skauta
-pozostaw kod lepszym miż go zastaleś
Kod jest własnością wszystkich
Bądź katalizatorem zmian
Nie toleruj wybitych okien
Testuj swój kod i nie obwiniaj innych
Code review - collective code ownership - gerit - raz na tydzien
- współdzielenie wiedzy
- dostęp nowicjuszy do procesów code review
70. Clean code
dziel kod na części
unikaj goto
unikaj używania globalnych zmiennych
czy naprawdę programujesz obiektowo?
projektuj zanim zaczniesz kodować
twórz obiekty niezmienne -> gc , tread-safe
minimalizuj zakresy zmiennych - > gc
preferuj kod samodokumentujący się
jeśli potrzebujesz zagnieżdżenia wybierz funkcję
funkcje powinny być możliwe jak najkrótsze
funkcje powinny mieć możliwie mało parametrów -> wrapper jeśli > 4
kod zorientowany na 1 odpowiedzialność -> SRP
komentarze w większości przypadków są zbędne - utrzymanie, out-of- date etc
intuicyjne nazwy bytów
71. Ciągła nauka
Bieda architektowi, który zaprzestał
wytwarzania kodu....
Bieda programistom, którzy zaprzestali się
uczyć nowych języków
Bieda projektantom, którzy przestali się uczyć
nowych technik i rozwiązań
Bieda PM, którzy nie śledzą nowych metodyk
wytwarzania
72. Bądź pragmatyczny
ciągła nauka
książki, blogi, tweety, mentoring, virtual mentors
zrozum jak działa biblioteka czy framework
zrozum przyczynę problemu nawet jeśli poprawiłeś błąd
konferencje i warsztaty
pragmatic programmers !!
Technologia szybko ewaluuje, jeśli zostaniesz w tyle ciężko będzie Ci powrócić
wszechobecna automatyzacja : maven , gradle , bash , CI
magia nie istnieje - jak coś raz nie zadziało to za drugim razem też nie będzie lepiej
DRY - twórz abstrakcje i metody template'owe jak i klasy.
- OCP SRP, abstract factory czy factory method
- użyj Strategy pattern zamiast bloków if-then
- AOP
- prostota , utrzymanie , jakość
- pociski smugowe : logowanie, CI
- buduj prototypy → Spring Boot
73. Lombok
Boilerplate code – powtarzający się kod w wielu
miejscach, nie wprowadzający znaczących
zmian w logice aplikacji. Często zaciemniający
prawdziwy cel czy zamierzenie programisty.
Można go zredukować stosując wzorce
projektowe, AOP, generatory kod etc.
75. Grasp
General Responsibility Assignment Software Patterns
- Creator – kiedy obiekt obligowany jest do utworzenia nowego obiektu ? (kompozycja, używanie,
posiadanie danych, zapisywanie). Uzyskiwany efekt dzięki wykorzystaniu fabryk , metod fabrykujących
czy LC.
- Information Expert – ustalamy odpowiedzialność obiektu (wygrywa obiekt , który ma najwięcej
potrzebny informacji w momencie decyzji o delegacji) (LC i HC)
- Controller - oddzielenie warst (mvc) (Command, Facade, LC i HC)
- Polymorphism – zachowania polimorficzne pozwalają ograniczyć bloki if-else
- Low Coupling – nowa funkcjonalność łatwa do wprowadzenia , projektuj klasy możliwie jak najmniej
zależne od siebie. Wprowadzana zmiana przełoży się do edycji w możliwie najmniejszym skrawku
Twojego kodu.
- High Cohesion – ograniczenie odpowiedzialności obiektu SRP
- Pure Fabrication – problem przydzielania odpowiedzialności aby nie naruszyć zasad HC i LC. (DAO)
- Indirection – podjęcie decyzji o przydzieleniu zobowiązania w oderwaniu od bezpośredniego
powiązania między dwoma bytami (wprowadzenie obiektu pośredniczącego jak : Facade, Adapter,
Observer). Unikanie HC przez zastosowanie jakiegoś pośrednika.
- Protected Variation – problem projektowania obiektów , aby te nie wywierały wpływu na inne
elementy systemu. Stosowanie stabilnych interfejsów
77. Zasady którymi powinieneś
się kierować
Preferuj kompozycję zamiast dziedziczenia.
Dziedziczenie prowadzi często do przypadku
ułomnej klasy bazowej.
Wszechobecna hermetyzacja – jako zarodek
klas szablonowych i fabryk.
Abstrakcja jest dobra.
78. Guava
Ko -
lum n a
1
Ko -
lum n a
2
Ko -
lum n a
3
Static Imports
Eliminacja boilerplate code
Minimalizacja kodu
Wydajność i efektywność
Niezmienność
Kodowanie defensywne
Wprowadzenie do programowania funkcyjnego
79. Joda Time
Łatwość użycia API
Dokumentacja
Lepsza wydajność
Immutable
Strefy czasowe
Lepsza funkcjonalność
80. Joda Time vs Date & Time
Date i Calendar :
- słaba wydajność;
- skomplikowane, niewygodne operowanie czasem i datą;
- problematyczne wyliczanie czasu pomiędzy dwoma zadanymi
okresami
- ! thread-safe
- miesiące zaczynają się od 0
- brak możliwości reprezentacji czasu w oderwaniu od strefy
czasowej;
- brak obiektowej reprezentacji takich pojęć jak okres, odstęp czasu,
czas trwania
81. Joda Time
Każdy tworzony obiekt jest (thread-safe) niezmienny
Proste tworzenie konkretnej daty
DateTime dt = new DateTime(2013,3,8,12,0); //2013-03-08 12:00
zamiana obiektów JodaTime w Date i na odwrót :
Date myDate = dt.toDate();
dt = new DateTime(myDate);
Żeby pobrać z obiektu Date konkretny składnik daty musieliśmy tworzyć obiekt
Calendar (tu problem z numerowaniem np. miesiące zaczynają się od 0) dostęp był
przez parametr int
w JodaTime wygląda to następująco np. :
dt.getMonthOfYear() , dt.getDayOfYear(), dt.getHourOfDay()
82. Joda Time
Prosta modyfikacja daty
np. dodanie dnia dt.plusDay(1) , dt.plusMinutes(10)
Formatowanie:
dt.toString("yyyy-MM-dd");
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss");
formatter.print(dt);
String strDateTime = "01.12.2012";
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd.MM.yyyy");
DateTime dateTime = formatter.parseDateTime(strDateTime);
System.out.println(strDateTime);
System.out.println(ISODateTimeFormat.yearMonthDay().print(dateTime));
Wynik :
01.12.2012
2012-12-01
85. Logging levels
Trace – najniższy poziom (! production)
Debug – tryb deweloperski
Info – informacja o jakiś zdarzeniu
Warn – może oznaczać problem
Error – raczej jest niedobrze, często wymaga
interwencji programisty. Kwalifikuje się do
działań supportowych.
86. Exception
Wyjątki powstały do obsługi sytuacji wyjątkowych. Tworzenie,
zgłaszanie i przechwytywanie wyjątków jest stosunkowo
kosztowne(słabo obsługiwane przez jvm).
Umieszczenie kodu w bloku try-catch blokuje niektóre
optymalizację.
Wyjątki to pełno wartościowe obiekty. Mogą posiadać pola,
metody, konstruktory itd. Własności te mają na celu wspomóc
programistę w szybszej i lepszej eliminacji potencjalnego
zagrożenia lub problemu.
Właściwe wykorzystanie wyjątku zwiększa czytelność, ułatwia
konserwacje oraz solidność kodu.
87. Exception
Weryfikowalne(checked) – muszą być jawnie obsłużone w
metodach
Nieweryfikowalne (unchecked) – są instancją klasy Error i
RuntimeException. Nie wymagają jawnej obsługi. Nie
powinny być też przechwytywane.
Przechwytywanie wyjątków ma wtedy sens kiedy jesteśmy
w stanie przywrócić prawidłowy przepływ w aplikacji.
Wyjątki przechwytywalne stosuj wtedy kiedy można
naprawić błąd , a nieprzechwytywalne dl obsługi błędów
programowych.
88. Exception
Nie ignoruj wyjątku (loguj)
! catch block
Zawężaj jak tylko to możliwe
Nie wyrzucaj wyjątku z sekcji finally
Zawsze wyrzucaj wyjątki najszybciej jak to możliwe
Owijaj wyjątki w zależności od potrzeby, czasem RuntimeException nic nie mówi.
deklaruj specyficzne weryfikowalne wyjątki jeśli używasz throws != Exception →
SpecificException1, SpecificException2
Nigdy nie łap po Throwable (java errors są podtypem Throwable)
Nie używaj printStackTrace
Zawsze pamiętaj o zwolnieniu zasobów – finally
Nigdy nie używaj wyjątków do sterowania przepływem programu
89. Exception Wrapper
Odpowiedni opakowuj wyjątek tak aby nie
zgubić potrzebnych informacji
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " +
e.getMessage());
}//wrong
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " , e); //correct
90. Exception → log & throw
Wyrzucaj wyjątek lub loguj zaistniałą sytuację.
catch (Exception e) {
log.error("Some information", e);
throw e;
}//wrong
Przykład 2.
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
91. Tworzenie i usuwanie objektów
Użycie statycznej metody faktory zamiast konstruktora
- zalety lepiej odzwierciedla zamiary autora
- nie wymaga tworzenia nowego obiektu podczas jej wywołania (używa już starego obiektu)
np. Boolean.valueOf(boolean)
- zastępuje konstruktor teleskopowy
-możliwość zwracania typu , który jest podtypem danego typu
-ograniczenie objętości tworzenia instancji typów sparametryzowanych
np. public static <T,V> HashMap<T,V> newInstance() {
return new HashMap<T,V>();
}
w JAVA 7 wprowadzono diament
92. Tworzenie i usuwanie obiektów
Wzorzec builder
Wykorzystanie konstruktora prywatnego w celu zabezpieczenia przez utworzeniem
obiektu , ma to zastosowanie w statycznych klasach narzędziowych.
Unikanie powielania obiektu
Usuwanie niepotrzebnych referencji do obiektu (object = null) – wycieki pamięci
Unikanie finalizatorów – nie ma gwarancji ich wykonania. Są powolne i nie dowiesz się
nić o żadnym wyrzuconym wyjątku.
Rozważanie użycia wzorca singleton – Enum jest najlepszym przykładem dla wzorca
singleton.
Preferuj użycie obiektów niezmiennych - nie wymagają on żadnej synchronizacji
(thread safe) . Są to takie obiekty których wszystkie znaczące pola są private oraz final.
Nie można zmienić stanu wewnętrznego tych obiektów. Żadna metoda nie może zostać
przesłonięta
93. Metody wspólne
Użyj Float.compare i Double.compare zamiast
operatorów '<' i '>'
Przedefiniuj metodę toString()
Uważaj zawsze hashCode() w kontrakcie z equals()
94. Klasy i Interfejsy
Hermetyzacja
Kompozycja jest na ogół lepszym rozwiązaniem niż dziedziczenie , ponieważ
dziedziczenie narusza hermetyzację . Jest odpowiednie tylko wtedy kiedy istnieje
relacja podtypu między klasą bazową a podklasą.
Konstruktom nie wolno wywoływać metod które można przesłonić.
Klasy typu Utils , zamień na finalne lub zamień jest konstruktor na prywatny
(można zrobić to i to)
Preferuj interfejsy nad klasy abstrakcyjne – Interfejsy pozwalają na tworzenie
niehierachicznych modeli typów. Są idealne do definiowania klas mieszanych czyli
oprócz implementacji 'typu pierwotnego' deklaruje dodatkowo zestaw funkcji
(Comparable). Interfejsy pozwalają na bezpieczne i efektywne rozszerzanie
zestawu funkcji.
Celem interfejsu nie jest definicja stałych !
96. Maven
- deklaratywność (struktura i zawartość projektu są z góry znane )
- zarządzanie zależnościami (automatycznie je pobiera i
konfiguruje)
- wbudowane narzędzia do kompilacji, testowania, wdrażania
aplikacji itd.
- bogactwo pluginów
- integracja z repozytoriami
- integracja z CI
- integracja z systemami śledzenia błędów
- integracja z narzędziami badającymi jakość kodu
97. Maven konfiguracja
Dodajemy możliwość debugowania oraz ustawiany ramy pamięci:
MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m
-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
w pliku settings.xml:
- ustawiamy ścieżkę do lokalnego repozytorium bibliotek
- ustawiamy proxy jeśli takie występuje
- ustawiamy dostęp do różnych serwisów czy serwerów np. nexusa
- ustawiamy mirrory zasobów
- ustawiamy profile działania aplikacji
98. Maven : pom
Model obiektów projektu Maven – POM (Maven project object model)
pom.xml zawiera szczegółowy opis naszego projektu.
- definiuje strukturę projektu
- definiuje zależnościami projektu oraz zależności bibliotek
- definiuje tym wytworzonego produktu (ear, war, jar, sar, pom, rar, par etc)
- definiuje wersję produktu (version)
- definiuje zasoby aplikacji i zasoby testowe
- definiuje członków zespołu, kontakt do nich
- definiuje system kontroli wersji, CI oraz system zgłaszania błędów
- definiuje wersje (bibliotek i javy)
i tak w pom.xml wyszczególniamy:
groupId - definiuje określony projekt lub zbiór bibliotek w ramach firmy czy organizacji
artefactId - definiuje faktyczną nazwę projektu
version - definiuje kolejne wersji w ramach wersji rozwojowej (snapshot) lub wersji stabilnej i docelowej (release)
scm - definiujemy system SCM (svn, git etc)
issue Management - system śledzenia błędów (jira, trac, etc)
ciManagement - definiujemy system CI (jenkins, bamboo, etc)
developers - w tej sekcji w ramach znacznika <developer> definiujemy programistów, którzy pracują nad danym projektem
contributors - dostawcy uczestniczący w projekcie
name - nazwa do wyświetlenia
packaging - sposób pakowania artefaktu
url - link do projektu
inceptionYear - rok rozpoczęcia projektu
organization - organizacja , firma
licenses - typ licencji
99. Maven
Automatyzacja budowy paczek
- kompilacja źródeł do wersji binarnych
- tworzenie różnych rodzajów paczek
- odpalanie testów, regresja
- przenoszenie paczek na zdalne maszyny (repozytoria)
- tworzenie dokumentacji i release notes
Modularyzacja projektu
- możemy tworzyć wiele modułów, zarządzanych przez wspólne zależności i procesy zdefiniowane w
parent projekty (<packaging>pom</packaging>)
Zarządzanie zależnościami
- dependencyManagement jako dobra praktyka (wszystko definiujemy w parent pom.xml a w
poszczególnych pom.xml (child) pomijamy już wersje biblioteki)
Badanie jakości kodu
- pluginy
- mvn site
- sonar
101. Maven
Szybki start (PoC) :
archetype – szablon projektu
mvn archetype:generate
-DarchetypeArtifactId=maven-archetype-quickstart
-DgroupId=pl.java.scalatech.borowiec -DartifactId=myApp
bez trybu interakcji: -DinteractiveMode=false
użycie samego mvn archetype:generate pozwala nam wybrać typ projektu na
samym stracie. Tym samym zwiększa to np. szybkość tworzenia naszego PoC.
102. Maven : moduły
compiler – odpowiada za kompilację
clean – czyści zasoby po procesie budowy
deploy – umieszcza produkt w zdalnym repozytorium
failsafe – odpala testy integracyjne JUnit w izolowanym classloader
install – umieszcza artefakt w lokalnym repozytorim
site – generuje raport
surefire – odpala testy Junit w izolowanym classloder
changelog – generuje listę zmian z SCM
checkstyle – sprawdzanie jakości i standaryzacji kodu
pmd – sprawdzanie jakości i standaryzacji kodu
assambly – budowanie dystrybucji paczki
release – wydanie wersji release i umieszczenie jej w SCM tags
eclipse – generacja projektu dla eclipse
idea – generacja projektu dla idea
103. Maven
mvn test – testowanie projektu
mvn package – budowanie artefaktu
mvn install - instalacja artefaktu na lokalnym repozytorium
mvn site – generowanie raportów
mvn release – dostarczanie paczki i umieszczanie jej w tags
mvn deploy – dostarczanie paczki
mvn clean install – czyszczenie i instalacja artefaktu
mvn clean package -U – pobieranie bibliotek ze zdalnego repozytorium
mvn -o - tryb offline, nie próbuje się łączyć ze zdalnym repozytorium
mvn package -X - debugowanie
mvn -Dmaven.test.skip=true - pomijanie testów (antipattern)
mvn -Dmaven.test.skip {nazwa klasy testu } - pomijanie konkretnego testu
mvn versions:display-dependency-updates - pokazuje zależności, które są w nowych wersjach na zdalnych repozytoriach w porównaniu z tymi które używamy
obecnie (przykład)
mvn versions:display-plugin-updates - pokazuje pluginy, które są w nowych wersjach na
zdalnych repozytoriach w porównaniu z tymi które używamy obecnie (przykład)
mvn dependency:tree -Ddetail - pokazuje drzewko zależności (przykład)
mvn dependency:list – pokazuje listę zależności (przykład)
mvn help:effective-pom – pomoc w tworzeniu 'efektywnego poma'
mvn help:effective-settings – pomoc w tworzeniu 'efektywnych ustawień settings.conf' (przykład)
mvn help:system – pokazuje zmienne środowiskowe
mvn dependency:build-classpath – pokazuje classpath użyty do budowy artefaktu
mvn help:all-profiles - wyświetlenie wszystkich zadeklarowanych profili (przykład)
mvn archetype:generate – wybór archetypu do budowy szkieletu projektu
mvn install:install-file -Dfile=homeprzodowniksome-{version}.jar -DgroupId=pl.java.przodownik
-DartifactId=commandApp -Dversion={version} -Dpackaging=jar
- instalowanie artefaktu do lokalnego repozytorium
mvn dependency:analyze – określa które zależności mają status np. unused
106. Przykład wykorzystania fazy budowy
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
107. Maven : cykl życia
1. validate -walidacja projektu
2. initialize -inicjalizacja zmiennych, tworzenie katalogów
3. generate-sources -generacja źródeł
4. process-sources -przetwarzanie kodu źródłowego , np. w celu przefiltrowania pewnych wartości
5. generate-resources -generowanie zasobów.
6. process-resources -kopiowanie i przetwarzanie zasobów do katalogu wynikowego
7. compile -kompilacja kodu źródłowego
8. process-classes-post-process -generowanie plików dla kompilacji
9. generate-test-sources -generacja kodu potrzebnego do testów
10. process-test-sources -filtrowanie zasobów do testów
11. generate-test-resources -tworzenie zasobów do testów
12. process-test-resources -kopiowanie i przetwarzanie zasobów do katalogu wynikowego testów
13. test-compile -kompilacja testów
14. process-test-classes -przetwarzanie testów w celu np. udoskonalenia bytecodu
15. test -odpalanie testów
16. prepare-package -wykonywanie operacji, które mają za zadanie przygotować klasy i zasoby do wytworzenia artefaktu
17. package -wykorzystanie już skompilowanego kodu i wytworzenie paczki zgodnie z definicją pom.xml np. jar czy ear
18. pre-integration-test -wykonywanie zadań przez testami integracyjnymi
19. integration-test -wykonanie testów integracyjnych jeśli takie są zdefiniowane w pom.xml
20. post-integration-test
21. verify -wykonanie zadań po przeprowadzeniu testów integracyjnych np. czyszczenie zasobów, sprawdza poprawność paczki
22. install - umieszcza paczkę w lokalnym repozytorium
23. deploy - umieszcza (publikuje) paczkę w zdalnym repozytorium
109. Kontekst i artefakt - postawy
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId> → groupId – określa twórcę , firmę itd
<artifactId>my-app</artifactId> → arfitactId – określa nazwę aplikacji
<packaging>jar</packaging> → packaging – sposób pakowania artefaktu
<version>1.0-SNAPSHOT</version> → version – wersję artefaktu
<name>my-app</name> → name - nazwę wyświetlaną
<url>http://maven.apache.org</url> → url - link do strony projektu
<inceptionYear>...</inceptionYear> - rok rozpoczęcia projektu
<licenses>...</licenses> - typ licencji
<organization>...</organization> - organizacja , firma
<developers>...</developers> - deweloperzy uczestniczący w projekcie
<contributors>...</contributors> - dostawcy uczestniczący w projekcie
110. Artefakty oraz pakiety
Pom (packaging) – zawiera inne projekty mavena (multi-projekt)
Jar (packaging) - Zbiór komponentów EJB , Entity lub też po
prostu biblioteka klas
War(packaging) - webowy pakiet javy (może zawierać dowolna
ilość jarów) ,zawiera deskryptor WEB-INF/web.xml
Ear (packaging) - korporacyjny pakiet javy (może zawierać wary
oraz jary) , zawiera deskryptor META-INF/application.xml
Sar - różnego rodzaju aplikacje usługowe, rozszerzające
możliwości serwera (JBOSS) , zawiera deskryptor META-
INF/jboss-service.xml
115. Maven : Profile
Profile służą do definiowana zachowania w zależności od warunków.
Np możemy zdefiniować sobie zmienne środowiska jak :
- develop (rozwojowe)
- stage (pomostowe)
- production (produkcyjne)
I tak przełącznik -Pdevelop załaduje nam zasoby związane z danym profilem czyli np:
testową bazę danych, testowy adresy WS , plus inną konfiguracją cechującą testy.
Uwaga : profile można łączyć :
mvn install -P profile-1,profile-2
lub które nie mają być aktywowane:
mvn install -P !profile-1,!profile-2
118. Ukrywanie wrażliwych informacji
Hasła zapisuje w pliku setting.conf w katalogu maven.
<settings>
<profiles>
<profile>
<activeByDefault>true</activeByDefault>
<properties>
<environment.type>prod</environment.type>
<database.password>secretPassword</database.password>
</properties>
</profile>
</profiles>
</settings>
119. Maven : zasięg
compile – kompilacja , testowanie i uruchomienie . Biblioteka zawsze jest
dołączana do wyprodukowanej artefaktu. Wartość domyśla.
provided – kompilacja i testowanie. Maven zakłada , że paczka zostanie
dostarczona przez kontener na którym artefakt będzie docelowo działał
np. Servlet API , czy Hibernate
test – kompilacja testów oraz testowanie . np. junit , mockito
runtime – testowanie i uruchomienie . Biblioteka jest potrzebna podczas
uruchamiania testów oraz do działania artefaktu na danym kontenerze.
system – z jakiś powodów nie umieszczamy biblioteki w repozytorium ale
dostarczamy ją z jakiejś lokalizacji dyskowej
121. Maven:Best practices & capabilities
maven Repository (http://mvnrepository.com/)
Enforcer Plugin (omijanie kłopotów z konfliktami bibliotek)
build-helper-maven-plugin (podczepianie wygenerowanych źródeł)
wbudowane kontenery Jetty, Tomcat -stosowane podczas rozwijania systemu
raportowanie i statystyki (testowanie, pokrycie testami, jakość kodu, java docs, sonar ,
scm statistisc etc )
M2Eclipse wtyczka do Eclipse
wrażliwe informacje przetrzymujemy w settings.conf
exclude w stosunku do niektórych bibliotek w hierarchii zależności (classloader problem)
testy (maven-failsafe-plugin, selenium-maven-plugin, pitest-maven, jmeter-plugin, soapui-
plugin, etc)
DSL (maven-apt-plugin)
metamodel (hibernate-jpamodelgen, etc)
122. Gradle
Narzędzie do budowy projektów
Deklaratywne i imperatywne zarazem
Oparte na języku groovy
Dojrzałe
Posiada kontrolę zmian
Minimalna konfiguracja a duże efekty
Wolny do Xml'a
123. Gradle : co odziedziczył od innych
Ant:
- elastyczność
- pełna kontrola
- wywoływanie targetów w łańcuchu
- tworzenie tasków
Ivy:
- zarządzanie zależnościami
- wykorzystuje jego repozytoria
Maven:
- Convention over configuration
- Multi-module projects
- rozszerzalność poprzez pluginy
- wykorzystuje jego repozytoria
Gant
-opakowanie kodu Anta w DSL za pomocą języka groovy
125. Gradle : polecenia
gradle -gui - pokazuje nam jakie taski możemy wykonać. Wystarczy
kliknąć.
gradle --help - wyświetla dodatkowe opcje.
gradle tasks - wyświetla dostępne taski.
gradle install – instalacja artefaktu w repozytorium
-Dproperty=value - definiuje zmienna nową zmienną systemową
--info, -i - ustawia poziom logowania
--debug, -d - przełącza na poziom debug , włączając w to stacktrace
(przykład)
--quiet, -q - pomija większość outputów na konsoli, pokazuje tylko błędy
gradle dependencies - pokazuje zależności i ich zakresy
128. Gradle : minimum
apply plugin: 'java' //dadanie tasków dla javy
apply plugin: 'eclipse' //dodanie tasków dla eclipse
sourceCompatibility = 1.7 //kompatybilnosc z java 7
version = '1.0' //wersja artefaktu
jar { //dyrektywy do wyprodukowania jara
manifest {
attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
}
}
repositories { //dadanie repo mavena
mavenCentral()
}
dependencies { //dodanie zależności
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
test { //dodanie zmiennych środowiskowych dla testów
systemProperties 'property': 'value'
}
uploadArchives { //opublikowanie jara w lokacji
repositories {
flatDir {
dirs 'repos'
}
}
}
129. Gradle : polecenia
gradle [task_name] - wykonuje taska o nazwie [task_name]
gradle -x first second - pomija pierwszy task (x)
(definiowanie kolejności wywoływania : second.mustRunAfter(first) )
gradle fi - domyśla się, że chodzi o task first. (fi)
gradle -m second - nie wykonuje żadnego taska ale informuje co
potencjalnie by wykonał (-m)
gradle [task] --profile - profilowanie taska