czwartek, 30 stycznia 2014

clean code 4

Praca z kodem czyli moje zajęcie :)
OK. Rozpoczynamy naszą  walkę o dobry kod.
Na sam początek zdefiniujemy sobie kilka terminów lub pojęć, które wypada znać.
Może inaczej,  bez ich znajomości nie można pisać dobrego kodu - takie jest moje zdanie. Są to głównie paradygmaty OO takie jak SOLID, GRASP etc.
Poniżej przygotowałem w skrócie prezentacje w xmind na której widać o co w tym wszystkim biega.


W poście tym, który jest kontynuacją poprzedniego który to mówił co należy zmienić w Twojej mentalności tak abyś stał się profesjonalistą w tym co robisz.
Teraz dowiesz się  jakie praktyki proponuje C.Martin. Jak należy dobrze programować w OO oraz inne pożyteczne wskazówki, które to mam nadziej wzbogacą Twój warsztat.


Ale co to jest czysty kod (według Uncle Boba)?
Czysty kod to kod elegancki, efektywny, prosty, pełen trafnych abstrakcji.
Łatwo sterowalny. Każdy o niego dba. Posiada i przechodzi testy jednostkowe i akceptacyjne. Jest wolny od powtórzeń. Powinien być maksymalnie minimalny objętościowo. Generalnie opiera się na wszystkich zasadach SOLID i GRASP.


TIP : @author (Javadoc) - kod bez jawnego autora, sprawia, że rozmywa się odpowiedzialność. Podpisany kod jest podatny na ocenę innych i o to w tym chodzi.


Prawo Demeter mówi, że metoda danego obiektu może odwoływać się jedynie do metod:
 - należących do tego samego obiektu,
 - metod dowolnego parametru przekazanego do niej,
 - dowolnego obiektu przez nią stworzonego,
 - dowolnego składnika klasy do której należała dana metoda.


W praktyce oznacza to, że obiekt powinien unikać wywołania metod klasy, której obiekt został mu dostarczony przez inny obiekt. np. w języku Java kod a.b.metoda() łamie prawo Demeter,  podczas gdy a.metoda() tego prawa nie łamie.
Tak więc prawo Demeter ogranicza długie łańcuchy wywołań.
Popularnie jest ono wyrażane: 'Nigdy nie rozmawiaj z obcymi'.

Stosowanie prawa Demeter, ułatwia pielęgnację, zmniejsza współczynnik błędów, ogranicza powiązania między obiektami, wzmacnia hermetyzację i abstrakcję
obiektów, a tak że powoduje przeniesienie odpowiedzialności za dostęp do metod i atrybutów klasy z obiektu odwołującego się do nich na ich właściciel

Loose coupling (luźne wiązania) - jest to własność systemu, która oznacza, że jego poszczególne moduły mogą być traktowane w dużym stopniu niezależnie i ich kody nie są ze sobą ściśle powiązane.

Cohesion -  miara powiązań funkcjonalnych metod w danej klasie. Należy dbać o utrzymanie wysokiej spójności (high cohesion).
Jeżeli jedna klasa odpowiada za zbyt wiele zagadnień (jest niespójna), z czasem nadmiernie się rozrośnie i będzie trudna do zrozumienia oraz pielęgnacji. Czasem należy przenosić odpowiedzialność do klas potomnych lub pomocniczych w celu zwiększenia ogólnej spójności.

TIP : LCOM4 , Metryki Kodu

Projektowanie pakietów










  Reguły SOLID :






























Zasady GRASP :



















Zdiagnozowane i zdefiniowane problemy: 








































Moje stare notatki :






































Zasady projektowania :
















Java class layout :
 1.Package statement
 2.Import statements
 3.Comments
 4. Class declaration {
          5. Variables
          6. Comments
          7. Constructors
          8. Methods
          9. Nested classes
         10. Nested interfaces
         11. Enum
 }

TIP : Sonar rules , PMD rules

Zalecenia uncle Boba :

TIP : Zasada skautów (The boy scout rule)
(leave the campground cleaner than you found it)

 - używaj nazw przedstawiających Twoje intencje. (Use Intention-Revealing Names)

Wybór odpowiedniej nazwy jest naprawdę ważną rzeczą - utrzymanie kodu)
     int k; // jest  niedopuszczalne 
  
