niedziela, 26 maja 2013

Od Zera Do Matchera

To jest materiał podstawowy, który przygotowałem do wewnętrznej prezentacji w pracy. Jeśli ktoś jest obcykany w matcherach niech nie traci czasu i poczyta sobie lepiej jakieś dzieła w stylu trzynastej księgi Pana Tadeusza.

Jeśli jednak ta tematyka jest Ci obca to zapraszam do lektury

Domena

Domenę biznesową tworzą dwie klasy - piosenka i techno mikser

 

public class Song {

 private String title;

 private int numberOfBits;
 
 public Song(String title,int numberOfBits) {
  this.title = title;
  this.numberOfBits = numberOfBits;
 }

 public void play(){
  System.out.println("plying "+title);
 }
 
 public String getTitle() {
  return title;
 }
 
 public int getNumberOfBits() {
  return numberOfBits;
 }
}

 

public class TechnoMixer {
 public List makeTechnoMix(Song... originalSongs){
  int technoMultiplier = 2;
  String technoPostfix = "_techno_mix";
  return mixSongs(technoMultiplier, technoPostfix, originalSongs);
 }
 
 public List makeThunderdomeMix(Song... originalSongs){
  int thunderdommeMultiplier = 4;
  String thunderdommePostfix = "_thunderdomme_mix";
  return mixSongs(thunderdommeMultiplier, thunderdommePostfix,
    originalSongs);
 }

 private List mixSongs(int bitsMultiplier,
   String titlePostfix, Song... originalSongs) {
  List mixedSongs=new ArrayList<>();
  for (Song originalSong : originalSongs) {
   int newNumberOfBits=originalSong.getNumberOfBits()*bitsMultiplier;
   String newTitle=originalSong.getTitle()+ titlePostfix;
   mixedSongs.add(new Song(newTitle, newNumberOfBits));
  }
  return mixedSongs;
 }
}

Działanie jest proste - TechnoMixer zwyczajnie zwiększa ilość bitów znacząco podnosząc komfort słuchania piosenki :) No i odpowiednio modyfikuje tytuł utworu oznajmując wszem i wobec, że słuchamy lepszej jej formy

Spróbujmy to przetestować...

Test próba pierwsza

 

@Test
public void shouldMixSongsToTechno() {
 //given
 Song equador=new Song("Equador", 100);
 Song onaTanczyDlaMnie=new Song("Ona Tanczy Dla Mnie", 50);
 Song harlemShake=new Song("Harlem Shake", 150);

 //when
 List mixes = technoMixer.makeTechnoMix(equador,onaTanczyDlaMnie,harlemShake);
 
 //then
 Assert.assertEquals(mixes.get(0).getNumberOfBits(), 200);
 Assert.assertEquals(mixes.get(1).getNumberOfBits(), 100);
 Assert.assertEquals(mixes.get(2).getNumberOfBits(), 300);
 
 Assert.assertEquals(mixes.get(0).getTitle(), "Equador_techno_mix");
 Assert.assertEquals(mixes.get(1).getTitle(), "Ona Tanczy Dla Mnie_techno_mix");
 Assert.assertEquals(mixes.get(2).getTitle(), "Harlem Shake_techno_mix");
}

Testy przechodzi ale wygląda kiepsko - a pamiętajcie, że to tylko prosty przykład. Przy bardziej skomplikowanych obiektach będzie jeszcze więcej syfu.

Test próba druga - zewnętrzna metoda

 

@Test
public void shouldMixSongsToTechno2() {
 //given
 Song equador=new Song("Equador", 100);
 Song onaTanczyDlaMnie=new Song("Ona Tanczy Dla Mnie", 50);
 Song harlemShake=new Song("Harlem Shake", 150);

 //when
 List mixes = technoMixer.makeTechnoMix(equador,onaTanczyDlaMnie,harlemShake);
 
 //then
 assertThatSongsHaveBits(mixes,200,100,300);
 assertThatSongsHaveTitles(mixes,"Equador_techno_mix","Ona Tanczy Dla Mnie_techno_mix","Harlem Shake_techno_mix");
}


private void assertThatSongsHaveBits(List mixes, int... expectedBites) {
 for (int currentSongNumber = 0; currentSongNumber < expectedBites.length; currentSongNumber++) {
  Assert.assertTrue(mixes.get(currentSongNumber).getNumberOfBits()==expectedBites[currentSongNumber]);
 }
}

private void assertThatSongsHaveTitles(List mixes, String... expectedTitles) {
 for (int currentSongNumber = 0; currentSongNumber < expectedTitles.length; currentSongNumber++) {
  Assert.assertEquals(mixes.get(currentSongNumber).getTitle(),expectedTitles[currentSongNumber]);
 }
}

Test wygląda już czytelniej. Metody są bliźniaczo podobne ale nie będziemy ich jeszcze refaktorować. Na razie zastanówmy się nad kilkoma rzeczami :

  • Czy wywołanie może być jeszcze czytelniejsze
  • Czy można gdzieś przenieść metody pomocnicze aby nie zaśmiecały testu
  • Zakłądając, że w bardziej skomplikowanej domenie obiekt Song mógłby wystąpić w większej ilości testów - czy można zrobić jakoś tak aby metod "reużyć"?

Można!

Matcher - wersja pierwsza

 

@Test
public void shouldMixSongsToTechnoWithMatcher() {
 //given
 Song equador=new Song("Equador", 100);
 Song onaTanczyDlaMnie=new Song("Ona Tanczy Dla Mnie", 50);
 Song harlemShake=new Song("Harlem Shake", 150);

 //when
 List mixes = technoMixer.makeTechnoMix(equador,onaTanczyDlaMnie,harlemShake);
 
 //then
 SongMatcher.assertThat(mixes).haveBits(200,100,300).and().titles("Equador_techno_mix","Ona Tanczy Dla Mnie_techno_mix","Harlem Shake_techno_mix");
}

 

public class SongMatcher {

 private List songs;

 public SongMatcher(List songs) {
  this.songs = songs;

 }

 public static SongMatcher assertThat(List songs) {
  return new SongMatcher(songs);
 }

 public SongMatcher haveBits(int... expectedBits) {
  for (int currentSongNumber = 0; currentSongNumber < expectedBits.length; currentSongNumber++) {
   Assert.assertEquals(expectedBits[currentSongNumber],songs.get(currentSongNumber).getNumberOfBits());
  }
  return this;
 }

 public SongMatcher titles(String... expectedTitles) {
  for (int currentSongNumber = 0; currentSongNumber < expectedTitles.length; currentSongNumber++) {
   Assert.assertEquals(expectedTitles[currentSongNumber],songs.get(currentSongNumber).getTitle());
  }
  return this;
 }

 public SongMatcher and() {
  return this;
 }

}

