Showing posts with label OOP. Show all posts
Showing posts with label OOP. Show all posts

Sunday, 26 August 2012

Ksiązki, znowu książki

If you don't know polish - just go directly to Programmers Don't Read Books -- But You Should (written by Atwood, so it's worth reading;)).

After reading that article, I'd like to put my hands on 2 books that were mentioned there (let's say it's my recommendation and essence of whole this entry):








Ok, a teraz po polsku. Można? wszystko można ;)

Książki są zajebiste, w ogólności. Mają ten plus, że raczej NA PEWNO ktoś już je przeczytał i mógł je ocenić. Są gusta i guściki, ale załóżmy, że jak ktoś już bierze do ręki książkę "dla programisty", to ma łeb na karku i bzdur na jej temat chyba nie będzie wypisywał ;) Generalnie - zakładanie, że ludzie mają dobre intencje, ułatwia życie. Nie wiem czy powyższe 2 książki są aż tak genialne, aby warto je było przeczytać - wiem tylko:
  • jaką mają średnią na Amazonie
  • nie dotyczą jednej technologi, czyli się raczej nie przedawnią
  • poleca je gość, który jest dla mnie zawodowym autorytetem (chociażby za stworzenie stacka)
  • piszę o nich posta, aby o nich nie zapomnieć ;) - do "Clean Code" się przekonałem i efekt jest lepszy niż sądziłem. Chociaż czasem polskie tłumaczenie jest nieco zabawne ;)

Ale wiem co ja czytałem i co mogę śmiało polecić. Ba, z paroma kumplami opracowaliśmy "algorytm" książek, które trzeba przeczytać, nim się zechce zmienić pracę. Nie będę zdradzać ich personaliów, bo faktycznie czytają je oni w tym celu. I absolutnie nie narzekają! :)

Kolejność nieprzypadkowa:
  1. Effective Java
  2. Clean Code
  3. Refactoring to patterns
  4. Java Concurrency in Practice
Cytat z Clean Code:

You are reading this book for two reasons. First, you are a programmer. Second, you want to be a better programmer. Good. We need better programmers.

Monday, 11 June 2012

Rozprawka o new i fabryce... fabryce fabryk faryk :)

To był mój powitalny post post na tym blogu, zawierał on sobie, niestety w formie obrazka, link do mojej odpowiedzi na stacku w temacie "Factory Design pattern and keyword 'new'".


Wracam do tego nie dlatego, że był to taki świetny wpis, który faktycznie nadawałby się na bloga, ale dlatego, że dziś przypomniałem sobie o nim, widząc ten obrazek:



Moim zdaniem świetnie oddaje on to o czym napisał  Joshua Kerievsky, którego cytowałem też tam, na stacku:
I’ve seen numerous systems in which the Factory pattern was overused. For example, if every object in a system is created by using a Factory, instead of direct instantiation (e.g., new StringNode(ノ)),the system probably has an overabundance of Factories.

Moja wypowiedź tyczyła się właśnie tego - chłodnej głowy w tworzeniu fabryk do wszystkiego. Fabryki fabryk fabryk. Bezsens. Z reguły używanie słowa kluczowego new przecież nikogo nie boli, mimo, że powstają całe poematy o tym "why 'new' is evil".

Przykładowy poemat - Java's new Considered Harmful - oczywiście, nie chodzi w nim o to, aby nigdy i nigdzie nie używać new, ale niestety niektórzy mają skłonności do zapędzania się i wtedy właśnie może powstać coś w stylu ProblemFactory.

... Nie chcę przepisywać tego, co już kiedyś napisałem na stacku, a co jest podlinkowane u góry tego posta, jak ktoś nie jest leniwy, to sobie kliknie :)



Po więcej odsyłam do wzorowego opisu wzorca fabryki wraz z opisem refaktoringu z nim związanego: Move Creation Knowledge to Factory. Warto, warto! Kiedyś zawodowo zajmowałem się czytaniem i pisaniem o wzorcach, ale ten artykuł, a w zasadzie fragment książki, to najlepsza rzecz o fabrykach, na jaką trafiłem. Polecam każdemu.


W sumie cała książka Joshuy jest jak najbardziej godna polecenia... i zarazem bardzo trudna do wygooglowania w formie pdfa :)





Na sam koniec jeszcze jedna perełka, luźno związana z tym o czym mowa powyżej - kiedy w zamyśle fajny design nie jest fajny, lecz jest problemem:

zle, i gorsze, pomysły na zamianę ifów na coś innego

jako morał można uznać jeden z komentarzy:


Pozwala to spiąć mój post słowami Atwooda, przytoczonymi wtedy na stacku:
The best way to learn to write simple code is to write simple code! Patterns, like all forms of complexity, should be avoided until they are absolutely necessary. That's the first thing beginners need to learn. Not the last thing.

Monday, 16 April 2012

Getters and setters - the good parts


Każdy ich używa... ale czemu?

Co nam dają settery i gettery?

- Ukrywają implemenetację!
- Czyżby?
- No tak...
- Na pewno?
- No chyba...

Czym się różni:
public String name;
od:
private String name;

public String getName() { return name; }
public void setName(String name) { this.name = name; }

bo przecież nie ukrywaniem* czegokolwiek...

Owe ukrywanie, czyli enkapsulacja, to jeden z najważniejszych aspektów OOP i zarazem jeden z częstszych motywów podczas rozmów kwalifikacyjnych, więc warto zgłębić ten temat nieco... głębiej. Tym bardziej, że studiach się o tym chyba (a może nie słuchałem...) nie mówi, natomiast w pracy na takie "pierdoły" nie ma czasu. O samej enkapsulacji będzie innym razem, także w kontekście wzorców.

Wracając do setterów i getterów... istnieją ortodoksyjni wojownicy obiektowości głoszący "why getter and setter methods are evil" - http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html - wygląda na fajny artykuł, jednak nie czytałem go, bo spodziewam się co będzie tam napisane. Tak, podejście rodem z JavaBeans ma swoje wady, wśród których prym wiedzie gigantyczny znak zapytania przy "ukrywaniu".

Co jest więc takiego dobrego w setterach i getterach, że były, są i będą używane?

Po pierwsze, wracając do powyższego porównania publicznego pola name typu String z polem prywatnym i akcesorami... Te 2 kawałki kodu nie różniłby się niczym, gdybyśmy nie mieli opcji zmiany tego, co zaproponował nam kompilator podczas wspaniałomyślnego wygenerowania gettera i settera. Settery dają możliwość walidacji danych! Chcesz zamieniać polskie znaki w Stringu na ich "okrojone" odpowiedniki? Nie ma sprawy - zmieniasz jednego settera - i już, wszystko działa. Tak, jednego. Mając do czynienia z polami publicznymi stykamy się z czymś bardzo hardcorowym - wprowadzając zmiany w logice musimy zrobić to w każdym miejscu, gdzie to pole jest ustawiane, to byłoby nie tylko sprzeczne z podstawowymi zasadami programowania, ale po prostu skrajnie głupie.

Wracając jednak do "walidacji" - w każdym przypadku, gdy w setterze dzieje się coś więcej niż standardowe przypisanie nowej wartości (np. walidacja, jakieś efekty uboczne, rzucanie wyjątkiem) trzeba opisać to w Javadocu - wtedy i tylko wtedy. Dokumentowanie tych o domyślnym działaniu to strata czasu.

Po drugie, o dziwo czasem jednak "ukrywają" ;) czyniąc kod odporniejszym na zmiany.

przed:
private boolean alive = true;

public boolean isAlive() { return alive; }
public void setAlive(boolean alive) { this.alive = alive; }
po:
private int hp; // zmiana implementacji!

public boolean isAlive() { return hp > 0; } // stare sygnatury
public void setAlive(boolean alive) { this.hp = alive ? 100 : 0; }
Jest to skrajny przypadek, ale i takie się zdarzają. Zmieniła się implementacja, interfejs pozostał niezmieniony, klasa nadal spełnia swój kontrakt, brawo dla niej, brawo dla nas ;)

//@TODO: jakiś oczywisty kontr przykład - np. zamiana typu z int na long, aby pokazać, że powyższe to raczej wypadek przy pracy niż reguła :)

Po trzecie - polimorfizm. Warto o tym pamiętać, że używanie getterów, setterów i javadoców czyni możliwym to, co byłoby niemożliwe przy zwyczajnym dziedziczeniu publicznego pola. Pola nie są polimorficzne.

Po czwarte - debugging. W środku metody możemy w razie uzasadnionej potrzeby dorzucić breakpointa albo logowanie. Znowu - robimy to tylko jeden raz a efekt staje się globalny.



Ok, to tyle, następnym razem będzie w drugą stronę (czyli co zamiast getterów i setterów), ale na zakończenie jeszcze mała przypowieść "why getter and setter methods are GOOD":
Because 2 weeks (months, years) from now when you realize that your setter needs to do more than just set the value, you'll also realize that the property has been used directly in 238 other classes :-)