TIP:  Avoid inconsistent naming  
 - unikaj dezinforamacji (Avoid Disinformation)

 - używaj nazw które można wymówić (Use Pronounceable Names)
 - używaj nazw łatwych do wyszukania (Use Searchable Names)
    (The length of a name should correspond to the size of its scope)

 TIP : Magic numbers (PMD rules ,  Sonar rules)
 TIP : new Syntactic sugar like :  binary literals, underscores in numbers, diamond syntax (lub Guava Static constructors)


   - klasy to rzeczowniki (unikaj takich nazw jak Manager, Info, Processor, Data)
   - metody są czasownikami
   - gdy konstruktory są przeciążone zastąp je metodą fabrykującą

   Uwaga: W konstruktorze nigdy nie może być metoda którą możesz przesłonić !  

   - wybieraj jedno słowo na pojęcie (Pick One Word per Concept
      (np fetch, get, retrieve etc) Nazwy funkcji powinny być niezależne i spójne.

  - korzystanie z nazw dziedziny rozwiązania  (Use Solution Domain Names)
   (np : AccountVisitor - zastosowany wzorzec visitor)

  - dodanie znaczącego kontekstu (Add meaningful context)
     Czasem warto dodać przedrostek by pokazać, że zmienna jest częścią większej struktury.

Funkcje

    - funkcje powinny być krótkie (small), najlepiej jak mają maksymalnie kilka linii < 20.
    - funkcje powinny wykonywać tylko jedno zadanie (Do One Thing), jeśli tak nie jest istnieje realna potrzeba dekompozycji funkcji na mniejsze logiczne kawałki
   - wartość zagnieżdżenia instrukcji warunkowych w jednej funkcji (Blocks and Indenting) nie powinna przekraczać 2 (<2). (czytelność, złożoność lokalna)
   - działanie funkcji powinno opierać się na jednym poziomie abstrakcji   (One Level of Abstraction per Function)

   - funkcje pisz tak aby łatwo można było je czytać od góry do dołu
     (Reading Code from Top to Bottom: The Stepdown Rule)

  - instrukcje switch (Switch Statements)
    Należy uważać na instrukcje typu switch ponieważ często są to duże byty, często naruszają zasadę SRP oraz OCP .

 TIP : użyj Abstract Factory

  - korzystaj z nazw opisowych (Use Descriptive Names) - aby dokładniej sprecyzować faktycznie znaczenie funkcji oraz czynności jaką ma za zadanie wykonać. (długa nazwa nie jest problemem)

 - argumenty funkcji (Function Arguments)
Generalnie trzymajmy się zasady im mniej tym lepiej bo jest ona wtedy łatwiejsza do analizy. Przyjmuje się, że funkcje powinny zawierać max do trzech argumentów. Argumenty sprawiają też, że taką funkcję jest trudniej przetestować. Funkcje z jedno-argumentowym typem boolean są złe, bo oznacz to, że funkcja wykonuje więcej niż jedną operację.
Jeśli funkcja wymaga więcej niż dwóch czy trzech argumentów użyj wrapper. Funkcje powinny być czasownikami lub tworzyć parę czasownik-rzeczownik. Jeśli już się zdarzy, że funkcja złamie zasadę SRP to Twoim obowiązkiem jest zasygnalizować to w nazwie funkcji.

 - argumenty wyjściowe (Output Arguments)
 Analiza wyniku argumentów wyjściowych z reguły trwa długo. Można odwoływać się do referencji this jako wyniku działania danej funkcji. Po prostu funkcja zmienia stan własnego obiektu i ma do tego prawo (OO).

 - stosowanie wyjątków zamiast kodów błędów (Prefer Exceptions to Returning Error Codes) prowadzi do powstawania głęboko zagnieżdżonych struktur (complexity) poprzez zastosowywanie instrukcji if. Zwracany kod błędu musimy natychmiast obsłużyć w ten czy inny sposób. Zastosowanie wyjątku odseparowuje prawdziwą ścieżkę wykonania od obsługi błędu przez co kod staje się prostszy. Ponadto wyrzucenie wyjątku z nieweryfikowalnego lub zdefiniowanego biznesowo znacznie uprasza strukturę i zrozumienie problemu.
Konstrukcje typu zamykanie kodów błędów w enum jest też słabe. Dodanie nowego wymaga ponownego przekomplilowania programu.



TIP :
       - Improved exception handling - redukcja kodu, enumerujesz wyjątki '|'
       - Try-with-resources (TWR) - nie martwisz się dłużej o zamykanie zasobów oraz eliminujesz brzydkie finally.
Uwaga : korzystając z TWR pamiętaj, że  zastosowaniu java.lang.AutoCloseable , bo właśnie na tym opiera się mechanizm TWR


W javie 7 wygląda to tak : - wyodrębnij blok try/catch (Extract Try/Catch Blocks)
Blok try/catch wygląda brzydko już sam w sobie. Narusza strukturę przepływu bo miesza przetwarzanie błędu ze zwykłym przetwarzaniem. Warto jest wyodrębnić poszczególne bloki try oraz catch czy finally do osobnych funkcji.
Obsługa błędów też jest operacją i powinna robić też tylko jedną rzecz.

Inne przydatne features java 7 :











TIP : TWR , AOP Throws Advice

- programowanie strukturalne (Structured Programming)
  Zawsze unikaj goto ! Uważaj na zwielokrotnianie instrukcji return. Dziel duże funkcje na małe.
 

 Komentarze

 - obecność komentarza sugeruje nieporadność programisty lub po prostu nieudany kod
 - zamiast pisać komentarz spróbuj napisać kod tak aby sam wyrażał swoje intencje (Explain Yourself in Code)
 - nie jesteśmy w stanie utrzymywać komentarzy, więc często są już nie aktualne.
 - duża liczba komentarzy wprowadza bałagan w kodzie.

 Dobre komentarze to (Good Comments):

  - komentarze prawne (Legal Comments)  np: licencje
  - komentarze informacyjne (Informative Comments)  ale w przypadkach gdzie faktycznie taki komentarz dużo pomaga dla czytającego kod. np (wyrażenia regularne)
   - wyjaśniające zamierzenia i postępowania (Explanation of Intent) np @SuppressWarnings (Eliminate unchecked warnings  J.Bloch)

   - ostrzeżenie o konsekwencjach (Warning of Consequences)
     np : Not thread safe
  
   - komentarze TODO  (TODO Comments) oznaczające zadania do wykonania, ale z jakiegoś powodu w danym momencie nie możemy zrobić tego od ręki.

   - wzmocnienie (Amplification)  - ukazujący wagę danej operacji.

   - komentarze do publicznego API (Javadocs in Public APIs)


Złe użycie komentarzy (Bad Comments) :

- bełkot (Mumbling) - to taki komentarz, który naprawdę  nic nie wnosi.
   
- powtarzające się komentarze (Redundant Comments) oraz komentarze które nic nie wnoszą (Noise Comments)
  np : wszystkie pola, konstruktory, metody getter oraz setter etc

- znaczniki pozycji (Position Markers)
 np : // Do something with user account ///////////////

- komentarze w klarach zamykających (Closing Brace Comments) oznaczające koniec bloków np for czy if

- atrybuty i dopiski  (Attributions and Bylines) używamy systemy kontroli wersji więcej tam możemy komentować różne rzeczy np kto dodał modyfikację

 - zakomentowany kod (Commented-Out Code) jeśli zobaczyć fragmenty lub sekcje zakomentowanego kodu po prostu go wywal. Jest przecież historia zmian w systemie kontroli wersji.

 - komentarze HTML (HTML Comments)  powinny być generowany - formatowe przez narzędzie do generacji dokumentacji.

- informacje nie lokalne (Nonlocal Information) - czasem spotyka się komentarz, który znajduje się w złym miejscu lub po prostu do tego miejsca nie pasuje. np informacje o konfiguracji trzymaj na WIKI.


cdn.

środa, 29 stycznia 2014

clean code - wprowadzanie część 3

Szacowanie

Strach przed szacowaniem zadania wydaje się być naturalny, ale czy musi tak zawsze być ? Szacowanie to odwieczny konflikt między PM a programistą. Dlaczego tak się dzieje ? Ponieważ PM traktuje szacowanie jako zobowiązanie, a programista jako przypuszczenie.
Profesjonalista nie podejmuje zobowiązań kiedy nie ma pewności, że je wypełni w zadanym czasie. Jeśli nie jesteś pewien, że zdołasz to zrobić w zaproponowanym przez siebie czasie po prostu odmów.

Bazując się na Twoich szacunkach inni zaczną tworzyć swoje plany.

TIP : PERT



Latające palce
Członkowie zespołu siedzą przy stole i omawiają wszystkie zadania w danym sprincie. Omawiają co może skomplikować dane zadanie i jak można je zaimplementować. Na raz uczestnicy podnoszą palce do góry i pokazują liczbę od 0 do 5 w zależności od własnego przeczucia co do pracochłonności zadania.
Jeśli będzie pełna zgoda, znaczy to, że zadanie zostało zaakceptowanie. W przeciwnym wypadku zaczynamy proces od nowa. Zgoda nie musi być całkowita. Odchylenie można ustalić na początku spotkania.








 Planning Poker
Każdy członek zespołu dostaje zestaw kart z różnymi numerami. Prowadzący wymienia zadanie i zaczyna się dyskusja. W końcu wszyscy muszą zdecydować jaką kartę wybrać. Aż do momentu pokazania karty, nikt nie ma prawa jej widzieć poza właścicielem. Jeżeli wszystkie numery są podobne następuje zaakceptowanie szacunku w przeciwnym wypadku postępujemy dokładnie tak samo aż do skutku. Siła tego narzędzia to dyskusja.







Szacowanie : Stożek niepewności (Cone of uncertainty)

















Stożek niepewności przypomina programiście, że jego początkowe szacowania mogą się różnić od końcowego stadium zadania nawet o 400%. Obrazuje nam jeszcze jak wygląda stosunek : szacunek od stadium projektu.


Żeby poprawić swoje szacowania głównie potrzebujemy :
 - historii, który rozmiary mogą być porównywane w stosunku do siebie samych
 - systemu punktowego do śledzenia postępów

Istnieje terminy:
   - szacunek względny (przez triangulacje) jest to taka sytuacja kiedy robiłeś coś podobnego do  bieżącego zadania tym samym masz jakiś pogląd sytuacji, możesz te zadaniu w pewien sposób porównać ze sobą.

 - szacunek bezwględny - kiedy nie istnieje żadna rzecz do której możesz porównać swoje zadanie, aby przynajmniej w przybliżeniu stwierdzić ile to Ci   de facto zajmie czasu np wyrzucenie dwóch piątek kością do gry pod rząd.

System punktowy pozwala wprowadzić wymyślona jednostkę miary, którą będziemy estymować nasze zadanie. Możemy też dzięki temu śledzić postępy i szacować względnie.
Zaletą tego systemu jest to, że uświadamia nam iż nadal mamy do czynienia z szacunkiem a nie wartością znaną np czas . Jest łatwy, szybki i prosty.

TIP : Pamiętaj , że programista nie pracuje wydajnie przez cały dzień , więc mówienie, że coś zajmie np 3 dni musi brać tę zależność pod uwagę.

Tip : The Burn-Down Chart -> czyli coś dla  PM'ów

Burn-Down Chart jest  to graficzne przedstawienie pozostałych do wykonania w projekcie prac względem czasu. Wykres pokazuje także szacowany czas pracy do zakończenia projektu.















źródło : http://www.agilenutshell.com/


Presje

Najważniejsze jest to żeby opanować stres. Zamartwianie się niewiele pomoże. Nieprzespane noce, podobnie. Najgorsze co możesz zrobić to zacząć się spieszyć. Wtedy utoniesz do reszty.

Tip : Informuj o kłopotach zawczasu.

Pamiętaj : Zły kod zawsze spowalnia.

Współpraca

Kodu jest własnością zespołu (collective code ownership). Bardzo złym symptomem jest to jak którykolwiek z programistów w zespole buduje mur otaczający jego kod i odmawia zmian pozostałym.

Praca w parach się opłaca.
Jeśli nigdy tak nie pracowałeś to spróbuj.
To najlepszy sposób bezpośredniego dzielenia się wiedzą. Technika ta pozwala również rozpowszechniać dobre wzorce i praktyki oraz wzbogaca cały zespół w solidną wiedzę na temat projektu. Dotyczy to zarówno części biznesowej jak i technicznej.
Niektórzy mogą powiedzieć, że tracimy zasoby bo dwie osoby robią to samo.
Okazuje się jednak, że to błędne myślenie. Taka inwestycja zwraca się bardzo szybko, ponieważ potem okazuje się, że kod napisany jest lepiej (real-time code review), zawiera mniej błędów. Następny atut tej metody, że każdy członek zespołu może bezboleśnie poprawiać błędy w wielu obszarach aplikacji, bo istnieje duże prawdopodobieństwo, że w którym z tych obszarów już empirycznie uczestniczył.

Tip : XP

Swarming (z ang - rój) czyli równoległa praca wielu członków zespołu nad jednym wybranym problemem.
Przykładowe zastosowanie : eliminacja wąskich gardeł, detekcja błędów, dotarcie zespołu etc.

Zespoły i projekty

Zgranie zespołu wymaga czasu. Po pewnym czasie każdy wie co ma robić i w czym jest dobry.
Zadaniem analityka jest zdefiniowanie wymagań biznesowych, czasem tworzenie zautomatyzowanych testów UAT.
Testerzy również mają tworzyć takie testy.
Jak więc jest różnica?  Analityk koncentruje się  na biznesie , a tester na poprawności. Analityk z reguły przechodzi przez optymistyczną ścieżkę, a tester powinien zastanowić się co można zepsuć w tym całym procesie.
Menadżer zaś monitoruje postępy zespołu, definiuje priorytety i harmonogramy.
Ktoś w zespole scrumowym musi pełnić role mistrza. Jego odpowiedzialnością jest ochrona procesów oraz metod wyznaczonych przez zespół.

Tip : Zespół tworzy się trudniej niż projekt

Ok. na tym zakończyliśmy rozważania 'filozoficzne'.

Teraz przejdziemy do clean code w czystym wydaniu. Bazując na pracach Uncle Boba omówimy sobie jak pisać 'czysty', czytelny kod. Po prostu przedstawimy kilkanaście recept i porad, który wyniesie jakość Twojego kodu na wyższy poziom.

dalej ->

Big data - wprowadzenie.

Big data to ....
Big data pozwala na gromadzenie, przechowywanie, zarządzanie i manipulowanie wielkimi wolumenami danych.
Co więcej pozwala przetwarzać te dane z właściwą prędkością, w zadanym czasie.
Cechy Big data to :
1. volume - objętość danych
2. velocity - szybkość przyrostu
3. variety - różnorodność danych
   
NoSQL to nowoczesne systemy 'pseudo' bazodanowe, które nie opierają się na tradycyjnym modelu relacyjnym, nie wymagają określonego schematu, nie używają złączeń i bardzo dobrze się skalują horyzontalnie.

Bazy relacyjne istnieją od 1973 roku. W tamtych czasach przewidywalna liczba jednocześnie pracujących użytkowników wynosiła maksymalnie klika tysięcy. Dziś bazy wielkość bazy danych możemy szacować na podstawie dziennego przyrostu danych nie ilości wierszy. W przypadku dużych baz liczba ta idzie w miliony.

Od wczesnych lat 80 szybkość procesorów wzrosła z 10MHz do 3,6 GHz czyli 360 razy.Koszty pamięci znacznie spadły z 1000$ za 1MB do 25$ za GB.
Oznacza to ok 40000 redukcje kosztów w stosunku do objętości.

Co roku liczba danych niemal się  podwaja - prawo Moore’a które mówi, że liczba tranzystorów w układzie scalonym w latach kolejnych posiada trend wykładniczy. Znajdujemy więc w tym pewną analogię w stosunku do gromadzenia danych.


Co da Ci znajomość technologi Big data ?

Kasa:  to chyba jeden z najważniejszych powodów aby zakasać rękawy i zacząć uczyć się nosql i jego okolic :)