Test wygląda już ok ale w matcherze mamy te jakże podobne do siebie metody. A Gdyby tak obiekt miał 10 własności? Czas na jakiś refaktoring - na tyle na ile znam refleksję to wyjdzie coś takiego....

Matcher - wersja druga

 

public class SongMatcher2 {
 private List songs;

 public SongMatcher2(List songs) {
  this.songs = songs;

 }

 public static SongMatcher2 assertThat(List songs) {
  return new SongMatcher2(songs);
 }

 public SongMatcher2 haveBits(Integer... expectedBits) {
  assertValueOnProperty("NumberOfBits",expectedBits);
  return this;
 }
 
 public SongMatcher2 titles(String... expectedTitles) {
  assertValueOnProperty("Title",expectedTitles);
  return this;
 }


 private void assertValueOnProperty(String fieldName, Object[] expectedBits) {
  Assert.assertNotNull(songs);
  Assert.assertFalse(songs.isEmpty());

  try {
   assertValueOnPropertyUnsafely(fieldName, expectedBits);
  } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   throw new RuntimeException(e);
  }
  
 }

 private void assertValueOnPropertyUnsafely(String fieldName,
   Object[] expectedBits) throws NoSuchMethodException,
   IllegalAccessException, InvocationTargetException {
  Method methodToInvoke = songs.get(0).getClass().getDeclaredMethod("get"+fieldName);
  for (int currentNumberOfValue = 0; currentNumberOfValue < expectedBits.length; currentNumberOfValue++) {
   Song currentSong = songs.get(currentNumberOfValue);
   Object invokeResult = methodToInvoke.invoke(currentSong,new Object[0]);
   Assert.assertEquals(expectedBits[currentNumberOfValue], invokeResult);
  }
 }

 

 public SongMatcher2 and() {
  return this;
 }
}

No i uważne oko zauważy, że wykształcił nam się taki matcher w matcherze. Zakładając, że obiektów w domenie będzie więcej to być może znowu jakoś tę logikę z refleksją da się gdzieś tam ładnie udostępnić. Możemy alb o delegować albo dziedziczyć. Niby książki mówią, żeby delegować ale tutaj z powodów nad którymi teraz nie chce mi się rozwodzić będziemy dziedziczyć.

Matcher - wersja trzecia

 

public class BaseMatcher {

 protected List objectsUnderTest;
 
 public BaseMatcher(List objectsUnderTest) {
  this.objectsUnderTest = objectsUnderTest;
 }

 protected void assertValueOnProperty(String fieldName, Object[] expectedValues) {
  Assert.assertNotNull(objectsUnderTest);
  Assert.assertFalse(objectsUnderTest.isEmpty());

  try {
   assertValueOnPropertyUnsafely(fieldName, expectedValues);
  } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   throw new RuntimeException(e);
  }
  
 }

 private void assertValueOnPropertyUnsafely(String fieldName,
   Object[] expectedBits) throws NoSuchMethodException,
   IllegalAccessException, InvocationTargetException {
  Method methodToInvoke = objectsUnderTest.get(0).getClass().getDeclaredMethod("get"+fieldName);
  for (int currentNumberOfValue = 0; currentNumberOfValue < expectedBits.length; currentNumberOfValue++) {
   Object currentObject = objectsUnderTest.get(currentNumberOfValue);
   Object invokeResult = methodToInvoke.invoke(currentObject,new Object[0]);
   Assert.assertEquals(expectedBits[currentNumberOfValue], invokeResult);
  }
 }

 

 public BaseMatcher and() {
  return this;
 }
}

 

public class SongMatcher3 extends BaseMatcher{

 public SongMatcher3(List songs) {
  super(songs);
 }

 public static SongMatcher3 assertThat(List songs) {
  return new SongMatcher3(songs);
 }

 public SongMatcher3 haveBits(Integer... expectedBits) {
  assertValueOnProperty("NumberOfBits",expectedBits);
  return this;
 }
 
 public SongMatcher3 titles(String... expectedTitles) {
  assertValueOnProperty("Title",expectedTitles);
  return this;
 }
}

Na razie możemy testować tylko listy ale to na potrzeby przykładu i jeszcze do tego wrócimy. Wygląda całkiem obiecująco ale pojawia się pewien problem otóż kompilator zgłasza błąd w teście :

 

@Test
public void shouldMixSongsToTechnoWithMatcher3() {
 //given
 Song equador=new Song("Equador", 100);
 Song onaTanczyDlaMnie=new Song("Ona Tanczy Dla Mnie", 50);
 Song harlemShake=new Song("Harlem Shake", 150);

 //when
 List mixes = technoMixer.makeTechnoMix(equador,onaTanczyDlaMnie,harlemShake);
 
 //then
 SongMatcher3.assertThat(mixes).haveBits(200,100,300).and();// O TUTAJ JEST BŁĄD .titles("Equador_techno_mix","Ona Tanczy Dla Mnie_techno_mix","Harlem Shake_techno_mix");
}

Dzieje się tak dlatego, że nasz matcher bazowy nic nie wie o metodach matchera domenowego. Ostatni szlif i ostatnia sztuczka własnie przed nami. Musimy jakoś tę wiedzę do nadklasy przekazać.

Matcher - wersja czwarta

 

public class BaseMatcher2 {

 private K self;
 
 protected List objectsUnderTest;
 
 public BaseMatcher2(List objectsUnderTest,Class selfClass) {
  this.objectsUnderTest = objectsUnderTest;
  this.self=selfClass.cast(this);
 }

 protected void assertValueOnProperty(String fieldName, Object[] expectedValues) {
  Assert.assertNotNull(objectsUnderTest);
  Assert.assertFalse(objectsUnderTest.isEmpty());

  try {
   assertValueOnPropertyUnsafely(fieldName, expectedValues);
  } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   throw new RuntimeException(e);
  }
  
 }

 private void assertValueOnPropertyUnsafely(String fieldName,
   Object[] expectedBits) throws NoSuchMethodException,
   IllegalAccessException, InvocationTargetException {
  Method methodToInvoke = objectsUnderTest.get(0).getClass().getDeclaredMethod("get"+fieldName);
  for (int currentNumberOfValue = 0; currentNumberOfValue < expectedBits.length; currentNumberOfValue++) {
   Object currentObject = objectsUnderTest.get(currentNumberOfValue);
   Object invokeResult = methodToInvoke.invoke(currentObject,new Object[0]);
   Assert.assertEquals(expectedBits[currentNumberOfValue], invokeResult);
  }
 }

 public K and() {
  return self;
 }
}

 

public class SongMatcher4 extends BaseMatcher2{

 public static SongMatcher4 assertThat(List songs) {
  return new SongMatcher4(songs);
 }

