<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>KoziołekWeb &#187; Inżynieria Oprogramowania</title>
	<atom:link href="http://koziolekweb.pl/category/inzynieria-oprogramowania/feed/" rel="self" type="application/rss+xml" />
	<link>http://koziolekweb.pl</link>
	<description>Sięgam tam gdzie wzrok nie sięga, a tam NullPointerException</description>
	<lastBuildDate>Tue, 07 Feb 2012 19:00:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<image>\n<url>http://koziolekweb.pl/icon.png</url>\n<title>KoziołekWeb</title>\n<link>http://koziolekweb.pl</link>\n<width></width>\n<height></height>\n</image>\n		<item>
		<title>Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności</title>
		<link>http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/</link>
		<comments>http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 21:07:52 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2382</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Część 3 Część 4 Część 5 Część 6 Część 7 Część 8 Piątek, a zatem słuchamy Listy w Trójce. Przed nami ostatnia z zasad Jeff&#8217;a Bay&#8217;a Nie używaj getterów/setterów/własności Niewątpliwie jest to najbardziej obiektowa z zasad. By zrozumieć o co w niej chodzi porównajmy takie oto dwie klasy Listing [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a><br />
<a href="http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi//">Część 3</a><br />
<a href="http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/">Część 4</a><br />
<a href="http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/">Część 5</a><br />
<a href="http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/">Część 6</a><br />
<a href="http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/">Część 7</a><br />
<a href="http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/">Część 8</a></p>
<p>Piątek, a zatem słuchamy Listy w Trójce. Przed nami ostatnia z zasad Jeff&#8217;a Bay&#8217;a</p>
<h4>Nie używaj getterów/setterów/własności</h4>
<p>Niewątpliwie jest to najbardziej obiektowa z zasad. By zrozumieć o co w niej chodzi porównajmy takie oto dwie klasy</p>
<p class="listing">Listing 1. klasa bardziej &#8220;obiektowa&#8221;</p>
<pre class="java" name="code">class Chłopiec{

	private String imię;

	private String nazwisko;

	private String wiek;

	public String getImię() {
		return imię;
	}

	public void setImię(String imię) {
		this.imię = imię;
	}

	public String getNazwisko() {
		return nazwisko;
	}

	public void setNazwisko(String nazwisko) {
		this.nazwisko = nazwisko;
	}

	public String getWiek() {
		return wiek;
	}

	public void setWiek(String wiek) {
		this.wiek = wiek;
	}

}</pre>
<p class="listing">Listing 2. klasa mniej &#8220;obiektowa&#8221;</p>
<pre class="java" name="code">class Dziewczynka {

	public String imię;

	public String nazwisko;

	public String wiek;

}</pre>
<p>Czym różnią się te dwie klasy? </p>
<h4>Obiektowość to nie metody</h4>
<p>Pomijając różne specyficzne elementy języka związane z współbieżną zmianą stanu obiektów tych klas to te dwa twory niczym się nie różnią. Mogę jednak założyć się, że jeżeli pokażemy je &#8220;nagie i bezbronne&#8221; to pierwsza z nich zostanie zakwalifikowana jako bardziej obiektowa. Druga będzie mniej obiektowa. Dlaczego? Jakoś tak się utarło, że o obiektowości decydują metody.<br />
W Javie jest to szczególnie potęgowane przez specyfikację <a href="http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">Java Beans</a>:</p>
<blockquote><p>Properties are always accessed via method calls on their owning object. For readable properties<br />
there will be a getter method to read the property value. For writable properties there will be a<br />
setter method to allow the property value to be updated.
</p></blockquote>
<p>Cóż&#8230; Ma to pewien cel i jest tu pewien pomysł, ale tylko gdy przyjrzymy się tej specyfikacji jako całości (szczególnie z obsługa zdarzeń i wzorcem obserwatora). Niestety jak to w życiu bywa, ktoś z całego dokumentu wyciągnął jeden fragment i tak oto znaleźliśmy się w życi.  </p>
<h4>Czym jest obiektowość?</h4>
<p>Obiektowość to przede wszystkim enkapsulacja. Inaczej mówiąc obiekty nie powinny ujawniać swojego wnętrza, a jedynie udostępniać pewien interfejs, który będzie odwzorowywał operacje dokonywane przez obiekt. Oczywiście może się tak zdarzyć, że operacja polega na ustawieniu jakiejś wartości obiektu. Jednak są to specyficzne przypadki. W żadnym wypadku nie należy pozwalać na swobodną manipulację właściwościami obiektu.</p>
<h4>Co zamiast?</h4>
<p>Skoro nie powinniśmy mieć możliwości swobodnej manipulacji jak tworzyć i konfigurować obiekty? Z każdym z elementów zajmiemy się z osobna.</p>
<h5>Settery</h5>
<p>Generalnie obiekty powinny być niezmienne. Ma to wiele zalet. Najważniejszą jest możliwość swobodnego programowania współbieżnego bez obawy, że wątki wzajemnie pozmieniają sobie dane. W takim wypadku settery zostaną automatycznie wyrugowane przez mechanizmy języka wymuszające ustawienie pól w konstruktorze.<br />
Jeżeli jednak z jakiegoś powodu nie możemy użyć pól finalnych to należy ustawić je z użyciem jakiegoś kontenera DI. Zazwyczaj mamy dostęp do tego typu bibliotek i nie ma problemów z ich wykorzystaniem.<br />
Co jednak gdy z jakiś powodów kontener DI nie jest dostępny? W takim wypadku zostaje nam wykorzystanie wzorca fabryki wzbogaconego o użycie refleksji. </p>
<h5>Właściwości</h5>
<p>Unikamy sytuacji kiedy zachowanie obiektu zależy od właściwości. To właściwość powinna dostarczać odpowiedniego zachowania. Przykładowo w poprzedniej części mówiłem, że opakowane kolekcje powinny dostarczać metod &#8220;kontekstowych&#8221;. Podobnie w trzeciej części gdzie mowa była o opakowaniu typów prymitywnych wspominałem o możliwości zamknięcia w typie opakowującym pewnych prostych operacji np. walidacji czy operacji arytmetycznych. </p>
<h5>Gettery</h5>
<p>Najbardziej kłopotliwy element. Koniec końców zawsze musimy gdzieś pokazać uzyskaną wartość. Najprościej jest przesłonić <samp>toString</samp>. Nie zawsze się to da zrobić. O ile zadziała to w przypadku prostych obiektów to już obiekty złożone stanową duży problem. Pewnym rozwiązaniem może być użycie odpowiedniego prezentera, czyli wzorca MVP. Prezenter może dostać się do obiektu via refleksja względnie odpowiednio zinterpretować wyniki z metody <samp>toString</samp>. Wzorzec ten ma w tym przypadku wiele zalet. Jeżeli jednak chcemy zrobić coś małego to można użyć czegoś co roboczo nazywam obiektem &#8220;samopezentującym się&#8221;. W takim przypadku obiekt posiada metodę, do której można przekazać docelowe miejsce prezentacji np. strumień i tyle. Jest to rozwiązanie o tyle wygodne, że czasami chcemy ograniczyć możliwość prezentacji obiektu. W takim wypadku metoda pełni rolę swoistego &#8220;pasa cnoty&#8221; ponieważ ogranicza kanały prezentacji.</p>
<h4>Podsumowanie</h4>
<p>Uff&#8230; przebrnąłem. Nie było łatwo. Paweł Lipiński w komentarzu do siódmej części zwrócił uwagę, że są to przede wszystkim pewne heurystyki. W części zerowej wspomniałem, że zasady te są świetne jeżeli chcemy refaktoryzować kod. Są też doskonałym narzędziem do ćwiczenia. Zatem czy stosować zasady Jeff&#8217;a Bay&#8217;a? Moim zdaniem warto dążyć do kodu napisanego zgodnie z tymi zasadami. Ponieważ kod taki promuje przemyślane konstrukcje, pozwala na odnalezienie potencjalnie niebezpiecznych fragmentów i karkołomnych konstrukcji w architekturze oraz wymusza pisanie testów. Ja napisałem projekt zgodny z tymi zasadami mający około 1000 linii. Teraz czas byś usiadł i napisał swój projekt. </p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+9+%26%238211%3B+Nie+u%C5%BCywaj+getter%C3%B3w%2Fsetter%C3%B3w%2Fw%C5%82asno%C5%9Bci" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+9+%26%238211%3B+Nie+u%C5%BCywaj+getter%C3%B3w%2Fsetter%C3%B3w%2Fw%C5%82asno%C5%9Bci" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+9+%26%238211%3B+Nie+u%C5%BCywaj+getter%C3%B3w%2Fsetter%C3%B3w%2Fw%C5%82asno%C5%9Bci" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+9+%26%238211%3B+Nie+u%C5%BCywaj+getter%C3%B3w%2Fsetter%C3%B3w%2Fw%C5%82asno%C5%9Bci" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+9+%26%238211%3B+Nie+u%C5%BCywaj+getter%C3%B3w%2Fsetter%C3%B3w%2Fw%C5%82asno%C5%9Bci" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+9+%26%238211%3B+Nie+u%C5%BCywaj+getter%C3%B3w%2Fsetter%C3%B3w%2Fw%C5%82asno%C5%9Bci" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 9 &#8211; Nie używaj getterów/setterów/własności' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2012/01/20/ekstremalna-obiektowosc-w-praktyce-czesc-9-nie-uzywaj-getterowsetterowwlasnosci/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania</title>
		<link>http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/</link>
		<comments>http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 22:11:05 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2374</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Część 3 Część 4 Część 5 Część 6 Część 7 Gladius Noctis, a na blogu ósma z zasad Jeff&#8217;a Bay&#8217;a Klasa której polem jest kolekcja nie powinna mieć żadnych innych pól (opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania) Nazwa trochę długa, ale nie ważne. Powróćmy na chwilę do [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a><br />
<a href="http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi//">Część 3</a><br />
<a href="http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/">Część 4</a><br />
<a href="http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/">Część 5</a><br />
<a href="http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/">Część 6</a><br />
<a href="http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/">Część 7</a></p>
<p>Gladius Noctis, a na blogu ósma z zasad Jeff&#8217;a Bay&#8217;a</p>
<h4>Klasa której polem jest kolekcja nie powinna mieć żadnych innych pól (opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania)</h4>
<p>Nazwa trochę długa, ale nie ważne. Powróćmy na chwilę do pierwszej części tego cyklu. Na koniec przykładu z tablicami mieliśmy tam następujący kod:</p>
<p class="listing">Listing 1. Kod z pierwszej części
<pre class="java" name="code">package pl.koziolekweb.eowp1;

public class Array3DFiller {

	public static void main(String[] args) {
		int[][][] array3d = new int[3][3][3];
		fillArray(array3d);

		printArray(array3d);

	}