Spójrzmy na aktualną sytuację na rynku pracy:


Mongo :
scala - groovy , java
scala , groovy , nosql , hadoop
java , sql

Specjalnie dodałem też nowoczesne języki oparte na JVM.
Na wykresach widać jak rośnie ich popularność.
JAVA i SQL spadają. Taki jest trend. Z tym nie da się dyskutować.
W każdym razie ciesz się bo jesteś na odpowiedniej stronie, to może czegoś się nauczysz :)

Tip : kasa to najlepszy afrodyzjak :)

Ciekawe zastosowania = nowe możliwości
Zarządzanie i analiza danych od zawsze umożliwiały generacje zysków w firmach każdej wielkości.
Biznes od dawna zmagał się ze znalezieniem odpowiedniego sposobu przechowywania informacji o swoich klientach, produktach czy usługach.

Wszystko wygląda prosto kiedy firma ma do zaoferowania kilka produktów. Zarządzanie taką ilością jest relatywnie proste i nie sprawia żadnych kłopotów. Ale w dobie dzisiejszej gospodarki wygrywa ten kto ma przewagę nad
konkurencją.

Ja znalazłem sobie następujące zastosowania dla big data:
 - dopasowywanie ofert pod danego klienta - maksymalizacja zysków
 - wparcie dla procesów decyzyjnych
 - systemy rekomendacji
 - redukcja kosztów - kosztowne serwery dedykowane oraz licencje
 - systemy analityczne
 - dywersyfikacja ryzyka

 - znajdowanie podobieństw
 - wykrywanie oszustw (fraud detection)
 - business intelligence