 public SongMatcher4(List objectsUnderTest) {
  super(objectsUnderTest, SongMatcher4.class); 
 }

 public SongMatcher4 haveBits(Integer... expectedBits) {
  assertValueOnProperty("NumberOfBits",expectedBits);
  return this;
 }
 
 public SongMatcher4 titles(String... expectedTitles) {
  assertValueOnProperty("Title",expectedTitles);
  return this;
 }
}

Teraz powinno być ok

Co dalej?

Jak już wcześniej zwróciliśmy uwagę powyższe matchery nadają się jedynie do testowania list. Można by klasę bazową zamienić w fabrykę wyspecjalizowanych matecherów co ma sens bo testowania czy ilość elementów jest większa od zera nie ma sensu dla pojedynczych obiektów. I coś takiego jest już gotowe, nazywa się FEST i gorąco polecam

Co Jeszcze?

Przy okazji pisania artykułu użyłem JUnit 4.11, który ma nowy ciekawy patent : @FixMethodOrder(MethodSorters.NAME_ASCENDING). Od czasu przesiadki na Javę 7 JUnit zaczął wywoływać metody w losowej kolejności co czasami psuje testy integracyjne bo tam np. testując flow transformacji plików dla zaoszczędzenia czasu kolejne testy korzystają ze stanu pozostawionego przez poprzednie fazy. A ta małą adnotacja działa jak do rany przyłóż.

wtorek, 21 maja 2013

GeeCON 2013 - rekonstrukcja zdarzeń

Programowanie Funkcyjne

Ten temat pojawił się trzeciego dnia, więc pamiętam go najlepiej bo jako odpowiedzialny kierowca byłem wtedy trzeźwy i wyspany. Generalnie do czasu tej konferencji programowanie funkcyjne kojarzyło mi się jedynie z przetwarzaniem danych pomiędzy zbiorami gdzieś tam wewnątrz aplikacji (tak jak na matematyce dyskretnej w klasie 1 studiów). Aż tu na jednej prezentacji pojawił się rysunek podobny do poniższego (odtworzone z pamięci) :

Pewnie dla wyjadaczy scali, klołżerów i innych takich ten temat jest oczywisty jak składanie pita37 ale dla mnie to był moment oświecenia, że jako funkcję można przedstawić dowolne "coś" co dostaje na wejściu "cokolwiek" i zwraca "coś innego". I teraz taki Wzorzec Dekorator wydaje się być hakiem na obiekcie gdzie czymś bardziej naturalnym byłoby wywołanie f(g(x)) albo F(f1(x),f2(x),...) - jeśli dobrze zrozumiałem F to funkcja wyższego rzędu a fn funkcje niższego rzędu - czyli tutaj to mogą być np poszczególne walidatory w trakcie jednej wielkiej walidacji.

Jest jeszcze jedna ciekawa a być może nawet ważniejsza korzyść jaką może przynieść programowanie funkcyjne. Generalnie we wszystkich książkach o OOP we wstępie jest napisane, że właśnie ten sposób jest naturalny dla ludzi i dlatego wszystko pójdzie gładko. A to gówno prawda bo ludzie myślą w sposób proceduralny przez co bliżej nam do programowania imperatywnego co ma swoje potwierdzenie w kodzie większości studentów - masa ponakładanych na siebie ifów,forów i innego świństwa zamkniętych w 8000 linijkową metodę.

A jeśli do kogoś to nie przemawia to niech pomyśli sobie co dzieje się w jego głowie gdy idzie pozmywać naczynia po obiedzie:

Czy coś takiego :

Mam do dyspozycji obiekt klasy Zlew, obiekt klasy Ludwik oraz kolekcję obiektów klasy NAczynie oraz obiekt klasy Człowiek (czyli JA)

 
zlew.umieść(naczynia)
ludwik.nalejDo(zlew)
kran.odkręć()
ja.zmyjNaczynia(zlew)


Czy Może naturalniej jednak będzie :

Jest do pozmyawania sterta naczyń
 
JA muszę wrzucić te wszystkie naczynia do zlewu
JA muszę teraz odkręcić wodę 
JA muszę teraz nalać ludwika
JA teraz dla każdego talerza
      muszę go umyć
      jeśli jest już czysty 
          to JA go odłożę na suszarkę
      jeśli nie
          to JA go myję dalej
      W międzyczasie zakręcę wodę
      Dobra zrobię sobie krótka przerwę
      (...)
      
No jeśli ktoś myśli o abstrakcjach i interfejsach w trakcie zmywania naczyń to jakieś dobre zioło namierzył albo po ASPięknych.

Generalnie zarówno programowanie obiektowe jak i funkcyjne nie jest naturalne dla naszego umysłu ALE. Klasy i obiekty to wynalazek greckich filozofów i chyba ktoś ich kalibru ma odpowiednie doświadczenie aby stworzyć poprawny model obiektowy. W przeciwieństwie do humanistycznej obiektówki programowanie funkcyjne opiera się na zrozumieniu ścisłych zasad matematyki. A enkapsulacja i re-używalność jest równie dobra.

?Nowe spojrzenie na dług techniczny

Temat długu technicznego, kompatybilności wstecz, dodawania nowych ficzerów itd pojawił się na kilka prezentacjach pierwszego i drugiego dnia. I w sumie tutaj tez jest mały mindfuck bo do tej pory TechDebt traktowałem jako coś bezpośrednio związanego z jakością kodu i architekturą systemu.

A tutaj pojawia się taka ciekawostka. Jeśli mamy np. takie wymagania :

  • Zrobić funkcjonalność 1
  • Zrobić funkcjonalność 2
  • Zrobić funkcjonalność 3


To one tak naprawdę brzmią

  • Zrobić funkcjonalność 1
  • Zrobić funkcjonalność 2 i nie popsuć funkcjonalności 1
  • Zrobić funkcjonalność 3 i nie popsuć funkcjonalności 1 i też nie popsuć funkcjonalności 2

No to teraz jeśli założymy, że mamy w naszym systemie N (dla uproszczenia) podobnych funkcjonalności, to koszt dodania funkcjonalności N+1 będzie:

  • Tam gdzie jakimś cudem osiągnęliśmy legendarny poziom modularyzacji - Cost~F(n+1)
  • Tam gdzie ficzery są od siebie zależne ale system jest gotowy na rozbudowę - Cost~F(n+1) + M(n) - gdzie M(n) koszt utrzymania przy życiu pozostałej części systemu
  • Tam gdzie jest skomplikowana interakcja (zamierzona lub nie) pomiędzy ficzerami - Cost~F(n+1)+M(n^2)
  • Tam gdzie gówno pływa swobodnie po kodzie, "big ball of mud" i wszystko jest powiązane ze wszystkim w 10000 linijkowych klasach nazwanych "Menażer" - Cost~F(n+1)+M(2^n)