	private static int fill2dArray(int[][][] array3d, int current, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			current = fillRow(array3d, current, i, j);
		}
		return current;
	}

	private static int fillArray(int[][][] array3d) {
		int current = 0;
		for (int i = 0; i < array3d.length; i++) {
			current = fill2dArray(array3d, current, i);
		}
		return current;
	}

	private static int fillRow(int[][][] array3d, int current, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++, current++) {
			array3d[i][j][k] = current;
		}
		return current;
	}

	private static void print2dArray(int[][][] array3d, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			printRow(array3d, i, j);
			System.out.println();
		}
	}

	private static void printArray(int[][][] array3d) {
		for (int i = 0; i < array3d.length; i++) {
			print2dArray(array3d, i);
			System.out.println();
		}
	}

	private static void printRow(int[][][] array3d, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++) {
			System.out.print(String.format("%2s ", array3d[i][j][k]));
		}
	}

}
</pre>
<p>Przy tamtych założeniach było ok. Krawetko podał jeszcze zgrabniejszą wersję. Ja jednak zmienię tu wszystko.</p>
<h4>Co robimy z kolekcjami?</h4>
<p>Przede wszystkim iterujemy. Przeciskamy przez różne formy pętli w celu wykonania operacji na wszystkich elementach kolekcji. W Javie jest to dość upierdliwe. Za każdym razem należy napisać te klika linijek kodu by przepuścić daną kolekcję przez pętlę. W dodatku może okazać się, że coś skrewiliśmy albo nasz kod dostał się w niepowołane ręce, które wykonały kilka niefajnych operacji bezpośrednio na kolekcji.<br />
W Scali jest trochę lepiej mamy metodę <samp>foreach</samp>, która opakowuje pętlę:</p>
<p class="listing">Listing 2. <samp>foreach</samp> w Scali
<pre class="scala" name="code">
val x = 1 to 10
x foreach ($ => println($*$))
</pre>
<p>I już mamy kwadraty liczb od 1 do 10. W javie trzeba na to dwóch pętli.</p>
<p>Oczywiście jest tu ukryty mały "fakap" ponieważ zarówno metoda <samp>to</samp> jak i <samp>foreach</samp> maskują nam odpowiednie pętle. W przypadku <samp>to</samp> jest to jeszcze wzbogacone o lazy-init, ale to insza inszość.</p>
<h4>Dlaczego opakowywać kolekcje?</h4>
<p>Kod w Scali fajny jest. Dlatego warto stworzyć sobie podobne możliwości. W Javie nie jest to trudne generalnie poniższy kawałek kodu rzucił mi się kiedyś w oczy, ale skąd pochodzi ta koncepcja nie jestem wstanie powiedzieć.</p>
<p class="listing">Listing 3. <samp>foreach</samp> w Javie
<pre class="java" name="code">interface Foreach<T> {

	interface Action<T> {
		void perform(T t);
	}

	abstract class ForeachImpl<T> implements Foreach<T> {

		private static class ArrayDelegate<T> implements Foreach<T> {

			private T[] array;

			public ArrayDelegate(T[] array) {
				this.array = array;
			}

			@Override
			public void foreach(Action<T> action) {
				for (T t : array) {
					action.perform(t);
				}
			}
		}

		private static class Delegate<T> extends ForeachImpl<T> {

			public Delegate(Collection<T> collection) {
				super(collection);
			}
		}

		public static <D> Foreach<D> delegate(Collection<D> collection) {
			return new Delegate<D>(collection);
		}

		public static <D> Foreach<D> delegate(D[] collection) {
			return new ArrayDelegate<D>(collection);
		}

		private Collection<T> collection;

		private ForeachImpl(Collection<T> collection) {
			this.collection = collection;
		}

		@Override
		public void foreach(Action<T> action) {
			for (T t : collection) {
				action.perform(t);
			}
		}
	}

	public void foreach(Action<T> action);
}</pre>
<p>Jest to trochę karkołomna konstrukcja w tej postaci, ale wiadomo o co chodzi. Odpowiednie zagłębienia służą tu odwaleniu roboty podobnej do tej jaką odwala scalac przy dodawaniu traita do klasy. Dla przypomnienia jeżeli trait nie zawiera implementacji to jest traktowany jak interfejs. Jeżeli zawiera implementacje to tworzone są klasy abstrakcyjne zawierające zaimplementowane metody i w klasie docelowej następuje delegacja zachowania do takiej wewnętrznej klasy. Tyle w skrócie zainteresowanych odsyłam do konsoli i polecenia javap.</p>
<p>Nasza klasy wystarczy, że zaimplementuje interfejs i wydeleguje obsługę metody do klasy <samp>Delegate</samp>. Już dużo mniej roboty <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  później przy iterowaniu przez kolekcję wystarczy zaimplementować clou pętli czyli to co pomiędzy { i }. Można to też łatwo przetestować. Ba! Można implementację przerzucić na użytkownika API. Niech powie co robi z pojedynczym elementem kolekcji, a to jak będzie przechodził przez kolekcję to już nie jego sprawa. Tu dochodzimy do takiego modelu, który jest już blisko programowania funkcyjnego. Klient mówi CO i nie martwi się JAK.</p>
<h4>Wypełniamy tablicę</h4>
<p>Powróćmy do pierwszego kodu. W pierwszym kroku opakujmy tablicę jednowymiarową o zadanej ilości elementów w coś przyjaznego dla środowiska:</p>
<p class="listing">Listing 4. Opakowana tablica intów
<pre class="java" name="code">class ArrayOfInt {

	private Integer array[];

	public ArrayOfInt(int size) {
		array = new Integer[size];
	}

	public int fill(final int start) {
		return fill(start, 1);
	}

	public int fill(final int start, final int step) {
		int next = start;
		for (int i = 0; i < array.length; i++) {
			array[i] = next;
			next += step;
		}
		return next;
	}

	public void print() {
		ForeachImpl.delegate(array).foreach(new Action<Integer>() {

			@Override
			public void perform(Integer t) {
				System.out.print(String.format("%2s ", t));

			}
		});
	}

}</pre>
<p>Ok, na razie nic groźnego. O ile inicjację tablicy i jej wypełnienie musimy przeprowadzić iterując z palucha to już wypisanie robimy za pomocą delegowania.<br />
Teraz czas na tablicę dwu wymiarową. W tym przypadku musimy powiedzieć ile kolumn i ile rzędów chcemy mieć. Jednak czy aby na pewno? Opakowujemy w końcu kolekcję kolekcji... zatem...</p>
<p class="listing">Listing 5. Opakowana dwu wymiarowa tablica intów
<pre class="java" name="code">class Array2dInt {

	private class Next {
		int next;
	}

	private ArrayOfInt array[];

	public Array2dInt(int rows, int cols) {
		array = new ArrayOfInt[rows];
		for (int i = 0; i < array.length; i++)
			array[i] = new ArrayOfInt(cols);
	}

	public int fill(final int start) {
		return fill(start, 1);
	}

	public int fill(final int start, final int step) {
		final Next next = new Next();
		next.next = start;
		ForeachImpl.delegate(array).foreach(new Action<ArrayOfInt>() {

			@Override
			public void perform(ArrayOfInt t) {
				next.next = t.fill(next.next, step);
			}
		});

		return next.next;
	}

	public void print() {
		ForeachImpl.delegate(array).foreach(new Action<ArrayOfInt>() {

			@Override
			public void perform(ArrayOfInt t) {
				t.print();
				System.out.println("");
			}
		});
	}
}</pre>
<p>Whoa... inicjacja w konstruktorze nadal z palucha (tego nie przeskoczymy). Reszta przez delegaty. Tablica trójwymiarowa to już formalność. </p>
<p class="listing">Listing 5. Opakowana trójwymiarowa tablica intów
<pre class="java" name="code">class Array3dInt {

	private class Next {
		int next;
	}

	private Array2dInt array[];

	public Array3dInt(int rows, int cols, int depth) {
		array = new Array2dInt[depth];
		for (int i = 0; i < array.length; i++)
			array[i] = new Array2dInt(rows, cols);
	}

	public int fill(final int start) {
		return fill(start, 1);
	}

	public int fill(final int start, final int step) {
		final Next next = new Next();
		next.next = start;
		ForeachImpl.delegate(array).foreach(new Action<Array2dInt>() {

			@Override
			public void perform(Array2dInt t) {
				next.next = t.fill(next.next, step);
			}
		});

		return next.next;
	}

	public void print() {
		ForeachImpl.delegate(array).foreach(new Action<Array2dInt>() {

			@Override
			public void perform(Array2dInt t) {
				t.print();
				System.out.println("");
			}
		});
	}
}</pre>
<p>Całość można oczywiście ładnie rozdzielić na nieanonimowe klasy wewnętrzne (albo wyrzucić do osobnych klas o ograniczonej widoczności) czy uczynić generycznym. Cały kod jest, wbrew pozorom, prostszy i łatwiejszy w testowaniu. </p>
<h4>Podsumowanie</h4>
<p>Bardzo istotną rzeczą w takim podejściu do kodowania jest umiejętność rozdzielenia swojej osobowości na klienta i dostawcę. W przeciwnym wypadku możemy nieźle przestraszyć się ilością kodu. </p>
<p>Najistotniejszą cechą jest jednak ograniczenie klientowi pola manewru w pracy z kolekcją. Mając ograniczone API i pozbawiając go możliwości dowolnego manipulowania elementami możemy się zabezpieczyć przed nieprzyjemnymi sytuacjami jak chociażby usunięcie elementu z kolekcji (boli jak używasz JPA), głębokie klonowanie kolekcji albo nieskończonego iterowania.<br />
Dodatkowo operacje biznesowe są jasno określone przez co zmniejsza się prawdopodobieństwo "hakierowania" i tworzenia obejść we właściwym kodzie biznesowym. </p>
<h5>Gdzie warto używać</h5>
<p>Przede wszystkim warto opakowywać kolekcje, które wychodzą z bazy danych/DAO. W ten sposób można ograniczyć manipulowanie obiektami w ramach kodu biznesowego. Wszelkie operacje związane ze zmianą stanu bazy będą dokonywane poprzez interfejs opakowanej kolekcji. Dzięki czemu można kontrolować kto co może. W takim układzie aplikacja nie widzi DAO jako takiego. Widzi tylko interfejs dostarczający pewne dane na których można wykonać ściśle określone operacje.<br />
Po drugie MVP. W tym przypadku kolekcja staje się pomocnikiem dla prezentera. Można dzięki temu wprowadzić np. dodatkowe filtrowanie danych tuż przed ich wyświetleniem. To pozwala na stworzenie jednego prezentera, który będzie prezentował dane w zależności od potrzeb, ale będzie jednocześnie na tyle elastyczny by móc z niego skorzystać w wielu miejscach. Przykładowo kolekcja A przed wyświetleniem wymaga wycięcia części danych, których nie bardzo można pozbyć się na etapie pobierania z bazy. Jednocześnie kolekcja B nie ma tych danych już domyślnie. Obie mają metodę <samp>show</samp> przyjmującą jako parametr prezenter. Następnie w środku wywołują tylko wybrane metody prezentera.<br />
Po trzecie filtry. W takim przypadku zamiast pozwolić iterować po kolekcji możemy udostępnić klientowi ileś tam predefiniowanych metod, które filtrują kolekcję w określony sposób. Tu mała uwaga. Szkoda, że w Javie nie ma eleganckich domknięć i trzeba stosować haki w stylu anonimowych klas.</p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+8+%26%238211%3B+opakowywanie+kolekcji+w+klasy+specyficzne+dla+kontekstu+wykorzystania" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+8+%26%238211%3B+opakowywanie+kolekcji+w+klasy+specyficzne+dla+kontekstu+wykorzystania" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+8+%26%238211%3B+opakowywanie+kolekcji+w+klasy+specyficzne+dla+kontekstu+wykorzystania" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+8+%26%238211%3B+opakowywanie+kolekcji+w+klasy+specyficzne+dla+kontekstu+wykorzystania" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+8+%26%238211%3B+opakowywanie+kolekcji+w+klasy+specyficzne+dla+kontekstu+wykorzystania" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+8+%26%238211%3B+opakowywanie+kolekcji+w+klasy+specyficzne+dla+kontekstu+wykorzystania" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 8 &#8211; opakowywanie kolekcji w klasy specyficzne dla kontekstu wykorzystania' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2012/01/14/ekstremalna-obiektowosc-w-praktyce-czesc-8-opakowywanie-kolekcji-w-klasy-specyficzne-dla-kontekstu-wykorzystania/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jak ogarnąć DI?</title>
		<link>http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/</link>
		<comments>http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 14:11:10 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[miniblog]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Programowanie]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2370</guid>
		<description><![CDATA[Mini notka w miniblogu By ogarnąć DI należy napisać jeden projekt bez użycia słowa kluczowego new w kodzie biznesowym. Można go używać w provideach. Dozwolone jest też tworzenie prymitywów i Stringów &#8220;z palca&#8221;. Dodaj do]]></description>
			<content:encoded><![CDATA[<p>Mini notka w miniblogu <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>By ogarnąć DI należy napisać jeden projekt bez użycia słowa kluczowego new w kodzie biznesowym. Można go używać w provideach. Dozwolone jest też tworzenie prymitywów i Stringów &#8220;z palca&#8221;.</p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/&amp;title=Jak+ogarn%C4%85%C4%87+DI%3F" title="dodaj 'Jak ogarnąć DI?' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Jak ogarnąć DI?' do Del.icio.us" alt="dodaj 'Jak ogarnąć DI?' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/&amp;title=Jak+ogarn%C4%85%C4%87+DI%3F" title="dodaj 'Jak ogarnąć DI?' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Jak ogarnąć DI?' do digg" alt="dodaj 'Jak ogarnąć DI?' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/" title="dodaj 'Jak ogarnąć DI?' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Jak ogarnąć DI?' do Technorati" alt="dodaj 'Jak ogarnąć DI?' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/&amp;title=Jak+ogarn%C4%85%C4%87+DI%3F" title="dodaj 'Jak ogarnąć DI?' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Jak ogarnąć DI?' do Stumble Upon" alt="dodaj 'Jak ogarnąć DI?' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/&amp;title=Jak+ogarn%C4%85%C4%87+DI%3F" title="dodaj 'Jak ogarnąć DI?' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Jak ogarnąć DI?' do Google Bookmarks" alt="dodaj 'Jak ogarnąć DI?' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/&amp;t=Jak+ogarn%C4%85%C4%87+DI%3F" title="dodaj 'Jak ogarnąć DI?' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Jak ogarnąć DI?' do FaceBook" alt="dodaj 'Jak ogarnąć DI?' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/&amp;title=Jak+ogarn%C4%85%C4%87+DI%3F" title="dodaj 'Jak ogarnąć DI?' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Jak ogarnąć DI?' do wykop.pl" alt="dodaj 'Jak ogarnąć DI?' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2012/01/13/jak-ogarnac-di/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach</title>
		<link>http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/</link>
		<comments>http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 21:11:41 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2341</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Część 3 Część 4 Część 5 Część 6 Z głośników benefis Marka Niedźwieckiego. Na blogu siódma zasada Jeff’a Bay’a: Nie używaj klas o więcej niż dwóch polach Na początek kilka wyjątków, ponieważ ta zasada jest dość ciekawa. Otóż do liczby pól w klasie nie zaliczamy serialVersionUID oraz cache dla [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a><br />
<a href="http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi//">Część 3</a><br />
<a href="http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/">Część 4</a><br />
<a href="http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/">Część 5</a><br />
<a href="http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/">Część 6</a></p>
<p>Z głośników benefis Marka Niedźwieckiego. Na blogu siódma zasada Jeff’a Bay’a:</p>
<h4>Nie używaj klas o więcej niż dwóch polach</h4>
<p>Na początek kilka wyjątków, ponieważ ta zasada jest dość ciekawa. Otóż do liczby pól w klasie nie zaliczamy <samp>serialVersionUID</samp> oraz cache dla <samp>hashCode</samp> i <samp>toString</samp>. Pierwsze z wiadomego powodu &#8211; być musi jeżeli klasa jest serializowana. Reszta być może jeżeli klasa będzie niezmienna &#8211; pola będą final i obiekty w tych polach też będą niezmienne.</p>
<p>Teraz do rzeczy. </p>
<h5>Ile masz rąk?</h5>
<p>Zazwyczaj odpowiedź brzmi dwie. Nawet jeżeli jesteś &#8220;code monkey&#8221; to nadal nie posiadasz ani chwytnych stóp ani ogona. Zatem jesteś wstanie wykorzystywać tylko dwa przedmioty na raz.</p>
<h5>Co z klasami modelującymi dane?</h5>
<p>Zdawać by się mogło, że zasada ta nie jest do zastosowania wobec klas, które modelują dane (jakie to klasy? W uproszczeniu te które zawierają adnotacje JPA). Szybko można jednak dojść do wniosku, że i tu mamy pole manewru. Poza klasami posiadającymi tylko jedno pole &#8211; zasada numer 3 i zasada numer 8, są jeszcze klasy, które mają za zadanie komponować klasy zawierające po jednym polu. Jeżeli taka klas będzie miała dwa pola to będzie dość. </p>
<h5>Po co?</h5>
<p>Ok po co to robimy. W przypadku obiektów biznesowych intencja jest jasna. Im mniej pól, tym mniej wykonywanych operacji i tym samym ściślejsza odpowiedzialność.<br />
W przypadku obiektów DTO sprawa ma się trochę inaczej. Na pewno każdy prędzej czy później trafi na obiekt, który ma wiele(10+) pól i współpracuje z innymi obiektami o podobnym rozmiarze. Jest to często spotykany przypadek w starym kodzie. Prześledzenie w jaki sposób przekazywane są poszczególne wartości. Jak wygląda współpraca między nimi, co jak i dlaczego jest przekazywane. Znacznie prościej jest zatem zdekomponować klasę i otrzymać znacznie prostszy w ogarnięciu kod. Nie ma wtedy miejsca na zastanawianie się, które z dziesięciu pól do czego służy. Jesteśmy za to prowadzeni jak po sznurku od elementu do elementu.<br />
Ostatnią istotną cechą tak stworzonej hierarchii obiektów jest bardzo proste sprawdzanie poprawności stanu całego zestawu. Każdy z elementów ma własny walidator, który można odpowiednio przetestować, ma własny zestaw testów, ma w końcu jasno określony cel. Dodatkowo łatwo jest też &#8220;uniezmienniczyć&#8221; obiekty wystarczy dodać kilka razy <samp>final</samp>. </p>
<h4>Podsumowanie</h4>
<p>Problematyczne na pierwszy rzut oka wydaje się wykorzystanie tej zasady w przypadku wykorzystywania ORM. Ostatni mój projekt poprowadzony zgodnie z tymi zasadami używa JPA2. Na początku było dziwnie. Teraz jest dobrze. Grunt to poznać zasady mapowania w JPA2. Szczególnie jak mapować klasy złożone. Szczególnym przypadkiem wykorzystania tej zasady są <a href="http://koziolekweb.pl/2011/06/21/o-identyfikacji-encji-i-lenistwie-deweloperow/">naturalne klucze główne</a>, które ze swej natury organizują kod w mniejsze klasy o lepiej określonym przeznaczeniu.<br />
To tyle. Za niedługo trzeba będzie pokazać kawałek kodu <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+7+%26%238211%3B+Nie+u%C5%BCywaj+klas+o+wi%C4%99cej+ni%C5%BC+dw%C3%B3ch+polach" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+7+%26%238211%3B+Nie+u%C5%BCywaj+klas+o+wi%C4%99cej+ni%C5%BC+dw%C3%B3ch+polach" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+7+%26%238211%3B+Nie+u%C5%BCywaj+klas+o+wi%C4%99cej+ni%C5%BC+dw%C3%B3ch+polach" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+7+%26%238211%3B+Nie+u%C5%BCywaj+klas+o+wi%C4%99cej+ni%C5%BC+dw%C3%B3ch+polach" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+7+%26%238211%3B+Nie+u%C5%BCywaj+klas+o+wi%C4%99cej+ni%C5%BC+dw%C3%B3ch+polach" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+7+%26%238211%3B+Nie+u%C5%BCywaj+klas+o+wi%C4%99cej+ni%C5%BC+dw%C3%B3ch+polach" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 7 &#8211; Nie używaj klas o więcej niż dwóch polach' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/12/19/ekstremalna-obiektowosc-w-praktyce-czesc-7-nie-uzywaj-klas-o-wiecej-niz-dwoch-polach/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe</title>
		<link>http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/</link>
		<comments>http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 21:21:30 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2318</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Część 3 Część 4 Część 5 Therion &#8211; Secret of the Runes i szósta z zasad Jeff&#8217;a Bay&#8217;a Pilnuj wszystkie encje by były małe Na początek mały, obrazkowy przykład dlaczego warto pisać zwięzły kod. Oto jeden prosty program. W zasadzie jego połowa. Całość ma około 1000 linii. Tu wersja [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a><br />
<a href="http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi//">Część 3</a><br />
<a href="http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/">Część 4</a><br />
<a href="http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/">Część 5</a></p>
<p>Therion &#8211; Secret of the Runes i szósta z zasad Jeff&#8217;a Bay&#8217;a </p>
<h4>Pilnuj wszystkie encje by były małe</h4>
<p>Na początek mały, obrazkowy przykład dlaczego warto pisać zwięzły kod.<br />
<a href="http://koziolekweb.pl/wp-content/uploads/2011/12/openbrir.png"><img src="http://koziolekweb.pl/wp-content/uploads/2011/12/openbrir.png" alt="" title="openbrir" width="360" height="1196" class="aligncenter size-full wp-image-2321" /></a><br />
Oto jeden prosty program. W zasadzie jego połowa. Całość ma około 1000 linii. Tu wersja czcionką 1ką. Wyobraźmy sobie sytuację, w której:</p>
<ul>
<li>W trakcie kompilacji produkcyjnej usuwamy informacje dla debuggera.</li>
<li>Coś się spieprzyło na produkcji.</li>
<li>W stacktrace nie ma informacji o linii, bo zostały one wycięte na etapie kompilacji (piękny przykład <a href="http://devpytania.pl/questions/16531/java-kodowanie-znakow-win7-vs-winxp">tu</a>).</li>
</ul>
<p>Bingo! Szkoda tylko, że twoje serce nie wytrzymało stresu i po trzydziestej kawie odmówiło współpracy. </p>
<h5>Czym jest encja?</h5>
<p>W sumie nie encja, bo to określenie jednoznacznie kojarzy się z ORMem, POJO i generalnie klasami. Lepszym jest blok kodu, ale zostaniemy przy encji, bo tak. Inaczej mówiąc jakaś podstawowa jednostka kodu. Na nasze potrzeby przyjmijmy, że jednostką tą jest coś co powinno zdaniem czy to kompilatora czy też checkstyle zostać zamknięte pomiędzy { i }. W szczególności są to pętle, instrukcje warunkowe, metody, klasy. Dodatkowo Jeff Bay wspomina też o pakietach. </p>
<h5>Jak duża powinna być encja?</h5>
<p>Odpowiedź na to pytanie brzmi tradycyjnie &#8220;to zależy&#8221;. Najprościej rzecz ujmując zależy to od konkretnego przypadku, ale można określić pewne dobre praktyki. </p>
<p>Zacznijmy od klasy. Najprościej jest tu odnieść się do tego co dostarcza nam IDE. Klasa powinna mieścić się na ekranie. W całości. Oczywiście zanim klasa zostanie poddana temu testowi warto zwinąć javadoci. Można też trochę oszukiwać i zmniejszyć czcionkę, ale&#8230; kod musi być czytelny. Ustaw wielkość czcionki na taką jaka jest dla ciebie wygodna do pracy, uruchom edytor w trybie pełnoekranowym (Eclipse ctrl+m). Klasa ma się mieścić na ekranie. Dlaczego tak? Ponieważ tak mała klasa jest wygodna w czytaniu. Nie tylko jednak o wygodę tu chodzi. Za dużo kodu może oznaczać, że klasa ma za dużo odpowiedzialności. Względnie realizuje zbyt ogólną funkcjonalność za pomocą niskopoziomowych rozwiązań. Przykładowo klasa modem operująca bezpośrednio na ramkach. Jak temu zaradzić? Najprościej to delegować część czynności do osobnych klas, położonych &#8220;niżej&#8221; w architekturze. Wkraczamy tu na grunt grząski ponieważ większość programistów jest przyzwyczajona do sytuacji, w której <a href="http://koziolekweb.pl/2009/02/26/solidne-programowanie-czesc-1-czyli-monogamia/">SRP</a> zwalnia z patrzenia na kod przez pryzmat abstrakcji. Klas z obrazka na górze jest świetnym przykładem. Jedna odpowiedzialność 1000 linii kodu. To, że w ramach tej odpowiedzialności można wydzielić pewne mniejsze elementy&#8230; nieważne.</p>
<p>Metody są trochę prostsze do ogarnięcia. Tu można przyjąć zasadę pięciu linii &#8211; pięciu znaków ;. Jeżeli jest za dużo średników to znaczy, że robimy za dużo rzeczy naraz. Szczególnie jest to widoczne tam gdzie korzystamy ze zmiennych lokalnych. Dużo zmiennych lokalnych &#8211; dużo problemów. Zmienne lokalne są fajne, ale pod warunkiem, że ich nie używamy. Powiedzmy sobie szczerze, zmiennej lokalnej nie zastąpisz mockiem. Tym samym nie można przetestować jak zachowa się kod pod wpływem różnych wartości. Mniejszy problem jeżeli zmienna lokalna została pozyskana z parametru bądź z pola. Wtedy można to jeszcze jakoś przetestować. Gorzej jeżeli jest to zmienna pozyskana z innej zmiennej bądź za pomocą operatora <b>new</b>.<br />
Rozwiązaniem jest rozbicie metody na kilka mniejszych współpracujących ze sobą.</p>
<p>Pętle i instrukcje warunkowe. Bardzo podobne do metod. Jeżeli są dłuższe niż 5 linijek to można założyć, że robią za dużo na raz. Często też w przypadku instrukcji warunkowych przeniesienie części kodu do osobnej metody pozwala na odnalezienie pewnej grupy metod zależnych od jednego warunku, a to jest już świetnym punktem wyjścia do wprowadzenia nowej wyspecjalizowanej w obsłudze tego konkretnego warunku klasy. Dobrą praktyką jest przeniesienie całego bloku do osobnej metody &#8220;na dzień dobry&#8221;. W przypadku pętli można też zastosować zasadę nr 8 i zamiast gołej kolekcji użyć odpowiedniego obiektu opakowującego ze zdefiniowaną metodą robiącą &#8220;coś&#8221; na elementach kolekcji.</p>
<p>Na koniec pakiety. Jeff Bay określił maksymalną ilość klas w pakiecie na 10. Rzecz kontrowersyjna, ale do pewnego stopnia sensowna. Tak samo jak w przypadku klas zbyt duża ilość linii może świadczyć o wykonywaniu wielu rzeczy tak w przypadku pakietów zbyt wiele klas może być wskazówką, że pakiet jest przeładowany. Co to tak naprawdę oznacza? Przywoływana przeze mnie klasa z obrazka siedzi w pakiecie wraz z około 150 innymi klasami. Każda z tych klas to osobny bean (nie do końca, ale sens jest ten sam) zatem zdawać by się mogło, że wszystko jest OK. Tyle tylko, że czasami trzeba coś zmienić. W takim przypadku rekompilacja trwa. Testy trwają. Integracja trwa. W sumie nieźle masz czas zaparzyć trzydziestą kawę. Niewielkie pakiety promują silną modularyzację w aplikacji. O ile na co dzień nie dostrzegamy tego to mając już dwie podobne aplikacje możliwość napisania kodu raz i przenoszenia go pomiędzy aplikacjami to duży plus.<br />
Przykład z życia ELIXIR i EuroELIXIR to w praktyce identyczne aplikacje. Różnią się trochę jeśli chodzi o komunikaty przesyłane pomiędzy uczestnikami, bo wynika to z wymagań biznesowych np. Euro musi obsługiwać komunikaty w formacie XML, ale cała reszta taka jak zarządzanie oddziałami, użytkownikami, przeglądanie komunikatów, zarządzanie przebiegiem jest identyczne. Niestety COBOL i LINC nie miały możliwości pakietowania kodu. Zatem kod został zduplikowany. Po migracji duplikacja pozostała (i jest zwalczana w miarę potrzeb i wolnego czasu).<br />
Mając kod w niewielkich pakietach potencjalna ekstrakcja interesującego nas fragmentu do osobnego projektu będzie stosunkowo prosta.</p>
<h4>Inne metody skracania kodu</h4>
<p>Zanim jednak zabierzemy się za skracanie kody warto przyjrzeć się kilku technikom pozwalającym na pisanie mniejszych ilości kodu od ręki.</p>
<h5>Biblioteki</h5>
<p>Na początek warto zastanowić się czy jakiś fragment kodu nie został już napisany. Świetnym przykładem jest wprowadzona w Javie 7 klasa <samp>Objects</samp> wywodząca się z Commons Lang i dostarczająca builderów dla metod <samp>equals</samp> czy <samp>hashCode</samp>. Podobnie ma się sprawa z np. serializacją obiektów do XML (tu polecam <a href="http://simple.sourceforge.net/">Simple</a> &#8211; łatwe proste i nawet nie ma bugów). Osobnym zagadnieniem są oczywiście frameworki oraz Lombok.</p>
<h5>Mechanizmy języka</h5>
<p>W tym standardy. Zamiast po raz setny pisać warunek na nie nullowy parametr można użyć Bean Validation i adnotacji <samp>@NotNull</samp> (od wersji 1.1 także dla parametrów metod) albo jak nie mamy ochoty na kod beta machnięcie kilku aspektów. Szczególnie przydatnymi narzędziami są tu rozwiązania Dependency Injection w wersji czy to Springa, czy to CDI czy to Java Inject (Guice).</p>
<h5>Własne standardy</h5>
<p>Mój faworyt:</p>
<p class="listing">Listing 1. Po co ten if</p>
<pre class="java" name="code">public void doSth(Param param){
    if(param == null){
        throw new NullPointerException("Param is null");
    }
    param.someMethod();
}</pre>
<p>NPE i tak by poleciał, a rzucanie wyjątku tylko by go wyrzucić mija się z celem. Szczególnie, że komunikat nic nie wnosi. W zamian warto jasno określić czy metoda akceptuje np. <samp>null</samp>. Jak nie akceptuje to zanim wstawimy warunek warto sprawdzić czy wywołanie metody już domyślnie nie wywali błędu. Zawsze jeden if mniej. Podobnie w przypadku weryfikacji. Jeżeli już rzucamy wyjątkiem to niech komunikat coś mówi. Zresztą obsługa wyjątków to osobny temat.</p>
<h4>Podsumowanie</h4>
<p>Jest to, nie ukrywam, bardzo trudna do wdrożenia zasada. Często można spotkać się z oporem przed rozbijaniem kodu na drobne klasy. Warto jednak pamiętać, że szczególnie większe projekty, warto rozdrabniać. Ma to na celu maksymalne uproszczenie testowania kodu i jego późniejszego utrzymania. Rozdrobnienie pozwala też na szybkie wyłapanie zduplikowanego kodu oraz błędów w projekcie. Szczególnie ta ostatnia cecha jest pożądana ponieważ pozwala na wczesne wykrywanie miejsc podatnych na błędy czy nieprzewidzianych lecz możliwych stanów aplikacji, przypadków użycia czy też innych sytuacji. </p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+6+%26%238211%3B+Pilnuj+wszystkie+encje+by+by%C5%82y+ma%C5%82e" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+6+%26%238211%3B+Pilnuj+wszystkie+encje+by+by%C5%82y+ma%C5%82e" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+6+%26%238211%3B+Pilnuj+wszystkie+encje+by+by%C5%82y+ma%C5%82e" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+6+%26%238211%3B+Pilnuj+wszystkie+encje+by+by%C5%82y+ma%C5%82e" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+6+%26%238211%3B+Pilnuj+wszystkie+encje+by+by%C5%82y+ma%C5%82e" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+6+%26%238211%3B+Pilnuj+wszystkie+encje+by+by%C5%82y+ma%C5%82e" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 6 &#8211; Pilnuj wszystkie encje by były małe' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/12/05/ekstremalna-obiektowosc-w-praktyce-czesc-6-pilnuj-wszystkie-encje-by-byly-male/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw</title>
		<link>http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/</link>
		<comments>http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 20:38:43 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2310</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Część 3 Część 4 Dziś smutna, 20 rocznica śmierci Freddego Mercurego. Z tej okazji z głośników Queen, a na tapecie piąta z zasad Jeff&#8217;a Bay&#8217;a Nie skracaj nazw Każdy kto choć trochę interesował się zagadnieniem jakości kodu wie, że najlepszy kod to kod samo-dokumentujący się. Innymi słowy jeżeli czytamy [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a><br />
<a href="http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi//">Część 3</a><br />
<a href="http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/">Część 4</a></p>
<p>Dziś smutna, 20 rocznica śmierci Freddego Mercurego. Z tej okazji z głośników Queen, a na tapecie piąta z zasad Jeff&#8217;a Bay&#8217;a</p>
<h4>Nie skracaj nazw</h4>
<p>Każdy kto choć trochę interesował się zagadnieniem jakości kodu wie, że najlepszy kod to kod samo-dokumentujący się. Innymi słowy jeżeli czytamy jakiś fragment, metodę czy kilka metod, to bez zagłębiania się w niższe warstwy możemy na podstawie samej nazwy, czy szerzej sygnatury, metody określić mniej więcej co ona robi.</p>
<p>Z drugiej strony nikt nie lubi pisać długich nazw. Jest to niewygodne. Dlatego tak ważne jest opanowanie IDE. Dzięki temu bardzo łatwo będziemy wstanie dostać się do systemu podpowiadania nazw. To znowuż zaoszczędzi nam czasu. Jeżeli jeszcze dodatkowo zdefiniujemy własne szablony kodu to pisanie staje się czystą przyjemnością.</p>
<h5>Liberum Veto!</h5>
<p>Jeff Bay porusza jednak znacznie ważniejszy aspekt związany z nazewnictwem zmiennych, metod oraz klas. Jest to zniechęcenie, które pojawia się gdy wielokrotnie musimy powtarzać daną nazwę.<br />
Czyli co? Skrócić nazwę?<br />
I tak i nie. Jeżeli jakaś nazwa przewija się w kodzie wielokrotnie może to sygnalizować kilka problemów:</p>
<ul>
<li>Metoda jest przeładowana.</li>
<li>Zgubiliśmy klasę.</li>
<li>Źle określiliśmy zakres odpowiedzialności.</li>
</ul>
<h5>Metoda jest przeładowana</h5>
<p>Oznacza to, że metoda wykonuje kilka rzeczy w zależności od wartości argumentów. Zazwyczaj na początku mamy kilka ifów, które pełnią rolę routera kierując przepływ sterowania w oparciu o jakąś wartość.<br />
Rozwiązaniem jest rozdzielenie metody na kilka mniejszych i jeżeli istnieje konieczność zmiana w kodzie wywołującym tak by ograniczyć ilość instrukcji warunkowych. Warto też zastanowić się nad tym, czy dana operacja powinna być wykonana NA obiekcie czy raczej powinna być wykonana PRZEZ obiekt.</p>
<h5>Zgubiliśmy klasę</h5>
<p>Szczególnie widoczna przypadłość wszelkich klas <samp>Utils</samp> gdzie w ramach jednej klasy utrzymujemy wiele metod robiących wiele kompletnie nie związanych ze sobą rzeczy. Jeżeli w naszym kodzie dana klasa pojawia się często w różnych kontekstach warto rozbić ją na mniejsze bardziej wyspecjalizowane. Jeżeli nie jest to możliwe to należy pamiętać o adnotacji <samp>@Deprecated</samp> i wydelegować poszczególne grupy metod do osobnych klas. Zostaniemy w ten sposób z &#8220;klasą wydmuszką&#8221;, którą będzie można stosunkowo łatwo usunąć.</p>
<h5>Źle określiliśmy zakres odpowiedzialności</h5>
<p>Przypadek gdzieś pomiędzy wcześniejszymi. Z jednej strony dana metoda robi jedną rzecz, ale przy okazji wykonuje kilka dodatkowych czynności zazwyczaj związanych z walidacją parametrów czy sprawdzeniem stanu obiektu. W takim wypadku warto zastanowić się nad zmianą w kodzie tak by sprawdzać dane i delegować zadanie dalej albo założyć, że dane są zawsze dobre i nie ma sensu ich sprawdzanie.<br />
Oba rozwiązania są poprawne, a wybór konkretnego zależy w znacznej mierze od przyjętej w ramach projektu konwencji oraz tego na jakim poziomie aplikacji jesteśmy.</p>
<h4>Podsumowanie</h4>
<p>Przestrzeganie tej zasady jest bardzo proste i powinno być naszym nawykiem. Dzięki niej nie tylko zyskujemy czas w trakcie czytania kodu, ale też możemy sprawnie identyfikować miejsca w kodzie, które wymagają poprawek. Co do zasady takie podejście sprawdza się w obu kierunkach. Jeżeli nie potrafimy nadać krótkiej i znaczącej nazw, która nie zawiera skrótowców to nasz kod wymaga poprawki.<br />
Jak zawsze też w przypadku zasad Jeff&#8217;a Bay&#8217;a musimy uzbroić się w dobrą znajomość IDE. Bez tego będzie bardzo ciężko.</p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+5+%26%238211%3B+Nie+skracaj+nazw" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+5+%26%238211%3B+Nie+skracaj+nazw" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+5+%26%238211%3B+Nie+skracaj+nazw" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+5+%26%238211%3B+Nie+skracaj+nazw" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+5+%26%238211%3B+Nie+skracaj+nazw" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+5+%26%238211%3B+Nie+skracaj+nazw" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 5 &#8211; Nie skracaj nazw' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/11/24/ekstremalna-obiektowosc-w-praktyce-czesc-5-nie-skracaj-nazw/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię</title>
		<link>http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/</link>
		<comments>http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/#comments</comments>
		<pubDate>Sun, 20 Nov 2011 19:30:12 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Egg Framework]]></category>
		<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2296</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Część 3 Słuchając Manowar dzielnie zagłębiamy się w czwartą z zasad Jeff&#8217;a Bay&#8217;a. Używaj tylko jednej kropki na linię Jeżeli przejrzymy dowolny kod pisany &#8220;na szybko&#8221; będziemy wstanie znaleźć tego typu potworki jak ten tutaj: Listing 1. Typowy &#8220;łańcuszek&#8221; w kodzie package pl.koziolekweb.eowp4; public class App { public static [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a><br />
<a href="http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi//">Część 3</a></p>
<p>Słuchając Manowar dzielnie zagłębiamy się w czwartą z zasad Jeff&#8217;a Bay&#8217;a.</p>
<h4>Używaj tylko jednej kropki na linię</h4>
<p>Jeżeli przejrzymy dowolny kod pisany &#8220;na szybko&#8221; będziemy wstanie znaleźć tego typu potworki jak ten tutaj:</p>
<p class="listing">Listing 1. Typowy &#8220;łańcuszek&#8221; w kodzie</p>
<pre class="java" name="code">package pl.koziolekweb.eowp4;

public class App {

	public static void main(String[] args) {
		Person person = new Person();
		person.name ="Ilona";
		System.out.println(isFemaleName(person));
	}

	public static boolean isFemaleName(Person person) {
		return person.name.lastIndexOf("a") == person.name.length() - 1;
	}

}

class Person {

	String name;

}</pre>
<p>Mamy tu do czynienia z typowym &#8220;łańcuszkiem&#8221; wywołań metod. Kod ten będzie działał w oparciu o wiarę programisty w to, że po drodze nic się nie stanie.<br />
Innym często spotykanym rozwiązaniem związanym z obsługą XMLa jest taki oto potworek:</p>
<p class="listing">Listing 2. Następny &#8220;łańcuszek&#8221; tu obsługa XML.</p>
<pre class="java" name="code">Element newDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().getDocumentElement();
</pre>
<h5>Dlaczego jest to złe?</h5>
<p>Wraz z budową tego typu konstrukcji pojawiają się też błędy. Najpopularniejszym jest klasyczny <samp>NullPointerException</samp>, który występuje &#8220;gdzieś w linii numer&#8221;. W takim przypadku zaczyna się walka z debuggrem albo dupa-debug i rozpisywanie kolejnych &#8220;kropek&#8221; na pojedyncze zmienne. Tak jest zazwyczaj w drugim przedstawionym przypadku.<br />
Ze znacznie poważniejszym problemem mamy do czynienia w pierwszym przykładzie. Pomijając już to co pisałem w poprzedniej części na temat opakowywania typów prostych i stringów to mamy tu jeszcze bonus w postaci zignorowania podstawowych zasad programowania obiektowego. W tamtym przykładzie brakuje najzwyczajniej enkapsulacji. Wprowadzenie gettera nic nie da, bo &#8220;goły&#8221; getter służy tylko poprawie samopoczucia programisty, ale nie zapewnia enkapsulacji.<br />
Dlaczego jest to takie ważne? Ponieważ jeżeli olejemy w Javie zasady programowania obiektowego to równie dobrze można przesiąść się na COBOLa. </p>
<h5>Jak temu zaradzić</h5>
<p>Najprościej jest zastosować <a href="http://pl.wikipedia.org/wiki/Prawo_Demeter" target="_blank" title="From Wikipedia the definition of: Prawo Demeter" class="wikiterm" >Prawo Demeter</a><sup class="wikiicon" ><em>W</em></sup>. Jest to jednak dość ryzykowna zabawa. Przede wszystkim jeżeli mamy kiepsko przemyślaną strukturę to łańcuszek kropek zostanie zastąpiony przez łańcuszek metod. Co ciekawe kod wykazuje tu zadziwiająca właściwość do składowania tych metod jako publiczne w ramach obiektu, w którym mieliśmy łańcuszek. Jeff Bay proponuje więc trochę lżejszą wersję tego prawa. Mówi ona, że możesz:</p>
<ul>
<li>Bawić się własnymi zabawkami &#8211; legalne jest &#8220;łańcuszkowanie&#8221; metod prywatnych.</li>
<li>Bawić się zabawkami, które skonstruujesz &#8211; legalne jest użycie dowolnych metod z tworzonych lokalnie obiektów.</li>
<li>Bawić się zabawkami, które ktoś ci dał &#8211; możesz wywoływać metody obiektów przekazanych w parametrach metody.</li>
</ul>
<p>Zabrania się jednak zabawy &#8220;zabawkami zabawek&#8221;, czyli w praktyce jeżeli chcemy stworzyć kod taki jak w drugim przypadku to powinniśmy zamiast kilkunastu kolejnych wywołań otrzymać zabawkę &#8211; instancję <samp>Document</samp> i na niej wywołać odpowiednią metodę. Wynik tej metody przekazać niżej jako nasz podarunek dla wywoływanego obiektu.<br />
W pierwszym przypadku należało by zupełnie inaczej rozmieścić metody. Jako, że naszą zabawką jest obiekt klasy <samp>Person</samp> to nie możemy wykorzystać metod pola <samp>name</samp> (zabawka zabawki), nie za bardzo idzie też stworzyć nową zabawkę (np. dynamicznie dodać metodę &#8211; brak dynamicznego rozszerzania klas, ale już w Groovym będzie działać). Zostaje zatem zmiana właściciela metody tak by zabawki zostały w słusznej piaskownicy.</p>
<p class="listing">Listing 3. Wszystkie zabawki w swoich piaskownicach</p>
<pre class="java" name="code">package pl.koziolekweb.eowp4;

public class App {

	public static void main(String[] args) {
		Person person = new Person();
		person.name = "Ilona";
		System.out.println(person.isFemaleName());
	}

}

class Person {

	String name;

	boolean isFemaleName() {
		return name.lastIndexOf("a") == name.length() - 1;
	}
}
</pre>
<p>W ten sposób wszystko jest na swoim miejscu. W dodatku logika też trzyma się kupy. Klasa <samp>Person</samp> potrafi powiedzieć czy jest chłopcem czy dziewczynką.</p>
<h4>Wyjątek</h4>
<p>W ogólności unikanie wielu kropek w linii poza wymuszeniem lepszego rozłożenia metod i ulepszeniem ogólnego designu kodu poprawia też jego czytelność. Jest to bardzo dobre jeżeli np. korzystamy z Criteria API czy też podobnych wynalazków gdzie &#8220;da się&#8221; tworzyć konstrukcje typu przekazanie jako parametru metody trzech wywołań jakiś metod. Jest jednak pewien wyjątek od tej zasady. Jest nią wykorzystanie <a href="http://en.wikipedia.org/wiki/Fluent_interface">fluent interface</a>.</p>
<h5>Hej, ale tam są zabawki zabawek!</h5>
<p>No nie do końca. Założeniem tego modelu programowania jest niezwracanie <samp>void</samp>. Jeżeli jakaś metoda nie zwraca nic to powinna zwracać <samp>this</samp>. W ten sposób możemy łatwiej tworzyć czytelny kod. Przy czym czytelność będzie zależała w znacznej mierze od konfiguracji IDE <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Świetny przykład pokazał Jacek Olszak we <a href="http://jacekolszak.blogspot.com/2007/12/fluent-interface-w-egg-framework-20.html">wpisie</a> o FI w <a href="https://github.com/jacekolszak/EggFramework">EggFramework</a>. W praktyce zabawka zwraca samą siebie (bez klonowania mi tu!).</p>
<h4>Podsumowanie</h4>
<p>Czwarta z zasad jest z serii tych wrednych. Z jednej strony bardzo prosta do wprowadzenia, ale jednocześnie obnaży nawet najmniejsze nieprawidłowości w projekcie klasy. Zasada ta świetnie sprawdza się jeżeli chcemy utrzymywać porządek w interfejsie klas i nie do końca wiemy gdzie umieścić daną metodę.<br />
Szczególnie pomocna staje się ona w momencie gdy korzystamy z kontenera DI. W takim momencie bardzo łatwo jest określić czy dana operacja powinna być wykonana na danym poziomi, czy też lepszym rozwiązaniem nie będzie przeniesienie jej w głąb i udostępnienie jako pojedynczej operacji.</p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+4+%26%238211%3B+U%C5%BCywaj+tylko+jednej+kropki+na+lini%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+4+%26%238211%3B+U%C5%BCywaj+tylko+jednej+kropki+na+lini%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+4+%26%238211%3B+U%C5%BCywaj+tylko+jednej+kropki+na+lini%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+4+%26%238211%3B+U%C5%BCywaj+tylko+jednej+kropki+na+lini%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+4+%26%238211%3B+U%C5%BCywaj+tylko+jednej+kropki+na+lini%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%26%238211%3B+cz%C4%99%C5%9B%C4%87+4+%26%238211%3B+U%C5%BCywaj+tylko+jednej+kropki+na+lini%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce &#8211; część 4 &#8211; Używaj tylko jednej kropki na linię' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/11/20/ekstremalna-obiektowosc-w-praktyce-czesc-4-uzywaj-tylko-jednej-kropki-na-linie/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi</title>
		<link>http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/</link>
		<comments>http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 19:45:13 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2285</guid>
		<description><![CDATA[Część 0 Część 1 Część 2 Z głośników spokojnie tym razem. Era. Swoją drogą przypominają mi się stare dobre czasy gdy przy &#8220;Ameno&#8221; przerąbywałem się przez kolejne poziomy w Diablo: Hellfire. Wspomnienia, wspomnieniami czas jednak zająć się trzecią z zasad Jeff&#8217;a Bay&#8217;a. Opakowuj wszystkie prymitywy i Stringi(w klasy o specyficznej dla zastosowania nazwie) Rozejrzyj się [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a><br />
<a href="http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/">Część 2</a></p>
<p>Z głośników spokojnie tym razem. Era. Swoją drogą przypominają mi się stare dobre czasy gdy przy &#8220;Ameno&#8221; przerąbywałem się przez kolejne poziomy w Diablo: Hellfire.<br />
Wspomnienia, wspomnieniami czas jednak zająć się trzecią z zasad Jeff&#8217;a Bay&#8217;a.</p>
<h4>Opakowuj wszystkie prymitywy i Stringi(w klasy o specyficznej dla zastosowania nazwie)</h4>
<p>Rozejrzyj się wokoło. Zobacz jak zbudowany jest świat. Szybko stwierdzisz, że świat składa się z obiektów, które wchodzą w interakcje. Tak mniej więcej zaczyna się jakieś 99% kursów dotyczących programowania obiektowego. Pozostałe 1% zaczyna się mniej więcej tak: php jest językiem obiektowym.<br />
Rzecz w tym, że w realnym świecie nie występują liczby, znaki czy stringi. Służą one do opisania jakiś konkretnych przedmiotów są ich cechami i wartościują je według określonego wzorca. W Javie liczby są przedstawione jako typu proste, a autoboxing jest tylko dodatkiem pozwalającym na łatwiejszą pracę z nimi. Swoją drogą powoduje to cholernie wiele problemów jeżeli chcemy używać typów liczbowych w metodach przyjmujących Object i przez przypadek podamy z palca prymitywa. To jednak zupełnie inny temat.</p>
<h4>Program opisuje świat</h4>
<p>Tak jak w realnym świecie tak i w aplikacji nie powinno używać się typów prostych i stringów. W ich miejsce należy wprowadzać niewielkie klasy reprezentujące atomową jednostkę &#8220;czegoś&#8221;. Klasa taka powinna mieć znaczenie biznesowe ponieważ reprezentuje pewną małą istotę żyjącą w ramach systemu.</p>
<p>Na początek pewien prosty przykład. </p>
<p class="listing">Listing 1. Typ prymitywny i &#8220;ciekawy błąd&#8221;</p>
<pre class="java" name="code">package pl.koziolekweb.eowp3;

public class MoneyExample {

	public static void main(String[] args) {
		Konto konto = new Konto();
		print(konto.stan());
		konto.uznaj(10);
		print(konto.stan());
		konto.obciąż(5);
		print(konto.stan());
		konto.uznaj(-3);
		print(konto.stan());
		konto.obciąż(-5);
		print(konto.stan());
	}

	private static void print(int stan){
		System.out.println("Stan konta to " + stan);
	}
}

class Konto {

	private int stan = 0;

	public void uznaj(int wartość) {
		stan += wartość;
	}

	public void obciąż(int wartość) {
		stan -= wartość;
	}

	public int stan(){
		return stan;
	}
}</pre>
<p>Błąd widać na pierwszy rzut oka. Prymitywne typy danych prowokują do tego typu &#8220;ekscesów&#8221;. Oczywiście można wprowadzić dodatkowy walidator i bawić się w sprawdzanie czy przekazywana wartość nie jest mniejsza od 0. Jeżeli jednak operacje na danej wartości przeprowadzamy w różnych miejscach w aplikacji warto wprowadzić klasę zamiast typu prymitywnego. Jeff Bay idzie dalej i mówi, iż skoro w świecie realnym nie istnieją typy proste jako samodzielne twory to nie należy ich używać w aplikacji.</p>
<h5>Typy prymitywne</h5>
<p>Oczywiście trochę inaczej należy traktować typy proste, a inaczej String. Trochę lepsze rozwiązanie:</p>
<p class="listing">Listing 2. Typ prymitywny i obejście</p>
<pre class="java" name="code">package pl.koziolekweb.eowp3;

public class MoneyExampleWithType {

	public static void main(String[] args) {
		Konto2 konto = new Konto2();
		print(konto.stan());
		konto.uznaj(new Kwota(10));
		print(konto.stan());
		konto.obciąż(new Kwota(5));
		print(konto.stan());
		konto.uznaj(new Kwota(-3));
		print(konto.stan());
		konto.obciąż(new Kwota(-5));
		print(konto.stan());
	}

	private static void print(Stan stan) {
		System.out.println("Stan konta to " + stan);
	}

}

class Konto2 {

	private Stan stan = new Stan(0);

	public void uznaj(Kwota kwota) {
		stan.uznaj(kwota);
	}

	public void obciąż(Kwota kwota) {
		stan.obciąż(kwota);
	}

	public Stan stan() {
		return stan;
	}
}

class Kwota implements Wartość<Integer> {

	private final int wartość;

	public Kwota(int wartość) {
		if (wartość < 0)
			throw new IllegalArgumentException("Kwota nieprawidłowa.");
		this.wartość = wartość;
	}

	@Override
	public Integer wartość() {
		return wartość;
	}

}

class Stan {

	private int wartość = 0;

	public Stan(int i) {
		wartość = i;
	}

	public void uznaj(Kwota kwota) {
		wartość += kwota.wartość();
	}

	public void obciąż(Kwota kwota) {
		wartość -= kwota.wartość();
	}

	@Override
	public String toString() {
		return "" + wartość;
	}
}

interface Wartość<T extends Number> {
	T wartość();
}</pre>
<p>Przykład działa w tym przypadku całkiem nieźle, ale&#8230; no właśnie. Jest sobie interfejs <samp>Wartość</samp>, który tan naprawdę psuje nam wszystko. Z dwóch powodów. Pierwszy to ujawnia jak trzymana jest implementacja typu prostego w klasie <samp>Kwota</samp>. Drugi nadal operujemy bezpośrednio na typie prostym. Czas wyciągnąć naszą ulubioną broń, czyli dziedziczenie.</p>
<p class="listing">Listing 3. Typ prymitywny i dobre podejście</p>
<pre class="java" name="code">package pl.koziolekweb.eowp3;

public class MoneyExampleWithExtends {
	public static void main(String[] args) {
		Konto3 konto = new Konto3();
		print(konto.stan());
		konto.uznaj(new KwotaBazowa(10));
		print(konto.stan());
		konto.obciąż(new KwotaBazowa(5));
		print(konto.stan());
		konto.uznaj(new KwotaBazowa(3));
		print(konto.stan());
		konto.obciąż(new KwotaBazowa(15));
		print(konto.stan());
	}

	private static void print(StanKonta stan) {
		System.out.println("Stan konta to " + stan);
	}
}

class Konto3 {

	private StanKonta stan = new StanKonta(0);

	public void uznaj(KwotaBazowa kwota) {
		stan = stan.uznaj(kwota);
	}

	public void obciąż(KwotaBazowa kwota) {
		stan = stan.obciąż(kwota);
	}

	public StanKonta stan() {
		return stan;
	}
}

class KwotaBazowa {

	protected final int wartość;

	public KwotaBazowa(int wartość) {
		if (wartość < 0)
			throw new IllegalArgumentException("Kwota nieprawidłowa.");
		this.wartość = wartość;
	}

}

class StanKonta extends KwotaBazowa {

	private Debet debet = Debet.N;

	private enum Debet {
		T {
			int v() {
				return -1;
			}
		},
		N {
			int v() {
				return 1;
			}
		};
		abstract int v();

		public static Debet czyDebet(int i) {
			if (i < 0)
				return T;
			return N;
		}
	}

	public StanKonta(int i) {
		this(i, Debet.N);
	}

	private StanKonta(int i, Debet debet) {
		super(i);
		this.debet = debet;
	}

	public StanKonta uznaj(KwotaBazowa kwota) {
		int nowaWartość = debet.v() * wartość + kwota.wartość;
		return new StanKonta(Math.abs(nowaWartość), Debet.czyDebet(nowaWartość));
	}

	public StanKonta obciąż(KwotaBazowa kwota) {
		int nowaWartość = debet.v() * wartość - kwota.wartość;
		return new StanKonta(Math.abs(nowaWartość), Debet.czyDebet(nowaWartość));
	}

	@Override
	public String toString() {
		return "" + debet.v() * wartość;
	}
}</pre>
<p>Oczywiście ten kod wymaga jednej rzeczy. Testów (oraz synchronizacji, ale to inna inszość). Tych nie prezentuję, bo są nudne, ale trzeba je napisać. OK, ale co się stało? Przede wszystkim <samp>StanKonta</samp> reprezentuje kwotę (klasa nazywa się <samp>KwotaBazowa</samp>, bo siedzi w jednym pakiecie z poprzednimi przykładami i się kompilator burzy). Rozszerzyliśmy jednak zachowanie tej klasy w ten sposób, że poza zawsze dodatnią kwotą ma jeszcze flagę <samp>Debet</samp>. Flaga ta mogła być typu <samp>Boolean</samp>, ale... nie można by było wtedy uzyskać efektu wartości oraz metody <samp>czyDebet</samp> - <samp>Boolean</samp> jest <samp>final</samp>. To rozwiązanie ma pewne wady. Przede wszystkim rozwlekło kod. Wymaga też testów, ale... pierwotne rozwiązanie nadal wymaga testów w dodatku jest znacznie bardziej podatne na błędy (spróbujcie wrzucić do stanu konta np. zrzutowany <samp>char</samp>). Z drugiej strony uzyskaliśmy kod odporny na durne błędy. Łatwy w testowaniu. Jeżeli dodatkowo odpowiednio go popaczkujemy to będzie przenośny pomiędzy projektami.</p>
<h5>Typ String</h5>
<p>Podobnie jak typy proste typ <samp>String</samp> nie występuje w naturze z jednym wyjątkiem:<br />
<div id="attachment_2286" class="wp-caption aligncenter" style="width: 620px"><a href="http://koziolekweb.pl/wp-content/uploads/2011/11/object.toString.jpg"><img src="http://koziolekweb.pl/wp-content/uploads/2011/11/object.toString.jpg" alt="getStringFromObject" title="object.toString" width="610" height="761" class="size-full wp-image-2286" /></a><p class="wp-caption-text">getStringFromObject</p></div></p>
<p>i tego wyjątku się trzymajmy.</p>
<p>Generalnie typ znakowy jest używany dość często jako nośnik informacji. Począwszy od dupereli typu imię i nazwisko, poprzez hasła, loginy, kończąc na adresach URL czy adresach usług. Przesłanianie tego typu ma jednak dwie zalety.</p>
<p>Po pierwsze pozwala na wprowadzenie dodatkowych walidacji na etapie tworzenia obiektu. Tym samym mamy kontrolę nad tym co tworzymy i nie posypie się np. <samp>MalformedURLException</samp> czy nie otrzymamy pustego napisu.<br />
Po drugie znacznie łatwiej jest zarządzać kodem mając konkretny typ, a nie enigmatyczny <samp>String</samp>. Przykłady wymyślcie sobie sami.</p>
<h4>Inne typy proste</h4>
<p>Że co? Czy w Javie są jeszcze jakieś inne typy proste poza prymitywami(plus ich obiektowe wersje) oraz <samp>String</samp>? To zależy jak na to spojrzymy. Jeff Bay mówi o typach prostych, ale ja osobiści zalecam dodanie do listy typów prostych takich, które pochodzą z różnych narzędzi. Przykładowo jeżeli tworzymy XMLa i mamy schemę to warto poza walidacją ze schemą rozszerzyć klasy typu <samp>Node</samp> by uzyskać efekt wstępnej walidacji np. by nie wstawić nieprawidłowej nazw elementu.<br />
Podobnie ma się rzecz z usługami sieciowymi. Tu wartą rozszerzenia jest klasa <samp>QName</samp>, szczególnie jeżeli wywołujemy usługi w sieci z ograniczonym dostępem. Można wtedy wprowadzić dodatkową walidację by sprawdzać już na wstępie czy dana usługa jest osiągalna. Pozwoli to na kontrolowane wyłapanie baboli.</p>
<h4>Podsumowanie</h4>
<p>Zasada ta jest dość trudna w zastosowaniu. Wymaga umiejętnego użycia zarówno interfejsów jak i dziedziczenia. Tworząc taki kod warto zadawać sobie pytanie "Czy A to B?". Pozwoli to na uproszczenie kodu i wczesne wyłapanie pewnych abstrakcji. Rozwiązanie tego typu pociąga za sobą pewne niedogodności. Przede wszystkim uzyskujemy prawdziwą enkapsulację. Innymi słowy łatwo wyeliminować tu gettery/settery, co pociąga za sobą spore problemy natury prezentacyjnej. Ten problem poruszę jednak w ostatniej części. Na razie można używać getterów <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+3+%26%238211%3B+Opakowuj+wszystkie+prymitywy+i+Stringi" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+3+%26%238211%3B+Opakowuj+wszystkie+prymitywy+i+Stringi" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+3+%26%238211%3B+Opakowuj+wszystkie+prymitywy+i+Stringi" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+3+%26%238211%3B+Opakowuj+wszystkie+prymitywy+i+Stringi" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+3+%26%238211%3B+Opakowuj+wszystkie+prymitywy+i+Stringi" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+3+%26%238211%3B+Opakowuj+wszystkie+prymitywy+i+Stringi" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 3 &#8211; Opakowuj wszystkie prymitywy i Stringi' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/11/06/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-3-opakowuj-wszystkie-prymitywy-i-stringi/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else</title>
		<link>http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/</link>
		<comments>http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 12:25:05 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2279</guid>
		<description><![CDATA[Część 0 Część 1 Drugą część cyklu Ekstremalna obiektowość w praktyce czas zacząć. W głośnikach leci sobie Hammerfall, a my zajmiemy się drugą zasadą Jeff&#8217;a Bay&#8217;a. Nie używaj słowa kluczowego else Przecież to nic trudnego powiecie. Zatem na początek mały przykład kodu, w którym waszym zadaniem będzie zastosowanie tej zasady: Listing 1. Jak by tu [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a><br />
<a href="http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/">Część 1</a></p>
<p>Drugą część cyklu Ekstremalna obiektowość w praktyce czas zacząć. W głośnikach leci sobie Hammerfall, a my zajmiemy się drugą zasadą Jeff&#8217;a Bay&#8217;a. </p>
<h4>Nie używaj słowa kluczowego else</h4>
<p>Przecież to nic trudnego powiecie. Zatem na początek mały przykład kodu, w którym waszym zadaniem będzie zastosowanie tej zasady:</p>
<p class="listing">Listing 1. Jak by tu usunąć <samp>else</samp></p>
<pre class="java" name="code">public AbstractServiceStub(Object object) {
		if (service == null) {
			super.service = new Service();
		} else {
			super.service = service;
		}
		((Service) super.service).setTypeMappingVersion("1.1");
	}</pre>
<p>To jest kod wygenerowany przez AXIS. Trzeba z niego usunąć słówko kluczowe <samp>else</samp>. Proste, prawda?</p>
<p>W tym przypadku wystarczy użyć Extract Method w celu wyciągnięcia inicjalizacji do oddzielnego bloku:</p>
<p class="listing">Listing 2. Usunięcie <samp>else</samp> przez Extract Method</p>
<pre class="java" name="code">private void initService(final Service service) {
		if (Assertions.isNull(service)) {
			super.service = new Service();
			return;
		}
		super.service = service;
	}</pre>
<p>Metoda prosta i skuteczna. Życie nie jest jednak takie proste za każdym razem. </p>
<h5>Określony przepływ</h5>
<p>Trochę bardziej skomplikowane zadanie. Jest sobie obiekt <samp>State</samp> reprezentujący różne stany konfiguracji &#8211; prawidłowy, nieprawidłowy i niezainicjowany. Trzeba zaprogramować prawidłową zmianę stanu, czyli:</p>
<ul>
<li>Ze stanu niezainicjowany można zmienić stan na prawidłowy i nieprawidłowy.</li>
<li>Ze stanu prawidłowy można zmienić stan na nieprawidłowy.</li>
<li>Ze stanu nieprawidłowy nie można zmienić już stanu.</li>
</ul>
<p>Oczywistą sprawą będzie użycie enuma. Mniej oczywiste jest zmienianie stanu:</p>
<p class="listing">Listing 3. Uzależnienie wartości zwracanej od różnych warunków</p>
<pre class="java" name="code">package pl.koziolekweb.eowp2;

public enum State {

	VALID, INVALID, NOT_INIT;

	public State changeState(State target) {
		if (target == VALID &#038;&#038; this != INVALID) {
			return VALID;
		} else if (target == INVALID) {
			return INVALID;
		} else if (target == NOT_INIT &#038;&#038; this == NOT_INIT) {
			return NOT_INIT;
		} else {
			return this;
		}
	}
}</pre>
<p>Zaszalałem <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  Ok, co można tu zrobić? Można oczywiście zamiast konstrukcji <samp>else if</samp> zastosować kilka <samp>if</samp>ów, a zamiast ostatniego <samp>else</samp> zwracać <samp>this</samp> jako wartość domyślną. wtedy będzie to wyglądało mniej więcej tak:</p>
<p class="listing">Listing 4. Uzależnienie wartości zwracanej od różnych warunków bez <samp>else</samp></p>
<pre class="java" name="code">package pl.koziolekweb.eowp2;

public enum State {

	VALID, INVALID, NOT_INIT;

	public State changeState(State target) {
		if (target == VALID &#038;&#038; this != INVALID) {
			return VALID;
		}
		if (target == INVALID) {
			return INVALID;
		}
		if (target == NOT_INIT &#038;&#038; this == NOT_INIT) {
			return NOT_INIT;
		}
		return this;

	}
}</pre>
<p>W sumie nie zmieniło się nic. </p>
<h5>Drugi <samp>if</samp> w metodzie to tak naprawdę ukryty <samp>else</samp></h5>
<p>Nie ma w tym nic dziwnego. Po prostu formułkę &#8220;Jeżeli a to b w przeciwnym wypadku c&#8221; rozbijamy na &#8220;Jeżeli a to b. Jeżeli nie a to c&#8221;. Zysku żadnego, kod niby lepszy, a w praktyce gorszy, bo <samp>else</samp> choć złe to jednak coś oznacza. Kilka <samp>if</samp>ów z rzędu tylko gmatwa kod.<br />
W tym konkretnym przypadku rozwiązaniem jest wykorzystanie szmocy&#8230; znaczy się wykorzystamy <a href="http://pl.wikipedia.org/wiki/Polimorfizm_(informatyka)" target="_blank" title="From Wikipedia the definition of: Polimorfizm_(informatyka)" class="wikiterm" >polimorfizm</a><sup class="wikiicon" ><em>W</em></sup>. Zachowanie będzie zależało od konkretnej implementacji:</p>
<p class="listing">Listing 5. Uzależnienie wartości zwracanej od różnych warunków za pomocą polimorfizmu</p>
<pre class="java" name="code">package pl.koziolekweb.eowp2;

public enum State {

	VALID {
		@Override
		public State changeState(State target) {
			if (target != NOT_INIT) {
				return target;
			}
			return this;
		}
	},
	INVALID {
		@Override
		public State changeState(State target) {
			return this;
		}
	},
	NOT_INIT {
		@Override
		public State changeState(State target) {
			return target;
		}
	};

	public abstract State changeState(State target);
}</pre>
<p>Z zestawu kilku <samp>if</samp>ów wybraliśmy jeden istotny, a resztę usunęliśmy. Nie ma <samp>if</samp>ów, nie ma <samp>else</samp>ów udających <samp>if</samp>y. Ładnie.</p>
<h4>Motywacja</h4>
<p>Po co tak naprawdę stosujemy tą regułę. Powód jest prosty i nazywa się <a href="http://pl.wikipedia.org/wiki/Złożoność_cyklomatyczna" target="_blank" title="From Wikipedia the definition of: Złożoność_cyklomatyczna" class="wikiterm" >złożoność cyklomatyczna</a><sup class="wikiicon" ><em>W</em></sup> (mądre słowo). Jednostką złożoności jest ilość WTF/s. Inaczej mówiąc jest to liczba określająca zagmatwanie kodu. Ściślejsza definicja mówi coś o ilości brzegów, wierzchołków i punktów wejścia i wyjścia w grafie przepływu programu. Takie matematyczne pieprzenie, które nas malo obchodzi na chwilę obecną <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Generalnie sama złożoność nie będzie wiele mówić jeżeli programujemy obiektowo. Trochę lepszą metryką jest średnia złożoność na metodę w danej klasie. Jeżeli jednak korzystamy z tej metryki to trzeba pamiętać, że limity podane na wiki są znacznie niższe.</p>
<h5>Jak mierzyć CC?</h5>
<p>Potrafi to i <a href="http://cobertura.sourceforge.net/" title="Cobertura">Cobertura </a>i <a href="http://clarkware.com/software/JDepend.html" title="JDepend">JDepend</a> i <a href="http://javancss.codehaus.org/" title="JavaNCSS">JavaNCSS</a>.</p>
<h5>Po co mierzyć CC?</h5>
<p>Ponieważ nie tylko <samp>else</samp> wpływa na zagmatwanie kodu. Jest to dobra metryka obrazująca ogólną złożoność kodu i pozwala w połączeniu z prezentowaną tu regułą na uproszczenie kodu.</p>
<h4>Jak stosować ta regułę</h4>
<p>Istnieje kilka sposobów na to jak wprowadzić dziś omawianą regułę do kodu. Oto kilka z nich. Nie wszystkie, bo dużo w tym wypadku zależy od konkretnego przypadku, ale to te najpopularniejsze.</p>
<h5>Odwróć warunek</h5>
<p>Czasami można pozbyć się <samp>else</samp> odwracając warunek. Zamiast używać <samp>==</samp> można użyć <samp>!=</samp>. Trochę bardziej skomplikowaną sztuczką może być tu wykorzystanie <a href="http://pl.wikipedia.org/wiki/prawa_De_Morgana" target="_blank" title="From Wikipedia the definition of: prawa De Morgana" class="wikiterm" >prawa De Morgana</a><sup class="wikiicon" ><em>W</em></sup> choć to czasami wprowadza znacznie więcej zamieszania. Warto tu mieć już gotowy komplet testów, które pokrywają wszystkie kombinacje warunków.</p>
<h5>Polimorfizm</h5>
<p>Czyli uzależnienie przebiegu programu nie tyle co od warunku co od dostarczonej wersji metody. Bardzo fajna sprawa, szczególnie jak popatrzymy na scalowe Case Classes. Na dłuższą metę jest to bardzo trudne ponieważ zacznie się biegunka klas spowodowana koniecznością dostarczanie nie tylko klas realizujących różne wersje algorytmu w zależności od warunku, ale też odpowiednich fabryk. Tu ratunkiem mogą okazać się wzorce dekorator i builder oraz rozsądna delegacja zadań, które będą choć trochę upraszczać tworzenie klas.</p>
<h5>Delegacja do bibliotek zewnętrznych</h5>
<p>Każdy zna konstrukcję jeżeli <samp>null</samp> to NPE. W Bean Validation API 1.1 będzie walidacja argumentów metod. To pozwoli nam na adnotowanie argumentu i nie martwienie się o walidacje lokalne. Podobnie ma się sprawa z metodami takimi jak <samp>equals</samp>, <samp>hashCode</samp> i <samp>toString</samp>, które są niewyczerpanym źródłem <samp>else</samp>ów.</p>
<h5>Programowanie aspektowe</h5>
<p>Tak jak wyżej, ale w trochę inny sposób. Niektóre instrukcje można przenieść do aspektu i nie martwić się ich obsługa w kodzie. </p>
<h5>Kontrowersyjny Null Object</h5>
<p>Na koniec pozostawiłem sobie najbardziej kontrowersyjną metodę wprowadzenia tej reguły. Generalnie znaczna część instrukcji warunkowych sprawdza czy dany obiekt nie jest <samp>null</samp>. W zamian można wprowadzić wzorzec Null Object. W skrócie jest to użycie specjalnej implementacji klasy, która &#8220;robi nic&#8221; zamiast zwrócenia <samp>null</samp>. Upraszcza to znacznie implementację ponieważ nie trzeba sprawdzać warunków. Z drugiej strony należy pamiętać, że jest to wzorzec wirusowy. Oznacza to, że jeżeli dana metoda będzie zwracać jakiś obiekt, to w implementacji Null Object powinniśmy zwracać Null Object danego obiektu. Zatem obok drzewka realnych obiektów otrzymujemy ich nullowe odpowiedniki. Coś za coś.</p>
<h4>Podsumowanie</h4>
<p>Kolejna stosunkowo prosta reguła. Pozwala ona na tworzenie stabilnego, prostego kodu, który jest bardzo łatwy w testowaniu. Ograniczenie ilości warunków w instrukcjach warunkowych pozwala na uzyskanie lepszego pokrycia testami dla tych instrukcji.<br />
Wadą jest konieczność kombinowania ponieważ czasami ciężko wymyślić jakieś dobre rozwiązanie problemu i trzeba zmieniać wszystkie założenia co do klasy.<br />
Warto jednak wprowadzać tą regułę tak często jak tylko się da ponieważ dzięki temu nasz kod staje się prosty, a ilość WTF/s dąży do 1.</p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+2+%26%238211%3B+Nie+u%C5%BCywaj+s%C5%82owa+kluczowego+else" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+2+%26%238211%3B+Nie+u%C5%BCywaj+s%C5%82owa+kluczowego+else" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+2+%26%238211%3B+Nie+u%C5%BCywaj+s%C5%82owa+kluczowego+else" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+2+%26%238211%3B+Nie+u%C5%BCywaj+s%C5%82owa+kluczowego+else" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+2+%26%238211%3B+Nie+u%C5%BCywaj+s%C5%82owa+kluczowego+else" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+2+%26%238211%3B+Nie+u%C5%BCywaj+s%C5%82owa+kluczowego+else" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 2 &#8211; Nie używaj słowa kluczowego else' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/10/26/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-2-nie-uzywaj-slowa-kluczowego-else/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę</title>
		<link>http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/</link>
		<comments>http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 20:46:48 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Ekstremalna obiektowość w praktyce]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Wzorce projektowe]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=2269</guid>
		<description><![CDATA[Część 0 Witam w pierwszej części cyklu Ekstremalna Obiektowość w Praktyce. Z głośników płynie sobie Another Brick on the Wall part II, a my zajmiemy się pierwszą z zasad Jeff&#8217;a Bay&#8217;a. Brzmi ona Tylko jeden poziom zagłębienia na metodę Jest to jedna z prostszych zasad, której wprowadzenie wymaga tylko umiejętnego wykorzystania refaktoryzacji typu Extract Method. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://koziolekweb.pl/2011/10/19/ekstremalna-obiektowosc-w-praktyce-czesc-0/">Część 0</a></p>
<p>Witam w pierwszej części cyklu Ekstremalna Obiektowość w Praktyce. Z głośników płynie sobie Another Brick on the Wall part II, a my zajmiemy się pierwszą z zasad Jeff&#8217;a Bay&#8217;a. Brzmi ona</p>
<h4>Tylko jeden poziom zagłębienia na metodę</h4>
<p>Jest to jedna z prostszych zasad, której wprowadzenie wymaga tylko umiejętnego wykorzystania refaktoryzacji typu Extract Method. Pytania: </p>
<ul>
<li>Gdzie w Twoim ulubionym IDE jest dostępna ta refaktoryzacja?</li>
<li>Jaki jest jej skrót klawiaturowy?</li>
</ul>
<p>Mam nadzieję, że odpowiedziałeś/aś poprawnie na oba pytania i to bez chwili zastanowienia. Dlaczego to takie ważne? Pisałem o tym w części zerowej, ale przypomnę. Zasady przedstawione w tym cyklu wymagają dobrego warsztatu pracy tak by nie tracić czasu na szukanie narzędzi, a korzystać z nich.</p>
<h5>Na czym to polega?</h5>
<p>Załóżmy, na początek, że potrzebujesz wypełnić trójwymiarową tablicę za pomocą kolejnych liczb naturalnych, a następnie wypisać ją na standardowe wyjście. Wiem, że przykład jest głupi i mało rzeczywisty, ale bardziej namacalne za chwilę. Program realizujący taką funkcjonalność będzie wyglądał mniej więcej tak:</p>
<p class="listing">Listing 1. Wypełnienie i wypisanie tablicy 3D</p>
<pre class="java" name="code">package pl.koziolekweb.eowp1;

public class Array3DFiller {

	public static void main(String[] args) {
		int[][][] array3d = new int[3][3][3];
		int current = 0;
		for (int i = 0; i < array3d.length; i++) {
			for (int j = 0; j < array3d[i].length; j++) {
				for (int k = 0; k < array3d[i][j].length; k++, current++) {
					array3d[i][j][k] = current;
				}
			}
		}
		//----------------------------------------
		//poziom 0
		//--poziom 1 - to jest dopuszczalne
		//------poziom 2 - tego robić nie wolno
		//----------poziom 3 - tego tym bardziej robić nie wolno
		//----------------------------------------
		for (int i = 0; i < array3d.length; i++) {
			for (int j = 0; j < array3d[i].length; j++) {
				for (int k = 0; k < array3d[i][j].length; k++, current++) {
					System.out.print(String.format("%2s ",array3d[i][j][k]));
				}
				System.out.println();
			}
			System.out.println();
		}

	}

}
</pre>
<p>Realizacja w <samp>main</samp> tylko dla wygody uruchamiania. Z tego powodu dalej będę używał metod statycznych.</p>
<p>Jak widać jest to niezbyt ciekawy, zagmatwany kod. Tu o tyle prosty, że w poszczególnych pętlach niewiele się dzieje. Pierwsza z reguł Bay'a mówi, że należy tak pisać kod by w metodzie był tylko jeden poziom wcięcia. Co to oznacza? Oznacza to, że masz prawo zrobić 4 spacje/1 tab w celu wcięcia kodu metody, a następnie kolejne 4 spacje/1 tab w celu wcięcia dla np. instrukcji warunkowej czy pętli. W tej wciętej instrukcji nie możesz używać dalszych wcięć. Na listingu 1 komentarze oznaczają poszczególne poziomy wcięć.<br />
Spróbujmy teraz wyekstrahować poszczególne metody tak by osiągnąć kod zgodny z założeniami. W tym celu będziemy używać refaktoryzacji Extract Method.</p>
<p class="listing">Listing 2. Kod po pierwszej refaktoryzaci</p>
<pre class="java" name="code">package pl.koziolekweb.eowp1;

public class Array3DFiller {

	public static void main(String[] args) {
		int[][][] array3d = new int[3][3][3];
		int current = 0;
		for (int i = 0; i < array3d.length; i++) {
			current = fill2dArray(array3d, current, i);
		}

		for (int i = 0; i < array3d.length; i++) {
			current = print2dArray(array3d, current, i);
			System.out.println();
		}

	}

	private static int fill2dArray(int[][][] array3d, int current, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			current = fillRow(array3d, current, i, j);
		}
		return current;
	}

	private static int fillRow(int[][][] array3d, int current, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++, current++) {
			array3d[i][j][k] = current;
		}
		return current;
	}

	private static int print2dArray(int[][][] array3d, int current, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			current = printRow(array3d, current, i, j);
			System.out.println();
		}
		return current;
	}

	private static int printRow(int[][][] array3d, int current, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++, current++) {
			System.out.print(String.format("%2s ", array3d[i][j][k]));
		}
		return current;
	}

}
</pre>
<p>Jak widać kod wygląda już zdecydowanie lepiej. Nie jest może idealny, ale jest znacznie bardziej czytelny. Możemy oczywiście pogłębić refaktoryzację wyciągając jeszcze pętle z <samp>main</samp> do osobnych metod:</p>
<p class="listing">Listing 3. Kod po drugiej refaktoryzaci</p>
<pre class="java" name="code">package pl.koziolekweb.eowp1;

public class Array3DFiller {

	public static void main(String[] args) {
		int[][][] array3d = new int[3][3][3];
		int current = 0;
		current = fillArray(array3d, current);

		current = printArray(array3d, current);

	}

	private static int fill2dArray(int[][][] array3d, int current, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			current = fillRow(array3d, current, i, j);
		}
		return current;
	}

	private static int fillArray(int[][][] array3d, int current) {
		for (int i = 0; i < array3d.length; i++) {
			current = fill2dArray(array3d, current, i);
		}
		return current;
	}

	private static int fillRow(int[][][] array3d, int current, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++, current++) {
			array3d[i][j][k] = current;
		}
		return current;
	}

	private static int print2dArray(int[][][] array3d, int current, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			current = printRow(array3d, current, i, j);
			System.out.println();
		}
		return current;
	}

	private static int printArray(int[][][] array3d, int current) {
		for (int i = 0; i < array3d.length; i++) {
			current = print2dArray(array3d, current, i);
			System.out.println();
		}
		return current;
	}

	private static int printRow(int[][][] array3d, int current, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++, current++) {
			System.out.print(String.format("%2s ", array3d[i][j][k]));
		}
		return current;
	}

}
</pre>
<p>Co dzięki temu uzyskaliśmy? Już po pierwszej refaktoryzacji można zauważyć, nadmiarową część kodu. Jaką? Przyjrzyjmy się wypisywaniu tablicy... po co nam zmienna <samp>current</samp>? Oczywiście kod tworzony za pomocą kopiuj wklej jest zawsze podatny na tego typu potknięcia. Nie zmienia to jednak faktu, że w pierwotnej wersji kodu umyka ten szczegół. Co ważne, zmienna ta nie jest też potrzebna w metodzie <samp>main</samp> można zatem przenieść ją głębiej w kod. Dzięki temu osiągamy też ukrycie implementacji przed klientem. Klient nie musi wnikać jak wypełniana jest tablica. W szczególności nie obchodzą go zmienne wykorzystywane przez metodę wypełniającą.<br />
W wyniku wszystkich tych kroków otrzymujemy poniższy kod.</p>
<p class="listing">Listing 4. Kod zakończeniu pracy</p>
<pre class="java" name="code">package pl.koziolekweb.eowp1;

public class Array3DFiller {

	public static void main(String[] args) {
		int[][][] array3d = new int[3][3][3];
		fillArray(array3d);

		printArray(array3d);

	}

	private static int fill2dArray(int[][][] array3d, int current, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			current = fillRow(array3d, current, i, j);
		}
		return current;
	}

	private static int fillArray(int[][][] array3d) {
		int current = 0;
		for (int i = 0; i < array3d.length; i++) {
			current = fill2dArray(array3d, current, i);
		}
		return current;
	}

	private static int fillRow(int[][][] array3d, int current, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++, current++) {
			array3d[i][j][k] = current;
		}
		return current;
	}

	private static void print2dArray(int[][][] array3d, int i) {
		for (int j = 0; j < array3d[i].length; j++) {
			printRow(array3d, i, j);
			System.out.println();
		}
	}

	private static void printArray(int[][][] array3d) {
		for (int i = 0; i < array3d.length; i++) {
			print2dArray(array3d, i);
			System.out.println();
		}
	}

	private static void printRow(int[][][] array3d, int i, int j) {
		for (int k = 0; k < array3d[i][j].length; k++) {
			System.out.print(String.format("%2s ", array3d[i][j][k]));
		}
	}

}
</pre>
<p>Nie jest to oczywiście kod idealny. Metody mają za dużo parametrów, a klasa ma kilka odpowiedzialności (wypełnienie i wypisanie). Jak go ulepszyć będę jeszcze pisał w następnych częściach. Na chwilę obecną osiągnęliśmy wyznaczony cel. Metody nie mają więcej niż jeden poziom wcięcia. </p>
<h5>A może coś bardziej życiowego?</h5>
<p>Przykład był mało życiowy, ale prosty. Czas na coś bardziej życiowego.<br />
Jak wspomniałem wcześniej realizowałem ostatnio niewielki projekt, który postanowiłem napisać zgodnie z tymi zasadami. Jedną z funkcjonalności było przepisanie odpowiedzi serwera z tekstu (XML) na kolekcję obiektów. Sprawa prosta, a nie chciało mi się szukać biblioteki mapującej. Zresztą powoli robi mi się w projekcie jar-hell więc dołączanie biblioteki tylko dla jednej metody traci sens.<br />
W uproszczeniu cały program wyglądał by mniej więcej tak</p>
<p class="listing">Listing 5. Kod mapowania XML - Obiekt</p>
<pre class="java" name="code">package pl.koziolekweb.eowp1;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class TransactionUnmarshaller {

	public static void main(String[] args) throws Exception {
		String transaction1 = "
<transaction>" + "<id>1</id>"
				+ "<state>OK</state>" + "<senderid>100</senderid>"
				+ "<reciverid>101</reciverid>" + "</transaction>";
		String transaction2 = "
<transaction>" + "<id>2</id>"
				+ "<state>OK</state>" + "<senderid>101</senderid>"
				+ "<reciverid>100</reciverid>" + "</transaction>";
		String response = "
<transactions>" + transaction1 + transaction2
				+ "</transactions>";

		Unmarshaller unmarshaller = new Unmarshaller();
		Collection<Transaction> unmarshallFromStringXml = unmarshaller
				.unmarshallFromStringXml(response);
		System.out.println(unmarshallFromStringXml);
	}

}