Kiedy warto zastosować big data ?

- Problem biznesowy : (BI)
       - wiele źródeł danych.
       - wysoka złożoność danych
       - formaty danych : np dokumenty tekstowe, zdjęcia, filmy ...

- Problem implementacyjny i projektowy to :
      - bardzo duża ilość danych,
      - bardzo duża szybkość przybywania danych
      - bardzo duża różnorodność danych.

Tip : Redundant physical infrastructure jako fundamenty skalowalności nosql.

Zastosowania:

Przykłady:

Amazon: Rekomenduje książki na podstawie wcześniejszych zakupów, podobieństw upodobań klientów. Potrafi też dać upust przy zakupie produktu podobnej kategorii.
Amazon zapisuje dosłownie wszystko od Twoich pozycji do wyszukania po ścieżki przejścia.

Facebook : podobieństwa. Jeśli znasz Staszka a Staszek zna Olka i również Heniek zna tego Olka, a Ty z kolei znasz Staszka i Heńka to jest duże prawdopodobieństwo, że również możesz znać Olka.

Podobne mechanizmy oferuje LinkedIn
sugeruje kogo możesz znać lub kogo powinieneś znać.





 Przykładowe bazy nosql oraz ich zastosowania : 


Wprowadzenie do architektury rozwiązań systemów nosql:















Bazy kolumnowa (Columnar Stores). Zwiększenie wydajności hurtowni danych i systemów analitycznych. Dane przechowywane są w kolumnach dzięki czemu  możliwa jest lepsza kompresja danych.