Oczywiście poprzez refkatoringi, metodyki projektowe i inne takie można poprawić charakterystykę funkcji kosztu ALE - można też zmniejszyć pracochłonność zmniejszając N poprzez usunięcie częsci fukncjonalności. Niby szok kulturowy bo funkcjonalność - szczególnie ta działająca - zarabia dla nas pieniądze - no poza momentami kiedy ich nie zarabia!

Kiedyś czytałem w focusie artykuł o ludziach, którzy patologicznie kolekcjonują rzeczy przez co nie mogą się poruszać po swoim mieszkaniu. U mnie w komórce przez 10 lat też leżały jakieś deski bo a nuż kiedyś się przydadzą. Nikt ich nie używał to poszły na przemiał i podobnie trzeba wywalać jakieś dziwne opuszczone ficzery aplikacji, których nikt nie używa. Czyli nowy rodzaj długu technicznego : doskonale działąjąca funkcjonalność, której (praktycznie) nikt nie używa

Inne takie

Inna ciekawa rzecz to : http://code.google.com/p/spock/ w sumie fajna rzecz ale na Groovym . Po PHP trzymałem się z dala od języków dynamicznych ale trzeba się chyba przemów.

czwartek, 9 maja 2013

Jak się nie odkleić od rzeczywistości - lekarstwo na zarządzanie zasobami.

Odczuwam pierwsze objawy choroby, z którą zawsze walczyłem. Przez lata widziałem jak ludzie sprowadzani do roli pionka w projekcie zamieniają się w zombie pozbawione pasji. Wszędobylski palec wskazujący wsparty lśniącym gantem stanowił narzędzie wyroczni określającej byt pokornej jednostki ( w sensie - "ty Zdzichu tera robisz to i masz na to dwie godziny").

Odczuwam pierwsze objawy choroby, z którą zawsze walczyłem. Kiedy jesteś odpowiedzialny tylko za swoją pracę to dostaniesz wpi***** tylko za swoją pracę. Kiedy jesteś odpowiedzialny za pracę wielu to cios może przyjść z każdej strony. Umysł sam zaczyna się bronić szukając wszędzie potwierdzenia, że jesteśmy kryci - "czy to już jest gotowe" lub " na kiedy to będzie skończone" . Kiedy sam sobie piszesz kod doskonale wiesz na jakim etapie jesteś - kiedy masz dostać wpi**** za czyjś kod nagle zaczyna cię bardzo ciekawić na jakim etapie on jest - chyba dlatego ci ludzie zawsze tak bardzo wielbili raporty...

Odczuwam pierwsze objawy choroby, z którą zawsze walczyłem... i będę walczył dalej. Najpierw trzeba zrozumieć objawy, później opracować lekarstwo...

Objawy

Objawy są naturalne i występują u wszystkich znajdujących się w określonej sytuacji - no może prawie wszystkich. Aby to sobie przećwiczyć zerknijmy na obrazek powyżej, który pochodzi z gry kolonizacja. Jeśli ktoś o niej nie słyszał to idea w uproszczeniu wygląda tak - dopływamy do brzegu w 1492 roku, tworzymy miasto a w nim zbieramy surowce i produkujemy towary. Jeśli akurat z Europy wyemigruje specjalista to będziemy zbierać tych zasobów i produkować towarów więcej. Ale z drugiej strony jak już na przykład nazbieramy odpowiednio dużo rudy żelaza to przerzucamy górnika do pasania świń bo tak maksymalizujemy zyski miasta. Brzmi znajomo?

Widziałem to wiele razy w projektach bazujących na ganto-excelu - Dobra tego taska mamy zrobionego to przesuńmy risorsa do łatania layoutów, a później zbierzemy resztę risorsów do aktualizacji dokumentacji

Ba byłem nawet na studiach dla managerów i widziałem na własne oczy Ćwiczenia z MS Projecta polegające na "zrobieniu tak aby paski były zielone" . I ch** kogo obchodziło, że programista nazwany przez instrukcję ćwiczenia "Janem" będzie pracował przez 3 godziny and jednym taskiem, później przez godzinę nad innym i na koniec na godzinę wróci do pierwszego. Grunt, ze gantt będzie zielony.

No i pamiętam jak w jednej takiej firmie zawsze na koniec dnia manager robił obchód po sali i podbijał do każdego "raportuj, raportuj gdzie jesteś na gancie" - not kool , not f*** kool

Umysł dąży do uproszczenia modelu. A jeśli do tego psychika danego człowieka jest na etapie "jak najlepiej zaspokoić moje potrzeby" to mamy gotowy przepis na ganta-style-managera.

Co można z tym zrobić jeśli już sobie uświadomimy problem? Natura, mechanika czy elektronika już znalazły rozwiązanie. Co ma wspólnego układ hormonalny, lodówka i tranzystor z napięciem zasilania Baza-Kolektor?

Ujemne sprzężenie zwrotne!

Zaciśnij dłoń i uderz nią w ścianę - powinno zaboleć co powstrzyma cię przed kontynuowaniem tej czynności (no chyba, że bardzo to lubisz) - właśnie zostałeś poddany działaniu ujemnego sprzężenia zwrotnego. Jak tę koncepcję zastosować w IT? - proste - Jak już coś wymyśliłeś to musi cię to też zaboleć. Można to łatwo osiągnąć będąc cały czas blisko kodu. Ta koncepcja została ładnie opisana w tej książce ---> http://37signals.com/rework - wszystkie ręce na front! - jak już coś obiecałeś to też się przy tym namęczysz. A przy okazji będziesz wiedział co się dzieję w projekcie i nie będziesz ludzi męczył pytaniami (no dobra w praktyce na razie mi to tak w 90% przypadków wychodzi)

Dlatego cały czas intuicyjnie byłem przeciwny koncepcji team lidera, który biega sobie tylko na spotkania, naobiecuje i deleguje. Powiedziałem moim mocodawcom, że chcę być jak Mel Gibson w Patriocie (przełożeni z USA) z bagnetem na pierwszej linii frontu aniżeli jak jakiś generał siedzieć wygodnie w namiocie spokojnie przesuwający figury na mapie

No i akurat w tym tygodniu ktoś wrzucił taki fajny symboliczny rysunek na fejsa :

niedziela, 21 kwietnia 2013

Co nas motywuje i dlaczego korpo-targety nie działają

Lista tzw. motywatorów wewnętrznych :

Wolność

Dążenie do mistrzostwa

Poczucie celu