class Transaction {
	int id;
	String state;
	long senderId;
	long reciverId;

	@Override
	public String toString() {
		return "Transaction [id=" + id + ", state=" + state + ", senderId="
				+ senderId + ", reciverId=" + reciverId + "]";
	}
}

class Unmarshaller {

	Collection<Transaction> unmarshallFromStringXml(String response)
			throws Exception {
		DocumentBuilder newDocumentBuilder = DocumentBuilderFactory
				.newInstance().newDocumentBuilder();
		Document responseAsXml = newDocumentBuilder
				.parse(new ByteArrayInputStream(response.getBytes()));
		NodeList transactionNodes = responseAsXml
				.getElementsByTagName("transaction");
		int length = transactionNodes.getLength();
		List<Transaction> transactions = new ArrayList<Transaction>(length);
		for (int i = 0; i < length; i++) {
			Node transactinoNode = transactionNodes.item(i);
			Transaction transaction = new Transaction();
			NodeList transactionDataNodes = transactinoNode.getChildNodes();
			for (int j = 0; j < transactionDataNodes.getLength(); j++) {
				Node item = transactionDataNodes.item(j);
				if (item.getNodeName().equalsIgnoreCase("id")) {
					transaction.id = Integer.parseInt(item.getTextContent());
				}
				if (item.getNodeName().equalsIgnoreCase("state")) {
					transaction.state = item.getTextContent();
				}
				if (item.getNodeName().equalsIgnoreCase("senderId")) {
					transaction.senderId = Long
							.parseLong(item.getTextContent());
				}
				if (item.getNodeName().equalsIgnoreCase("reciverId")) {
					transaction.reciverId = Long.parseLong(item
							.getTextContent());
				}
			}
			transactions.add(transaction);
		}
		return transactions;
	}
}
</pre>
<p>Klasa <samp>Unmarshaller</samp> to istne pobojowisko. Oczywiście to działa poprawnie i jest nawet szybkie. Tyle tylko, że w czasie testów wyszły nam pewne bugi i poszukiwanie źródła było dość uciążliwe. W pierwszym odruchu refaktoryzacja w duchu zasady Jeff'a Bay'a przebiegła bardzo sprawnie i w jej wyniku otrzymałem coś takiego:</p>
<p class="listing">Listing 6. Kod po szybkiej refaktoryzacji</p>
<pre class="java" name="code">class Unmarshaller {

	Collection<Transaction> unmarshallFromStringXml(String response)
			throws Exception {
		DocumentBuilder newDocumentBuilder = DocumentBuilderFactory
				.newInstance().newDocumentBuilder();
		Document responseAsXml = newDocumentBuilder
				.parse(new ByteArrayInputStream(response.getBytes()));
		NodeList transactionNodes = responseAsXml
				.getElementsByTagName("transaction");
		int length = transactionNodes.getLength();
		List<Transaction> transactions = new ArrayList<Transaction>(length);
		for (int i = 0; i < length; i++) {
			Node transactinoNode = transactionNodes.item(i);
			Transaction transaction = visitTransaction(transactinoNode);
			transactions.add(transaction);
		}
		return transactions;
	}

	private void visitId(Transaction transaction, Node item) {
		if (item.getNodeName().equalsIgnoreCase("id")) {
			transaction.id = Integer.parseInt(item.getTextContent());
		}
	}

	private void visitReciverId(Transaction transaction, Node item) {
		if (item.getNodeName().equalsIgnoreCase("reciverId")) {
			transaction.reciverId = Long.parseLong(item
					.getTextContent());
		}
	}

	private void visitSenderId(Transaction transaction, Node item) {
		if (item.getNodeName().equalsIgnoreCase("senderId")) {
			transaction.senderId = Long
					.parseLong(item.getTextContent());
		}
	}

	private void visitState(Transaction transaction, Node item) {
		if (item.getNodeName().equalsIgnoreCase("state")) {
			transaction.state = item.getTextContent();
		}
	}

	private Transaction visitTransaction(Node transactinoNode) {
		Transaction transaction = new Transaction();
		NodeList transactionDataNodes = transactinoNode.getChildNodes();
		for (int j = 0; j < transactionDataNodes.getLength(); j++) {
			Node item = transactionDataNodes.item(j);
			visitId(transaction, item);
			visitState(transaction, item);
			visitSenderId(transaction, item);
			visitReciverId(transaction, item);
		}
		return transaction;
	}
}
</pre>
<p>Kod stał się czytelniejszy, a i przetestować było go łatwiej. Jednak dzięki temu uzyskujemy dodatkowy bonus. Otóż widać, że część kodu powtarza się. Można zatem pozbyć się tego powtórzenia do osobnej metody.</p>
<p class="listing">Listing 7. Kod po dokładniejszej refaktoryzacji</p>
<pre class="java" name="code">class Unmarshaller {

	Collection<Transaction> unmarshallFromStringXml(String response)
			throws Exception {
		DocumentBuilder newDocumentBuilder = DocumentBuilderFactory
				.newInstance().newDocumentBuilder();
		Document responseAsXml = newDocumentBuilder
				.parse(new ByteArrayInputStream(response.getBytes()));
		NodeList transactionNodes = responseAsXml
				.getElementsByTagName("transaction");
		int length = transactionNodes.getLength();
		List<Transaction> transactions = new ArrayList<Transaction>(length);
		for (int i = 0; i < length; i++) {
			Node transactinoNode = transactionNodes.item(i);
			Transaction transaction = visitTransaction(transactinoNode);
			transactions.add(transaction);
		}
		return transactions;
	}

	private boolean isNode(Node item, String nodeName) {
		return item.getNodeName().equalsIgnoreCase(nodeName);
	}

	private int toInt(Node item) {
		return Integer.parseInt(item.getTextContent());
	}

	private long toLong(Node item) {
		return Long.parseLong(item.getTextContent());
	}

	private void visitId(Transaction transaction, Node item) {
		if (isNode(item, "id")) {
			transaction.id = toInt(item);
		}
	}

	private void visitReciverId(Transaction transaction, Node item) {
		if (isNode(item, "reciverId")) {
			transaction.reciverId = toLong(item);
		}
	}

	private void visitSenderId(Transaction transaction, Node item) {
		if (isNode(item, "senderId")) {
			transaction.senderId = toLong(item);
		}
	}

	private void visitState(Transaction transaction, Node item) {
		if (isNode(item, "state")) {
			transaction.state = item.getTextContent();
		}
	}

	private Transaction visitTransaction(Node transactinoNode) {
		Transaction transaction = new Transaction();
		NodeList transactionDataNodes = transactinoNode.getChildNodes();
		for (int j = 0; j < transactionDataNodes.getLength(); j++) {
			Node item = transactionDataNodes.item(j);
			visitId(transaction, item);
			visitState(transaction, item);
			visitSenderId(transaction, item);
			visitReciverId(transaction, item);
		}
		return transaction;
	}
}</pre>
<p>Jak widać kod stał się jeszcze prostszy. Oczywiście to nie był koniec prac nad nim i tak jak w poprzednim przykładzie jeszcze wrócę do niego przy omawianiu innych zasad. Na teraz jednak wystarczy tej zabawy. Mamy dobry punkt wyjścia do kolejnych prac.</p>
<h4>Czas na małe podsumowanie</h4>
<p>Zasada jednego poziomu wcięcia na metodę jest bardzo prosta do zastosowania. Nie wymaga dużego nakładu pracy, a efekty są zadowalające i uzyskiwane bardzo szybko. </p>
<h5>Zalety</h5>
<ul>
<li><b>Prostota</b> - zasada prosta do zachowania. Nie wymaga dużo czasu i nakładu pracy.</li>
<li><b>Rozsądna granulacja kodu</b> - po zastosowaniu metody pracują na swoim "poziomie" bez wnikania w niższe i wyższe poziomy. Tak jak w pierwszym przykładzie metody pracujące na wierszu tablicy pracują na wierszu, a pracujące na całej tablicy pracują na całej tablicy. W drugim przykładzie metody pracują na swoim poziomie drzewa XML.</li>
<li><b>Łatwe testowanie</b> - jednostki kodu podlegające testowaniu są małe, a dzięki temu łatwe do testowania.</li>
<li><b>Łatwe wyszukiwanie powtórzeń</b> - w ramach jednej klasy można bardzo łatwo odnaleźć powtarzający się kod. W przypadku kilku klas też o ile użyjemy odpowiednich narzędzi szukających powtórzeń. Dzięki temu możemy usunąć powtórzenia i tym samym uzyskać jeszcze mniejszy i lepszy kod.</li>
<li><b>Łatwe wyszukiwanie drobnych błędów</b> - w czasie refaktoryzacji możemy odnaleźć kod zbędny, wykonujący niepotrzebne operacje czy w końcu tworzony metodą kopiuj wklej.</li>
<li><b>Pomaga przestrzegać SRP</b> - jeżeli powstaje dużo drobnych metod to możemy z łatwością stwierdzić, że klasa ma wiele odpowiedzialności i przeciwdziałać już na samym początku.</li>
</ul>
<h5>Wady</h5>
<ul>
<li><b>Duża ilość metod</b> - w krótkim czasie otrzymujemy dużo małych metod. Trzeba umieć korzystać z mechanizmów IDE by swobodnie pomiędzy nimi wędrować. <i>Rozwiązanie</i> - część metod można przenieść do nowych klas pomocniczych, gdzie będą testowane i utrzymywane niezależnie od obecnego kontekstu użycia w kodzie.</li>
<li><b>Metody o podobnych nazwach</b> - w czasie ekstrakcji metody otrzymują podobne nazwy. <i>Rozwiązanie</i> - jeżeli nazwy dobrze opisują metodę to dobrze. Jeżeli trudno dobrać taka nazwę to może oznaczać, że klasa ma za wiele odpowiedzialności.</li>
</ul>
<h5>Wrażenia i zalecenia</h5>
<p>Użycie tej zasady jest proste i dzięki temu można ją stosować na najniższym poziomie. W praktyce tak samo jak puszczenie testów co chwilę tak i tu warto na bieżąco dbać o zachowanie tej zasady. Pozwoli to na szybką lokalizację błędów oraz naruszeń <a href="http://koziolekweb.pl/2009/02/26/solidne-programowanie-czesc-1-czyli-monogamia/">SRP</a>. Wymaga to jednak dobrego opanowania IDE ponieważ dość szybko zamiast Extract Method zaczniemy używać Extract Class, a to już nie jest takie proste. No i najważniejsze. Drobne małe metody są wygodne jeżeli chcemy lokalizować błędy.</p>
<!-- Social Bookmarking Reloaded BEGIN --><div class="social_bookmark"><em>Dodaj do </em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+1+%26%238211%3B+tylko+jeden+poziom+zag%C5%82%C4%99bienia+na+metod%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Del.icio.us" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+1+%26%238211%3B+tylko+jeden+poziom+zag%C5%82%C4%99bienia+na+metod%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do digg" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Technorati" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+1+%26%238211%3B+tylko+jeden+poziom+zag%C5%82%C4%99bienia+na+metod%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Stumble Upon" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Stumble Upon" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+1+%26%238211%3B+tylko+jeden+poziom+zag%C5%82%C4%99bienia+na+metod%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Google Bookmarks" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do Google Bookmarks" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/share.php?u=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/&amp;t=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+1+%26%238211%3B+tylko+jeden+poziom+zag%C5%82%C4%99bienia+na+metod%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do FaceBook" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do FaceBook" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,border=0,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.wykop.pl/dodaj?url=http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/&amp;title=Ekstremalna+obiektowo%C5%9B%C4%87+w+praktyce+%E2%80%93+cz%C4%99%C5%9B%C4%87+1+%26%238211%3B+tylko+jeden+poziom+zag%C5%82%C4%99bienia+na+metod%C4%99" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do wykop.pl" alt="dodaj 'Ekstremalna obiektowość w praktyce – część 1 &#8211; tylko jeden poziom zagłębienia na metodę' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2011/10/22/ekstremalna-obiektowosc-w-praktyce-%e2%80%93-czesc-1-tylko-jeden-poziom-zaglebienia-na-metode/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