Przedstawiciel :
Cassandra  została zaprojektowana do zadań wymagających wysokiej wydajności, niezawodności oraz automatycznej replikacji.

HBase - cześć projektu Apache Hadoop wzorowanej na BigTable Google.
Stworzona do przechowywania ogromnych zbiorów danych porozrzucanych między tysiące nodów.

Bazy klucz-wartość (key/value stores). Działa na zasadzie mapy. Mimo prostego modelu posiada jedną bardzo cenną cechę - szybkość zapisu jak i odczytu.

Przedstawiciel : Redis 
Możemy ją traktować jako rozproszony cache, zamiennik dla memcached
Cechy
  -  transakcje
  -  klastrowanie
  -  atomowość operacji.
  - replikacja master-slave

Inni : 
  - Memcached (in-memory)
 -  MemcacheDB (bazuje na  Memcached)
 -  Berkley DB

Redis jak i Memcached wspierają wygasanie kluczy. Jest bardzo istotne w budowaniu systemów opartych na cache.
Redis ma złożoność wyszukiwania klucza na poziomie O(N) co w praktyce oznacza, że potrafi przeskanować 1000000 rekordów w czasie 40ms. To wszystko potrafi zrobić będąc zainstalowany na zwykłym laptopie. (http://redis.io/commands/keys).
Potrafi także przeszukać bazę kluczy bazując na glob-style pattern, czyli swoim wyrażeniu regularnym.




Bazy dokumentowe (Document stores/databases)
Wiersz zastąpiony jest dokumentem. (bardzo często w formie json)
Elastyczność rozwiązań.

Przedstawiciel : MongoDB 

Cechy:
 - replikacja i fail-over
 - wysoka wydajność
 - skalowanie horyzontalne (sharding - partitioning)
 - zorientowanie na json
 - geospatial
 - pełen CRUD
 - efektywne przetrzymywanie dużych binarnych obiektów
 - map/reduce

 Pojęcia:
  database -> database
  table      ->  collection  
  row        ->  document
  join        ->  embedding & linking
  partition->  shard
  partition key -> shard key

Bazy grafowe (Graph databases)
Każdy rekord przechowuje wskaźnik do rekordów z nim powiązanych.
Wyróżniamy dwa typy obiektów : węzły (node) i relacje (relationship)
Węzły są odpowiednikiem rekordu w relacyjnych bazach danych, natomiast relacje to coś na kształt kluczy obcych.

Przedstawiciel : Neo4j 
Jest to baza grafowa oparta na JVM. Całkowicie wspiera ACID.
Mogąca pomieścić biliony obiektów.
Bardzo wydajna i skalowalna.
Udostępnia  REST API oraz możliwość embedowania w aplikacji.
Indeksowanie oparte na Lucene.
Posiada konsolę graficzną.
Wsparcie ze strony Spring Data.

Etykiety (labels) określają typ węzła.
Własności (properties) mogą być przypisane zarówno do węzła jak i relacji.
Tip : Cypher
Przykład zastosowania sieć znajomych.

Inne :
  - FlockDB (from Twitter)

Bazy obiejektowe (Object databases)

Trendy w Nosql


MapReduce - kolejny cudowny wynalazek Google. Algorytm oparty na zasadzie dziel-i-zwyciężaj tylko, że działający jako rozproszony system między wieloma nodami.






















W fazie "map" zadanie jest dzielone na identyczne pod-zadania i dystrybuowane między węzły klastra które to przetwarzają zadania. Wyniki natomiast są agregowane w fazie "reduce" w większą całość.

Tip : EIP ->   Splitter - Aggregator
 

Splitter
Aggregator




Hadoop:
W skórcie Hadoop to skalowalna platforma umożliwiająca obsługę olbrzymich woluminów danych. Bazuje ona na wzorcu MapReduce, który to jak było wcześniej powiedziane pozwala na podział dużych zbiorów na mniejsze fragmenty danych oraz przetwarzaniu tychże fragmentów na wielu węzłach wykorzystując standardowe komputery. Hadoop operuje na danych niestrukturalnych. Opiera się również na HDFS czyli bardzo wydajnym systemie plików jeśli chodzi o dostęp do danych ta nim zawartych.

Przykład hadoop:
A - See more at: http://www.computerworld.pl/artykuly/385420/Hadoop..a.co.to.takiego.html#sthash.vhGG1OQ6.dpuf

Hadoop ecosystem :
źródło : http://techblog.baghel.com/media/1/20130616-HadoopEcosystem.JPG .








źródło:   http://tushar686.files.wordpress.com/2012/04/ecosystem-and-analytics.png


źródło: http://www.techspritz.com/wp-content/uploads/2013/05/5575485_orig.jpg

Big data landscape
źródło : http://www.ongridventures.com/wp-content/uploads/2012/10/Big-Data-Landscape.jpg




cdn

środa, 22 stycznia 2014

Introduce to groovy as an extension of the previous gradle post (czyli wprowadzenie do gradle cześć 2)


Groovy język skryptowy działający na JVM. Pozwalający zminimalizować kod, który robiłby  to samo a byłby napisany w Javie.

Dlaczego teraz zdecydowałem się wprowadzić Was w świat groovy?

Ponieważ chcemy przejść do najlepszych praktyk w wykorzystaniu gradle. W poprzednim poście pisałem jak działa gradle i o tym, że opiera się na groovy.
Taka kolejność postów wydaje  się być naturalnym rozwiązaniem.
Poza tym niedługo zaczniemy kodować w czysty sposób. Bliżej poznamy wtedy Guavę , Lomboka i spółkę.


Poznanie elementów groovy pozwoli na lepsze zrozumienie następnych tematów. Co więcej zdobędziesz podstawy języka i płynniej wejdziesz wtedy w grails , mało tego w linii prostej następny jest Spring Roo. I to jeszcze nie koniec - testowanie i spock stanie dla Ciebie otworem.
Ale o tym potem:).