Mam nadzieję, że każdy kto codziennie kładzie ręce na klawiaturze będzie się identyfikował z tymi trzema wartościami. Nie jest to przypadkowy zbiór ale wynik poszukiwań, które przeprowadził autor książki --> Drive: The Surprising Truth About What Motivates Us. Znajdziecie tam masę przykładów potwierdzających ten wybór jakkolwiek jeśli komuś nie chce się do książki sięgać ( a pewnie nikomu teraz nie chce się tam sięgać) krótkie wsparcie dla tych dogmatów.

  • wolność/autonomia : generalnie my jako ludzie dążymy do sytuacji, w której mamy raczej większe pole manewru, większe możliwości wyboru aniżeli mniejsze - chyba standardowe zachowanie w świecie zwierząt. Ale jest jeszcze ważniejsza rzecz - posiadając autonomię pracujesz na swoje konto (poniekąd) i możesz łatwiej zwiększyć swoją wartość w grupie. Jest jednakże jedna sytuacja, w której z radością zrzekniesz się wolności wyboru - sytuacja w której nie masz umiejętności (w korpo-języku - kompetencji) aby poradzić sobie z daną sytuacją. Na przykład w sytuacji gdy na ulicy zaatakuje mnie dziki lew (a dlaczego nie) z chęcią zrobię dokładnie to co mi powie jakiś specjalista od "przeżycia spotkania z lwem" (tak tutaj właśnie działa zasada autorytetu tak ochoczo wykorzystywana przez twórców reklam z pastami do zębów). W tej sytuacji jestem zależny od pomocy z zewnątrz a nasz umysł nie lubi być zależny - ma naturalną motywację aby nie być zależnym, aby być wolnym - i naturalnie dochodzimy do kolejnego punktu.
  • dążenie do mistrzostwa : no to jak już się nauczę walki z lwami to nie dość, że łatwiej mi przetrwać bo nie jestem zależny od zewnętrznej siły to dodatkowo wśród znajomych jestem znany jako "koleś który zna się na walce z lwami" (a na nasze - "to jest koleś, który zna się na Javaskrypcie") - ego jest dopieszczone a wartość społeczna rośnie. No chyba, że nie za bardzo umiejętność walki z lwami jest do czegoś potrzebna i tutaj pojawia się kolejna potrzeba
  • poczucie celu : i tutaj wskazówka -" maksymalizacja zysków firmy" w kontekście motywacji wewnętrznej nie jest celem jako takim dla większości ludzi, którzy w tej firmie pracują. Korporacje starają sobie wymyślić jakieś wizje i inne takie - skuteczność tych technik pozostawię wam do oceny. Jako ludzie chcemy być częścią czegoś większego ale nie jakimś tam trybikiem ale realną siłą która to coś kształtuje. W jednym z artykułów o "Valve" (taka firma bez managerów, która zarabia miliony na produkcji gier i jest dobrym przykładem zastosowania wspomnianych tu wartości) przeczytałem, ze w holyłudzie przemysłowi udało się zabić wszelką kreatywność w zawodzie grafika i potworzyły się takie specjalizacje jak "specjalista od tworzenia nosów". Czy tworząc nos jednej z postaci we władcy pierścieni identyfikowałbyś się z celem tworzenia tego filmu i czuł przepływającą przez ciebie moc tworzenia?

I teraz pojawiają się korpotargety...

... i ogromne nieporozumienie pod tytułem "pieniądze zabijają wewnętrzną motywację". Coś zupełnie innego zabija tutaj wewnętrzną motywację.

Przykład pierwszy - mierzenie efektywnośc

Powyższy ciąg myślowy może prowadzić do najbardziej patologicznych targetów w IT - nagradzanie/karanie programistów w zależności od tego ile napisali linii kodu. Inne chore pomysły to np. mierzenie ilości klas czy czasu spędzonego przy komputerze. Znam jednego dziadka, który zaproponował następujący sposób mierzenia efektywności programisty : Zmierzyć Velocity zespołu w jednym sprincie, następnie usunięcie "badanego członka" i zmierzenie Velocity teamu bez tej osoby - to jest przerażające. Tam gdzieś są osoby, które naprawdę tak myślą - oni mogą zrobić wiele krzywdy!

A jeśli czyta to ktoś z poza IT, kto nie rozumie braku sensu w przedstawionych pozycjach to już tłumaczę - ocenianie pracy programisty przy pomocy ilość napisanych linii kodu ma tyle samo sensu co ocenianie efektywności sprzedawcy na podstawie tego ile słów wypowie w trakcie rozmowy z klientem.

Podsumujmy :
Wolność MistrzostwoPoczucie celu
Zabita - jesteś zmuszony, po prostu zmuszony pisać więcej kodu niż potrzeba. Zamiast "dobrego kodu" produkujesz "duży kod" Poniekąd zabite - bo zamiast szkolić się w tym co potrzebne szkolisz się w tym co niepotrzebne ale nagradzane Zabite - bo to kompletnie nie ma sensu.

No można by mierzyć ilość dostarczonej funkcjonalności ale :

  1. W waterfailu i tak to nie ma znaczenia bo już jakiś wana-be-manager zaplanował 13 miesięcy wcześniej ile funkcjonalności będzie dostarczone.
  2. A w edzajlu,a w edzajlu problem jest taki, że Hrowa teoria mówi : "oceniajmy indywidualnie" - ej stary zrobisz mi code review? - spadaj realizuję swoje indywidualne cele....

Teraz w kontekście frazy "pieniądze zabijają wewnętrzną motywację". Jeśli siedzę sobie przy klawiaturze i ktoś wylewa na mnie wiadro z gównem i płaci za to powiedzmy 15% moich rocznych zarobków to mimo wszystko czuje się zdemotywowany. Nie czuję się zdemotywowany tym, że ktoś mi płaci ale tym, że siedzę zanurzony w gównie i najważniejsze - nie ma takiej sumy przy której gówno nagle przestaje śmierdzieć. Tak samo nie zacznę czuć nagle wewnętrznej motywacji przy określonej sumie pieniędzy - zacznie się jednak dziać co dla badaczy było niesamowite - płacąc więcej będę jeszcze mniej efektywniejszy - ejjj helołłłł! - ja nie lubię siedzieć w gównie - jak szybciej uzbieram swoją kasę to po prostu przestanę siedzieć w gównie. Tak samo np. jak zapłacicie milion złotych programiście , który siedzi w Informatycznym łajnie to jego efektywność nagle spadnie bo koleś pójdzie do kuchni na kawę i będzie miał to wszystko gdzieś - kasa jest odłożona. No niesamowite.

Przykład drugi - mierzenie jakości

