niedziela, 22 czerwca 2014

Play - formularze - fotki i spostrzeżenia

Najpierw komercha

Pizza sama się nie kupuje - więc jest i logo firmowe.
Obsługa wyjątków bez wyjątków.
W sumie trzeba było zrobić dwa zdjęcia - najpierw jedno z lewej strony - a w drugim wszyscy przechodzą na prawo i zakładają dla niepoznaki ubrania na lewą stronę - frekwencja 200%.
A tak się obsługuje formularze

Co następne

Teraz po wakacjach najpewniej :

  1. Powtórka wprowadzenia - teraz być może z Play 2.3
  2. Wystawianie RESTa przy pomocy JSONa i konsumpcja przy pomocy webservisów (żeby nie bawić się w javaskrypty)
  3. Integracja Playa z Akka

Spostrzeżenie

Aby w tym wpisie pojawiło się coś poza autopromocją - czas na ciekawe spostrzeżenie jakie pojawiło się w trakcie warsztatów.

Sytuacja wygląda tak : są jakieś okoliczności i pojawia się reakcja na te okoliczności. Reakcja wtapia się w światopogląd i nawet gdy już okoliczności się zmieniają i dana reakcja jest już być może niepotrzebna to już zdążyła stać się dogmatem, którego się nie kwestionuje bo nie. Dogmat w tym przypadku brzmi "nazwy zmiennych muszą zdradzać ich przeznaczenie czyli w skrócie - być czytelne". To było zbawianie gdy trzeba było pracować z 10000 liniami "managero-helkperów" w Javie (jeśli dla kogoś nie jest to czas przeszły to współczuję) ale czy jest to aktualne gdy nie pracuje się z okaleczonym kodem?

I teraz nowa sztuczka z kołczingu - aby uratować się przed flejmwarem należy sytuacje przedstawić nie w kontekście "co jest lepsze" ale raczej "czy zabawa w szukanie dziur w dogmacie da mi nowe możliwości i rozwinie moją osobowość abym stał się bardziej kompletnym bytem"- ano dokładnie tak!

Inspiracja tym tematem pojawiła się u mnie po lekturze jakiegoś bloga, którego teraz nie mogę znaleźć ale generalna koncepcja polegała na tym aby intencje zmiennej przekazywać nie przez jej nazwę ale przez jejże typ.

I teraz zerknijmy na dwie deklaracje metodki, która tworzy mi taki mały parserek do zapisywania pliku z formularza na dysku :


//po staremu
  def saveMultipartFile(multipartFileName:String,pathOnDisc:String)(data:MultipartFormData[TemporaryFile])=
//po nowemu
  def saveMultipartFile(m:MultipartFileName,p:PathOnDisc)(data:MultipartFormData[TemporaryFile])=
No i jaki widzę problem z pierwszą wersją? Ano taki jak z dokumentacją w wordzie - pisać można tam sobie wszystko co się komu podoba. I tka naprawdę to jaka jest pewność, że pierwszy parametr to faktycznie nazwa pliku a nie nazwisko panieńskie babci? W trakcie refaktoringu kod się zmieni a nazwa zostanie taka sama i dupa.

W drugim przypadku też 100% pewności nie ma ale raz, że w trakcie refaktoringu typy - czyli zwyczajne nazwy klas - zmienia IDE a nie JAnek programista z palca - a dwa, że jako String to mogę sobie przekazać co chcę i się zesra w Runtime. No i jest jeszcze trzecia strona medalu. Tak się wywołuje tę metodkę w kodzie :

val savingFileParserFunction=saveMultipartFile(MultipartFileName("file"), PathOnDisc("/tmp/testy"))_
I tutaj od razu w kodzie widać co jest co bez potrzeby wyświetlania Popapów z docami. Dla porównania w wywołaniu klasycznym :
val savingFileParserFunction=saveMultipartFile("file", "/tmp/testy")_
Tutaj dla odmiany raczej trzeba będzie zajrzeć do doca.

Na Code Retreat jest takie ćwiczonko gdzie należy każdą koncepcję w systemie przedstawić przy pomocy tzw. "klasy domenowej" czyli np. współrzędna jest typu "Wspolrzedna" a nie typu "Integer". No i w Javie pisanie tych wszystkich klas jest niby ok ale czułem się wewnętrznie, że w życiu raczej tego nie zastosuje bo wymaga to zbyt dużo prądu. W Scali sobie gdzieś w module trzasnę :

case class MultipartFileName(name:String) extends AnyVal
case class PathOnDisc(path:String) extends AnyVal
I już.

I jeszcze jedna ciekawa rzecz

Ten mały fragmencik :

extends AnyVal
Podobno sprawia, że kompilator w trakcie kompilacji "rozpakuje" typ i stawia w jego miejsce String wywalając wrappera. Czyli nie ma narzutu na pamięć kosztem tam chwilę dłuższej kompilacji. Chyba tak to działa.

I najważniejsze, żeby nie stawiać tej koncepcji w opozycji do tego co się wie i w co się wierzy ale spróbować chwilę się nią pobawić. Być może będzie to nowy bodziec do rozwoju i usprawnienia naszej pracy? A może po chwili się go wyrzuci i wróci do dotychczasowych metod? Najważniejsze to traktować to jako ćwiczenie a nie spór o to co lepsze. Po to też między innymi kasuje się kod w Code Retreat - aby pobawić się być może niewygodnymi pomysłami ze świadomością, że i tak to pójdzie do kibla i zostaną jedynie przeżycia w mojej czy twojej głowie.

Coś z zupełnie innej beczki

Bluzganie redukuje ból oraz zmniejsza wewnętrzne napięcie :

A co najważniejsze bluzganie buduje team spirit! Wiarygodności tych badań sprawdzać nie muszę gdyż weryfikuję je od lat trzydziestu. Ewentualnie jak ktoś był chowany pod kloszem i życia doświadczył tylko z odcinków Drużyny A to może zerknąć na : http://filing.pl/ilustrowany-podrecznik-dla-mlodziezy-dobrze-wychowanej/

4 komentarze:

  1. Paweł muszę przyznać, że mnie przekonałeś, ale tak jak powiedziałeś na ostatnim wujku Bobie: "zasady nie zastąpią myślenia". Tak samo chyba jest w tym wypadku i myślę, że dobrze bazować na "name every concept", a dopiero potem się z tego wyłamywać kiedy nam wiedza lub intuicja podpowie. Obawiam się, że odwrotna logika może średnio działać.

    PS. Dzięki za warsztaty, zawsze wartościowe.

    OdpowiedzUsuń
  2. Dzięki za ciekawy artykuł. Potwierdzam, extends AnyVal to sztuczka, dzięki której możemy mieć statyczne typowanie bez narzutu klas opakowujących. Od pewnego czasu nie mam już typów Customer {id: Int; ...} tylko CustomerId, etc.

    Polecam ciekawy artykuł o "wyciskaniu" z systemu typów ile się tylko da: http://techblog.realestate.com.au/the-abject-failure-of-weak-typing/

    OdpowiedzUsuń
  3. A może jakiś język przyszłości mógłby dopuszczać zmienne w ogóle bez nazw? ;) (http://www.warski.org/blog/2013/01/dry-parameter-names/)

    OdpowiedzUsuń