W każdym razie znając powyższe rozwiązania , ewentualnie jeszcze scalę oraz wzorce projektowe i przekształcenia refaktoryzacyjne jesteś w stanie tworzyć naprawdę dobry kod.
Zajebisty kod. Kod który każdy będzie chciał  pracować, bo praca ta w końcu stanie się przyjemna.

Groovy :

Cechy:
- typowanie dynamiczne (typ obiektu jest sprawdzany w czasie wykonania a nie w czasie kompilacji (static typing) )

- domknięcia (closure) (fragment kodu w nawiasach {} - traktowany jako obiekt.
  Może przyjmować parametry, zwracać rezultat działania , korzystać ze zmiennych zewnętrznych oraz  być wywołany w dowolnym momencie)
Generalnie jest to  zastąpienie mechanizmu (anonymous inner classes) znanego z javy
Wykonywane tylko wtedy gdy jest do niego odwołanie.


Tip :  .& - użycie metody danego obiektu

it - zmienna deklarowana z automatu wewnątrz domknięcia. Przypisana do pierwszego parametru
- przeciążanie operatorów

- operacje na kolekcjach

- brak typów prostych (wszystko dziedziczy po object)
   Wszystko jest obiektem zarówno typy, metody, operatory czy domknięcia.

- wspiera tworzenie XML'a oraz JSON'a
     XmlParser  - wybieranie danych z XML - chodzenie po grafie XML
     XmlSlurper wybieranie danych z XML - chodzenie po grafie XML
     MarkupBuilder  - generacja XML
JSON:

- szybkie operacje na plikach
- GSQL
      groovy.sql.Sql

- POGO (Plain Old Groovy Object)  == POJO  + autogeneracja setters, getters i map-based contructors
    Redukujemy settters , getters ,constructors .
    Możemy przesłonić sobie toString
    i wygenerować equals + hashcode poprzez @EqualsAndHashCode

   @ToString
   @TupleConstructor
   @Canonical = all

  Tip : lombok (to taki sprytny skurwysyn :) patrz co potrafi : screen poniżej :))
 


Zwykły POJO : Lombok POJO: POGO: - wyrażenia regularne

- integracja z bibliotekami javy
   Z default dostajesz biblioteki :
            - java.util,
            -  java.net,
            -  java.io,
            - groovy.lang,
            - groovy.util,
            - java.math.BigInteger,
            - java.math.BigDecimal.

- GROM = groovy orm (Grails Object-Relational Mapping)
     DSL -> Hibernate
     Nosql : mongoDB , Neo4j , Redis , etc

- wsparcie do testów jednostowych
        - GroovyTestCase
        - Spock  ->  BDD  (given, expect , when/then)

- metaprogramming
     np : dodanie metody do klasy w locie
     
Tip : AOP introducing (poniżej kawałek mojego starego kodu żeby był jakikolwiek przegląd rozwiazania)

GDK - rozszerzenie JDK

println "git help".execute().text
     
Groovy zakłada że wszystko jest public!

Operatory :
.@ - dostęp do pola
?: - elvis
*. - rozpiętość
as - rzutowanie
.& - referencja metody
?. - bezpieczne nawigowanie (reduce null problem )
*.@ - rozpiętość po polach
in - zawieranie
is - identyczność
** - potęgowanie
<==> - porównanie
==! - dopasowanie wyrażenia regularnego
=~ - znalezienie wyrażenia regularnego - zwraca Matcher

Domyśle metody (DefaultGroovyMethods) :

 Boolean  any{closure}  - zwraca true jeśli domknięcie  zwróci true dla dowolnego elementu
 List  collect{closure}  - zwraca listę wszystkich elementów które zwróci domknięcie
 void  each{closure} - wykona domknięcie dla każdego elementu
 Boolean every {closure} - zwraca true jeśli domknięcie zwróci true dla wszystkich elementów
 Object find {closure} - zwraca pierwszy element do pasującego wzorca
 Integer  findIndexOf {closure} - zwraca index pierwszego elementu pasującego do wzorca
 List  findAll {closure} - zwraca wszystkie elementy pasujące do wzorca

Operacje na Stringu: 


Tools :
 - groovysh
 - groovyConsole
 - groovyc - kompilacja do .class z groovy

Tip: gvm

def - deklaracja zmiennych oraz mówimy dla Groovy , że nie interesuje nas typ zmiennej

Uważaj ! , bo :

Wartości numeryczne domyślne to : Integer i BigDecimal przy operacjach matematycznych wynik jest tego samego typu albo typu wyżej

Podczas dzielenia wynik jest podawany w Double lub BigDecimal.

"==" => equals (oznacza równość nie identyczność)

a == b
a.equals(b)
a <=> b
a.compareTo(b) 

isCase(object) w instrukcji switch - wypasiony switch

"return" , ";" oraz kropki oznaczające wywołanie metody   nie są wymagane!

Wyjątki są bliźniacze do RuntimeException

' ' - instance of  String
" " - GString

Domknięcie przykład :

Sprawdzenie identyczności obiektu poprzez is

Unikanie null
city = user ?. address ?. city

GString =  string interpolation (also called Gstring)

Pętle

Switch

Zakresy
left..right        // całość
left>..<right    // z pominięciem progów
left..<right        // pół na pół


To samo można zrobić z liczbami

GroovyBean

Definiowanie klas, interfejsów, pól, metod  podobnie jak w javie

Mapy
Tworzenie poprzez [] i każda para zawiera klucz (String default) oraz wartość którą może być dowolny obiekt
Dostęp do elementów poprzez wskazanie indeksu lub klucza w nawiasach []

Listy

Tip : Guava tworzenie kolekcji!

Generacja template'ów
    - SimpleTemplateEngine            
    - GStringTemplateEngine
    - XmlTemplateEngine

Tip : velocity