Tutaj może powstać cel - pokrycie kodu minimum 60% ( a w patologicznym wypadku 100%). To jest bardziej chytre i bardziej kontrowersyjne niż poprzedni przykłąd. A to dlatego, że wielu wyznawców niejakiego wujka Bobra na prawdę wierzy, że trzeba mieć pokrycie 100%. Pierwsza kwestia to nie pamiętam kiedy ostatni raz wygenerowany przez eclipse getter nie działał. A druga ważniejsza kwestia to coś co trzeba wyczuć - siedzisz przy klawiaturze i piszesz kod albo najpierw test a później kod - nieważne - ważne jest to, że w pewnym momencie przestajesz myśleć czy wszystkie przypadki testowe masz już ogarnięte zaczynasz myśleć czy to co napisałeś już ci wygeneruje odpowiednie pokrycie. Kolega z jednej firmy kiedyś wspominał, że mają nawet taką stronkę gdzie teamy się lansują ile który ma pokrycia. I jak ich pokrycie sprawia to dzwoni manager z zagranicy i mówi "chłopaki zróbcie coś z tym bo jesteśmy już na 3 miejscu" - no to chłopaki dorzucają kilka testów z pustymi asercjami...

I ponownie to nie pieniądze zabijają tutaj motywacje ale gówno sączące się ze szlauchu

Wolność MistrzostwoPoczucie celu
Zabita - nie piszemy testów dla testowania ale jesteśmy zmuszeni, powtarzam zmuszeni do pisania testów dla pokrycia. Zabite - jedyne czego się uczysz to kreatywne sposoby na zwiększenie pokrycia Zabite


To co jest dobre?

Jeszcze dokłądnie nei wiem ale słyszałem mądrego człowieka, który mówił - "disconnecting from revenue is very dangerous" ( czy coś podobnego - ale na pewno po angielsku)

Ps

A no i żeby nie być gołosłownym powtórzyłem przed chwilą po raz kolejny eksperyment naukowy - zmierzyłem poziom mojej motywacji wewnętrznej - później wyciągnąłem pieniądze z bankomatu - wykonałem kolejny pomiar --> pieniądze same w sobie nie zmniejszyły mojej motywacji wewnętrznej - ba nawet trochę czuję się bardziej takim czystym pasjonatem z krwi i kości. Od tej pory daję prawo każdemu pasjonatowi programowaniu do odczuwania motywacji z powodu zarobków.

Uzupełnieniem do dzisiejszego artykułu może być --> http://pawelwlodarski.blogspot.com/2013/04/czy-za-kreatywna-prace-trzeba-pacic.html

niedziela, 7 kwietnia 2013

Czy za kreatywną pracę trzeba płacić?

Trzeba i to dużo...

.. skąd w ogóle pomysł, że mogłoby być inaczej? Niestety często złe rzeczy dzieją się gdy ludzie o ograniczonym zasobie wiedzy interpretują prace ludzi z wiedzą rozbudowaną. W sieci pojawia się coraz więcej materiałów o wyższości motywatorów wewnętrznych na zewnętrznymi - co jest jak najbardziej dobre. To co jest niedobre to to, że coraz więcej osób zaczyna wyciągać błędne wnioski, że pieniądze jako motywator zewnętrzny przynoszą więcej szkody niż pożytku.

Weźmy sobie choćby taki artykuł, który pojawił się w poprzednim tygodniu :

http://blogs.hbr.org/cs/2013/04/seven_rules_for_managing_creat.html

Pay them poorly: There is a longstanding debate about the relationship between intrinsic and extrinsic motivation. Over the past two decades, psychologists have provided compelling evidence for the so-called "over-justification" effect, namely the process whereby higher external rewards impair performance by depressing a person's genuine or intrinsic interest
(...)
The moral of the story? The more you pay people to do what they love, the less they will love it. In the words of Czikszentmihalyi, "the most important quality, the one that is most consistently present in all creative individuals, is the ability to enjoy the process of creation for its own sake." More importantly, people with a talent for innovation are not driven by money.

I to nie jest jakiś tam sobie blog ale coś co nazywa się Harvard Business Review. I chociaż data była bliska to jednak nie był to podobno żart primaaprilisowy. Nasuwa się pytanie :

Ok po kolei jak mogło do tego dojść, że ludziom takie dziwne pomysły przychodzą do głowy

O małpie co puzzle układała

Jest rok 1949 - dzięki niejakiemu Fryderykowi Taylorowi i jego kolożkom od "scientific management" panuje opinia, że ludzie są w dwóch stanach : albo się opie*dalają albo im się zapłaci i pracują (a konkretnie wierzono, że ludzie mają dwie potrzeby - zapewnić sobie przetrwanie, a kiedy już im się to uda mogą pracować za bonusy - marchewski). Na uniwersytecie w Wisconsin niejaki Harry F. Harlow przygotował eksperyment, który miał potwierdzić, że te instynkty siedziały w nas od wczesnych stadiów rozwoju - dlatego obiektem eksperymentu były bliskie człowiekowi małpki.

Doświadczenie miało mieć prosty przebieg - najpierw małpki dostaną do zapoznania się puzzle (takie nieskomplikowane dla małpek) a następnie przy pomocy nagród (pewnie bananów) badacz chciał pokazać jak nagrody zwiększają zaangażowanie badanych w rozwiązanie problemu. Niestety! Na złość badaczowi małpki zaczęły rozwiązywać puzzle zanim Harlow przedstawić im jakiekolwiek widmo nagrody. Im więcej małpy uczyły się problemu tym bardziej wydawały się nim zainteresowane - bez udziału banana czy marchewki!

Harlow pochwalił się odkryciem ale spotkał sie z takim zainteresowaniem jak osoba starająca się przekonać publiczność na wykładzie PMI (project management institute), że istnieją metodyki, które dostarczają sukcesywnie sofcik bez udziału managera - czytaj, nie udało mu się nikogo przekonać.

20 lat minęło

Jest rok 1969 - beton odchodzi na emeryturę i kolejne pokolenie znajduje badania Harlowa. Tym razem główną postacią jest Edward Deci, który rozpoczyna szereg eksperymentów testujących motywacje wewnętrzną i dochodzi do wniosku, że zewnętrzne motywatory mogą osłabić tę motywację. Na przykład w jednym eksperymencie podzielił studentów na trzy grupy i kiedy zaczął jednej z grup płacić za rozwiązanie puzzli a później przestał to (o dziwo!) przestali się oni interesować rozwiązywaniem puzzli. Dla porównania grupa "pasjonatów" wykazywała wzrost zainteresowania problemem.

Ponieważ eksperymenty w USA kosztują to część eksperymentów przeprowadzono w Indiach - wyniki udowodniły, że bez względu na długość i szerokość geograficzną zewnętrzny motywator w postaci pieniędzy obniżał kreatywność i "performens" rozwiązania. Natomiast wydajność zwiększała się w przypadku problemów czysto rutynowych. Można o tych eksperymentach posłuchać sobie więcej tutaj:



I tutaj :

Niestety jest to chyba moment, w którym ludzie przestają czytać te artykuły bo wyciągają dziwny wniosek, że "piniondze demotywują" - bez zrozumienia głębi problemu