Java a  Groovy : tworzenie klas , interfejsy takie same zasady tu i tu
Groovy ma typy dynamiczne więc nie potrzebuje wykorzystywać interfejsów do operacji polimorficznych jednak pozwala je używać.

Tip : stosuj słowo kluczowe assert do weryfikacji poprawności wyniku


Podsumowując :

Chciałem wprowadzić Was łagodnie w świat języka groovy. Poznaliśmy tutaj jego totalne podstawy.
Jeśli znasz javę to widzisz podobieństwa i różnice, a jak jesteś doświadczonym programistą to od razu widzisz co warto użyć czy czerpać z groovy'ego.

Parę rzeczy jest naprawdę fajnych np closure czy obsługa xml , json etc.

Moje praktyki to :

Model POGO uzyskuje używając lomboka jest po prostu zajebisty.
Wyrafinowane operacje na kolekcjach i Stringach wykonuje stosując Guave ona jest znowu wykurwista.

To po co mi do cholery ten groovy ?
Ano po to, żeby udoskonalać gradle i stosować mix metodyk podczas wytwarzania softu.
Robić coś prościej i minimalizować ilość kodu.
No i testy : spock ... oczy śmieją się same:)
Na koniec KATA.

Jeśli uważasz, że pisze bzdury  to w następnych postach udowodnię Ci używając branch'y git'a i porównując przykładowe projekty w narzędziu kontroli jakości sonar.

Pierwszy projekt to będzie projekt pisany po 'staremu' w javie.
Natomiast  drugi projekt skorzysta ze wszystkich dobrodziejstw, które dziś w tym poście wymieniłem.

Statystyki higieny kodu będą porażające. Czytelność również i doświadczysz tego empirycznie...



przykładowy kod do tego posta znajdziesz  (klasa groovy, lombok , spock ) tutaj.

Pamiętaj też, że blog cały czas żyje. Tzn jutro już może nastąpić modyfikacja każdego posta , o jakieś wartościowe informacje i tak samo jest z repo na githubie !!!
Przykłady będą sukcesywnie rozwijane.

Bardziej wyrafinowane rzeczy z języka  groovy pokaże Wam potem w następnych postach.


czyli cdn.




wtorek, 14 stycznia 2014

Clean code - wprowadzenie część 2


Programowanie to gra zespołowa.
Każdy gra na swojej pozycji najlepiej jak potrafi i pomaga kolegą zespołu z całej swojej mocy, jeśli tego potrzebują. Asertywność jest jednak wskazana.

Uważnie dobieraj słowa, aby nie zostać źle odebranym.
Niektóre słowa mają wiele różnych kontekstów.
Np jeśli zbliża się koniec terminu i PM prosi Cię o przyspieszenie sprinta np o cztery dni.
Odpowiadając, że spróbujesz przyznajesz, że masz jaki nowy plan.Ale czy aby na pewno go masz ?
Jak będą się różniły Twoje działania do działań bieżących ?
Chyba, że duże rezerwy czasowe do pracy po pracy wtedy jeszcze taka odpowiedz ma jakikolwiek sens.
Inaczej jest to okłamywanie siebie i swojego przełożonego.

Mantra:
Pamiętaj : Dobry kod jest łatwy w konserwacji i w prosty sposób modyfikowalny od kątem nowych funkcjonalności.


Jeśli czegoś nie zdążysz zrobić, powiedz to szczerze wcześniej.
Im wcześniej to zrobisz tym więcej czasu dasz zespołowi na podjęcie określonych działań.
Czy chciałbyś żeby kolega z którym umówiłeś się na browara czekał bez końca jak Ty utknąłeś w korku.
Lepiej szczerze przedstawić mu sytuacje. Reaguj od razu niż później tłumacz się bezsensownie - ale przecież był korek a to nie jest zależne ode mnie.

Podobnie wygląda sprawa z naprawą bug'a. Jeśli nie możesz sobie z nim poradzić a spędziłeś już nad nim wystarczająco dużo czasu po prostu śmiało zakomunikuj ten problem.

Dyscyplina zobowiązań
Masz do wykonania konkretny task.
Możesz pokusić się aby pominąć potrzebną już refaktoryzację, pisanie testów itd.
I to jest właśnie to miejsce kiedy poznasz prawdziwego profesjonalistę.
Właśnie w tym miejscu popełniasz duży błąd. W tym momencie już nic nie pójdzie szybciej. Pominięcie refaktoryzacji czy testów nie przyspieszy realnie prac.
Tego uczą lata doświadczenia. Powstały zysk jest złudny.
Poza tym jako profesjonalista powinieneś zachowywać wysokie standardy i być marką dla siebie samego oraz innych.


Umiejętność wyszukiwania własnych błędów jest ważna


Praca z kodem.
 - kod musi działać. Dbaj o szczegóły.
 - rozwiązywać problemy biznesowe. Wychwyć te rozbieżności i skieruj kod na właściwy tor
  - kod musi dobrze dopasowywać się do systemu. Nie może zwiększać jego sztywności czy nieprzejrzystości. Kod musi być zgody z GRASP i SOLID.
 -  być czytelny dla innych. Kolega musi równie dobrze pracować z Twoim kodem jak i swoim.
 - jeśli jesteś zmęczony. Przestań kodować - odpocznij. Wstań jutro wcześniej i dokończ to np z rana. Najgorszy kod to kod który powstał o 3 nad ranem:)
- kod musi mieć dobrze zdefiniowaną strukturę. Późniejsze obejścia (workaround)  stosowane przez zespół będą dużo kosztowały i spowodują wiele nieprzewidzianych problemów.
 - kod wymaga koncentracji. Jeśli istnieje jakaś rzecz, która Cię zdekoncentruje np choroba dziecka, jest duże prawdopodobieństwo, że popełnisz błędy.


TDD rules!
 - pozwala skrócić czas pracy nad projektem chociaż może wydawać się to niedorzeczne.
 - masz pewność, że kod działa.
 - otrzymujesz regresje w pakiecie
 - masz wysokie pokrycie kodu
 - szybko wyłapujesz problemy i braki w implementacji oraz design'ie.