Głębia problemu

Ile to już razy widzieliśmy scenę gdzie złożona koncepcja jest upraszczana na potrzeby ludzi, którzy nie do końca rozumieją całokształt. Weźmy chociaż pod lupę metodyki zwinne a zobaczymy jak sensowny zbiór doświadczeń ludzi, którzy zjedli zęby na IT zostaje zmieniony w "napierdalanie bez planu". Innym ciekawym przykładem są humanistyczne interpretacje fizyki kwantowej. Podobnie tutaj chyba mało kto zastanawia się "ale dlaczego tak to działa"?

Generalnie wszelkie koncepcje zmiany zachowań łatwiej i skuteczniej rozważa się kiedy pogodzimy się z mechaniczną naturą działania mózgu i zapomnimy o metafizycznym modelu duszy, przeznaczenia i magicznej roli jednostki w świecie. Toteż jeśli chodzi o mechanikę warto poszukać na guglach takiego oto pana : Brian Knutson, który podobno w poprzednim dziesięcioleciu badał zjawisko motywacji z udziałem rezonansu magnetycznego. Okazało się, że reakcje chemiczne w przypadku oczekiwania zewnętrznej nagrody były niezwykle podobne do reakcji chemicznych osób uzależnionych w przypadku oczekiwania na zaspokojenie nałogu. cześć mechaniczna odpowiedzialna za to ----> http://en.wikipedia.org/wiki/Nucleus_accumbens

Jeśli już pogodzimy się z tym, że nasza osobowość i zachowanie może zmienić się pod wypływem aktywności mechaniczno-chemicznej mózgu to zerknijmy na taką sytuację. Wróćmy na chwilę do czasów kiedy wszystko było prostsze - sawanna jakieś 100 000 lat temu. Koncepcja pieniądza nie została jeszcze wymyślona a ludzie jakoś się motywują do działania. Mamy oto sobie osobnika homo sapiens, który zauważył pszczele gniazdo z miodem gdzieś tam wysoko na drzewie - ma przed sobą kilka wyzwań

  • Jak wejść na drzewo
  • Jak oszukać pszczoły
  • Jak przetransportować miód

Problem wymaga kreatywnego podejścia do jego rozwiązania. A miód - jako źródło szybkowchłanialnych węglowodanów - w tamtych czasach opłacało się mieć. No więc nasz osobnik stoi i patrzy na drzewo a jego mózg pracuje, a konkretnie pracuje jego (chyba) kora nowa, która planuje i analizuje wszelkie możliwe ścieżki rozwiązania problemu, łączy matryce neuronów i generuje nowatorskie idee.

A teraz pojawia się taki duży koleś z zawieszoną na naszyjniku drewnianą plakietką "Zdzisław - szew plemienia - uczę się" i mówi - "jeśli będziesz się wspinał na drzewo szybciej niż średnia zważona dostaniesz łychę miodu". Kora nowa się wyłącza na rzecz wbudowanego systemu --> Fight or flight. Oczywiście, że fight for miód. Nie myśleć, nie działać tylko robić. WAŻNE --> To się dzieje poza kontrolą świadomości. Energia jest cenna więc po co się męczyć z kombinowaniem jak łycha miodu jest na wyciągnięcie ręki.

Co się teraz dzieję gdy odbierzemy łychę miodu, która byłą nagrodą - nasz "Nucleus_accumbens" ma już wyryte ścieżki w neuronach, stwierdza, że bodzieć nie jest dostępny i nie ma co się męczyć. Decyzja - flight, ucieczka od wysiłków, ucieczka od pasji i marzeń. Ale ale ale --- czy to znaczy, że miód był przeszkodą w powyższej sytuacji - NIE - miód był głównym, pierwszym, najistotniejszym powodem zaistnienia danej sytuacji. A kończąc z metaforą wróćmy do codzienności.

A tymczasem w biurze

Podsumujmy :

  1. Jeśli ktoś uważa, ze pasjonaci zmagający się codziennie z kreatywnymi rozwiązaniami problemów nie pracują dla pieniędzy, niech zapytają czy "gdybyś wygrał 10 baniek w totka to przyszedłbyś jutro do pracy?" - jeśli odpowiedź jest przecząca to taka osoba pracuje dla pieniędzy
  2. W życiu każdego informatyka istnieja naturalne motywatory : społdzielnia mieszkaniowa, elektrownia, pani za kasą w sklepie
  3. Na drodze do osiągnięcia celu istnieją problemy, które wymagają napięcia mięśni kreatywności
  4. Jeśli firma nagradza konkretne aktywności w osiągnięciu celu to zabija kreatywności towarzyszącą tym aktywnościom, najbardziej debilne przykłady to
    1. nagradzanie za napisanie określonej ilości linii kodu
    2. nagradzanie za osiągnięcie określonego pokrycia testami jednostkowymi
  5. Powyższe wcale nie oznacza, że pieniądze nie motywują osób kreatywnych, gdyż ten typ motywacji jest jak najbardziej u celu podróży.
  6. Wiele osób jest zmotywowanych gdy ma okazje nauczyć się nowych rzeczy, nowych technologii. Ej helołłł - dzięki temu wzrasta ich wartość w firmie i na rynku - kasa misiu kasa.
  7. Oczywiście osoba, którą motywuje tylko i wyłącznie kasa nie przetrwa w IT zbyt długo (no chyba, ze zostanie architektem ;))
Książka, która doskonale omawia powyższe tematy jest "Drive" Daniela Pink(a). Jako naturalne motywatory proponuje on autonomię,dochodzenie do mistrzostwa oraz poczucie celu . Jeśli ktoś w ogóle rozważa wpływ pieniędzy an motywację powinien według mnie najpierw zastanowić się czy dostarcza w stopniu zadowalającym wspomniane trzy kwestie.

linki

niedziela, 24 marca 2013

Marcowe nowinki żywieniowe

Czyli w zdrowym ciele zdrowy duch, mniejsze zamulenie i lepsze programowanie.

Ograniczyć węglowodany proste i tłuszcze w jednym posiłku

To jest info z marcowego wydania Perfect Body. Pomijając masę fachowych terminów - w uproszczenie sprowadza się do obserwacji, że od milionów lat jadło się zwierza (białko+tłuszcze) albo roślinki (głównie węgle+trochę białka). I teraz według opisu okazuje się, że tłuszcze i węglowodany proste są inaczej trawione - ba nawet przeszkadzają sobie nawzajem w tej czynności. Tłuszcze są trawione dopiero w jelicie cienkim gdzie przeszkadzają enzymom trawiącym węglowodany. Proces trawienia jest zaburzony, powstają gazy itd. Do tego kwasy tłuszczowe we współpracy glukozą i węgli szybciej budują tkankę tłuszczową (nie, nie idzie w cycki). Kto chce niech zweryfikuje informacje.

Zakwaszenie organizumu

Zakwaszenie to poniekąd takie zasyfienie organizmu. Gdy organizm jest zakwaszony w komórkach zaczynają się rozmnażać mikroorganizmy i inne bakterie, zmniejsza się regeneracja i wchłanialność witamin oraz minerałów. Organizm próbuje zrównoważyć tzw. pH kradnąc minerały między innymi z kości i zębów (te pierwsze zaczną się łamać a te drugie psuć). A później nawet pojawia się depresja i zmniejszona odporność psychiczna.

Co zakwasza organizm :

  1. Najbardziej ponoć piwko - czasem zabawnie jest się w ten sposób zakwasić ale żeby zmniejszyć destrukcje organizmu trzeba zarzucić jakąś sałatkę czy inną zieleninę.
  2. Nikotyna - tego nałogu nigdy nie rozumiałem
  3. Czekolada (nawet gorzka), orzechy , ryby, jajka, ryż, sól, słodziki, napoje gazowane - tutaj niektóre produkty są akurat pożyteczne dlatego warto zarzucić trochę roślin aby odczyn z kwasowego zmienić na zasadowy
No i zakwasza bardzo stres. Tutaj może pomóc przypomnienie sobie, że jesteśmy bandą gadających małp popie**alajacych na organicznej skorupie poprzez galaktykę. W kontekście tak sformułowanej rzeczywistości fakty, że na podłodze w kuchni źle ułożyły się płytki albo, że znowu nie wyjadę na riwierę by pochwalić się znajomym powinny przestać być stresogennymi.

niedziela, 17 marca 2013

33rd Degree - najlepsze antytrole i inne notatki

Poniższe notatki dotyczątej konferencji ------------------> http://2013.33degree.org/

Najlepsze anty-trolle

Najlepszy anty-troll to zdecydowanie odpowiedź Teda Newarda :

two minutes in the corner for being stupid..... I'm waiting"

Generalnie struktura jest na tyle uniwersalna, że powinna zwalczyć 90% występujących troli.

Inna ciekawą technikę odpowiedzi na zabarwione trollem pytania zastosował Dan North. Mechanizm jest bardzo prosty - polega na powtórzeniu pytania niekoniecznie słowo w słowo i natychmiastowej odpowiedzi. W efekcie wyglądało to tak jakby prowadzący w ogóle nie musiał zastanawiać się na odpowiedzią, tłum miał zabawę a pożerająca czas prezentacji trollo-konwersacja została zneutralizowana..

Sam temat, który był pod trollo obstrzałem jest sam w sobie ciekawy i pewnie dla niektórych nieco kontrowersyjny. Otóż ktoś kto sam wymyślił trzyliterową technikę - BDD - obalił trochę absolutność innego trzyliterowego skrótu -TDD. Już nie trzeba się wstydzić tego, że czasami na chwilę w klasie pojawi się main z próbką kodu albo o zgrozo napiszemy jakiś kawałek kodu a test dopiero później - teraz to ma nazwę - spike and stabilize

Co ciekawe cała akcja z tym TDD doskonale podchodzi pod to co Vankat Subramanian opowiadał ostatniego dnia w kontekście padających imperiów i efektu "rewolucji poprzedzającej stagnację". Generalnie TDD jest bardzo dobre bo nie pozwala na rozlanie się morza gównianego kodu ale jeśli ktoś kurczowo trzyma się tej techniki i oddaje jej cześć na każdym kroku to trochę tez wpada w kategorię ciemnogrodu.

Ciekawostki psychologiczne - strach przed nieznanym

http://en.wikipedia.org/wiki/Ellsberg_paradox - w skrócie: mając do wyboru dwa rozwiązania większość ludzi podświadomie zakłada, że rozwiązanie z większą ilością niewiadomych jest gorsze lub bardziej ryzykowne. Na wykładzie był przykład z dwoma urnami - w jednej jest tyle samo piłek białych co czarnych - o drugiej nic nie wiemy. Bez względu czy pytana osoba ma wyciągnąć białą czy czarną piłeczkę to zawsze podświadomie założy, że stosunek piłek w nieznanej urnie jest na jego niekorzyść.

W naszym IT objawia się to trzymaniem się starych rozwiązań a w życiu codziennym będziemy woleli stać w korku na znanej drodze aniżeli ryzykować jazdę skrótem. I to na szczęście nie jest zawsze prawdą gdyż niektórzy mają taką oto cechę ---> http://en.wikipedia.org/wiki/Novelty_seeking ale niestety niektórzy będą przez całe swoje życie codziennie wegetować w dniu świstaka.(chociaż kto tak naprawdę może decydować o tym co jest dobre a co niedobre...)

Ciekawostki psychologiczne - głupota grupowa

http://en.wikipedia.org/wiki/Asch_conformity_experiments - w eksperymencie brało udział 12 osób - z czego 11 podstawionych. Owe ustawione osoby zawsze wybierały tę samą błędną odpowiedź na pytanie "które linie są tej samej długości". Podobno to wystarczyło aby w większości przypadków ostatnia osoba - która nie była podstawiona - również wybrała błędną odpowiedź. Nie jest to pierwszy przykład tego, że ludzie w kontekście grupy/społeczeństwa zachowują się czasami jak debile (bo jak to inaczej nazwać). Temat jest na tyle ciekawy,że wymaga osobnego wpisu.

Myślenie grupowe na wiki ---> http://en.wikipedia.org/wiki/Groupthink

Blue Green Deployment

W Toyota Way przykładem waste były produkty zalegające w magazynach. W IT takim marnotrawstwem jest funkcjonalność, która zamiast robić pieniądze na produkcji zalega w szafie i czeka aż ktoś ja łaskawie wdroży (przy okazji przejdzie 1500 bramek wprocesie). Od jakiegoś czasu pracuję nad Doktryną natychmiastowej wartości biznesowej czyli po prostu redukcji do zera czasu gdy funkcjonalność oczekuje na wdrożenie. Aby to zadziałało trzeba znaleźć sposób na wgrywanie funkcjonalności bez zatrzymywania serwerów na produkcji gdyż to by zbytnio wkurwiało użytkowników. Jedyną zaletą niewiedzy są te magiuczne momenty gdy dowiadujesz się, że ktoś już miał podobne problemy i chyba znalazł rozwiązanie. Poniżej tzw "Blue Green Deployment". Na rysunku wygląda prosto - w rzeczywistości będzie pewnie niezwykle trudno ale jest przynajmniej jakiś nowy cel życia...



Do tego do obadania jest to ------> http://flywaydb.org/ - może będzie lepsze od liquibase.

Dwa fajne screeny na koniec