Prawa TDD:
- nie wolno napisać nawet linii kodu jeśli wcześniej nie napisze do tego testu, który nie zostanie zaliczony
 - nie wolno pisać więcej testów niż to naprawdę potrzebne, żeby test nie został zaliczony.
 - nie wolno napisać więcej produkcyjnego kodu niż trzeba aby test został zaliczony 

Tip: pisz w cyklach !

UAT = Testy akceptacyjne
Testy UAT mają za zadanie wprowadzić odpowiednią komunikację, precyzję oraz jasność do Twojego projektu.
Określają poprawne działanie systemu. Są tworzone w przez testerów, programistów a czasem nawet przez udziałowców danego systemu.
Bardzo ważną cechą jest tu automatyzacja.
Testy UAT nigdy nie powinny być wykonywane ręcznie - wysokie koszta!

Tip : Selenium,  Robot Framework
Tip : Acceptance Test-Driven Development (ATDD)
Tip : Cucumber, Fitnesse

Profesjonaliści powinni od początku wiedzieć, że takie rzeczy się automatyzuje.
Ponadto dobrą praktyką jest aby cześć scenariuszy testowy już podczas tworzenia implementacji przeprowadził sam programista. Odciąża on wtedy zespół QA.

Tip : Automatyzuj testy w formie czytelnej dla osób nie związanych z oprogramowaniem.

Nie przekonałem Cie jeszcze do testów akceptacyjnych ?
Masz tu przykład:
Kolega pracuje nad jakąś logiką biznesową w projekcie X.
Po jakimś czasie inny człowiek z firmy musi przejąć utrzymanie projektu X wraz z poprawieniem nowo wykrytych błędów.
Mając tylko skąpą dokumentację samo wdrożenie się w projekt, o ile to w ogóle możliwe potrwa tygodnie. W tym czasie ten człowiek rzyga już wszystkich. Logika jest pokręcona. Algorytm zupełnie niezrozumiały. Dokumentacja jak to często bywa nie była na bieżąco uaktualniana. Jednym słowem jedna wielka kupa gówna. 
Czy znasz ten stan ?:)

Jako receptę na taki przypadek proponuje właśnie testy akceptacyjne.
Nie ma znaczenia w jakiej technologii i jakim narzędziem zostaną stworzone.
Ważne jest to natomiast aby one istniały.

I tak wracają do naszego przykładu, zamiast zastanawiać się jak np działa logika  przetwarzania jakiś billingów puszczam sobie test Selenium.
Widzę cały przypadek uwieczniony przez samego autoram, lub osoby kompetentnej z QA.
Patrzę gdzie klikał i  jakich danych oczekiwał. Zamiast czytać nieaktualną dokumentacje, mam teraz przypadek wyjęty  prosto z życia aplikacji.
Ładnie zaprojektowany i odpowiednie przetestowany przypadek, który pozwala mi szybko zrozumieć istotę problemu oraz przyspieszyć implementacje i poprawę błędu.
Super !

Tip : Staraj się tworzyć testy UAT w każdej iteracji (sprint)
Tip : CI uruchamia testy UAT
Tip : Task uznaje się zakończony jeśli przejdzie wszystkie  testy w tym UAT i integracyjne
Tip : Staraj się testować wszystko. Proś o pomoc kogoś z QA jeśli masz jakiekolwiek wątpliwości.
Tip : Regresją testów UAT - sprawdź czy nie zepsułeś działającej już funkcjonalności (maszyna CI)
Tip : SRP, MVC dla GUI jako dobra praktyka


Testy jednostkowe - a testy akceptacyjne

Testy jednostkowe są pisane przez programistów dla programistów.
(O dobrych praktykach pisania testów dowiesz się w następnych postach)

Testy akceptacyjne są pisane przez nieprogramistów - dla nieprogramistów.
Są formalnymi dokumentami opisującymi jak powinien zachować się system w danej zasymulowanej  sytuacji.

Tip : Nie wiesz jak się za to zabrać mam na myśli testy UAT (cucumber, selenium + junit integration)) ?
Poproś kogoś bardziej doświadczonego lub sam o tym poczytaj.


Pracuj tak aby team QA był bez pracy.
Pamiętaj jednak, QA jest integralną częścią Twojej drużyny.
Podział testów znajdziesz w tym poście.

Spotkania na stojąco (stand up meeting)

Agenda:
- co będę dzisiaj robił
- co zrobiłem wczoraj
- co mi przeszkadza

Czas spotkania powinien być krótki max 15 minut. Każdy z uczestników odpowiada na pytanie z agendy.

Spotkania planujące iteracje
Omawiamy:

 - wybrane pozycje backlogu, realizowane w następnej iteracji
 - szacujemy pracochłonności tych pozycji
 - ocena oraz wartość biznesowa danej pozycji
 - szkic testów akceptacyjnych
 - każdy kandydat z backlogu może być odrzucony lub zaakceptowany
 - nad każdą pozycją dyskutujemy góra kilka minut w przypadku skomplikowanych problemów należy zebrać tylko ludzi 'zainteresowanych' i stworzyć odrębne spotkanie
 
Retrospekcja iteracji i demonstracja produktu
Następuje po końcu każdej iteracji.
Członkowie zespołu wymieniają się poglądami co poszło dobrze a co źle.
Jaki element sprintu możemy przyspieszyć, co ulepszyć  i w jaki sposób to osiągnąć.

Ślepa droga.
Pewnie każdy z nas nie raz spotkał się z takim stanem w swoim dewelopmencie.
Tutaj ważna jest umiejętność rozpoznawania tego typu sytuacji  oraz odwaga aby się z takiej drogi wycofać.
Otwarty umysł to klucz.
W razie ciężkich problemów poproś o radę kogoś bardziej doświadczonego z zespołu.

Tip : Lokalna burza mózgów


cdn.