<?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; Singleton</title>
	<atom:link href="http://koziolekweb.pl/tag/singleton/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, 22 May 2012 11:25:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</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>AspectJ trochę szczegółów &#8211; rodzaje porad</title>
		<link>http://koziolekweb.pl/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/</link>
		<comments>http://koziolekweb.pl/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 14:25:06 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[Dekorator]]></category>
		<category><![CDATA[Singleton]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=1526</guid>
		<description><![CDATA[      
      Wiemy już jak napisać aspekt i poznaliśmy dwa &#8220;rodzaje składni&#8221; aspektów. Czas na dokładniejsze przyjrzenie się temu jak wygląda składnia i jakie możliwości nam daje. Na chwilę obecną wiemy, że aspekt to jednostka kodu, która jest wstawiana za pomocą odpowiedniego narzędzia &#8211; kompilatora aspektowego lub agenta JVM do kodu programu. Pytanie jednak jakie mamy możliwości [...]]]></description>
			<content:encoded><![CDATA[      
      <p>Wiemy już jak napisać aspekt i poznaliśmy dwa &#8220;rodzaje składni&#8221; aspektów. Czas na dokładniejsze przyjrzenie się temu jak wygląda składnia i jakie możliwości nam daje. Na chwilę obecną wiemy, że aspekt to jednostka kodu, która jest wstawiana za pomocą odpowiedniego narzędzia &#8211; kompilatora aspektowego lub agenta JVM do kodu programu. Pytanie jednak jakie mamy możliwości wstawiania kodu i jakie rodzaje porad możemy tworzyć.</p>
<h4>Rodzaje porad</h4>
<p>Porada jest to pojedyncza operacja wstawiana w odpowiedni punkt przecięcia. Generalnie istnieją trzy rodzaje porad (i ich zrozumienie jest naprawdę proste w porównaniu z definicjami punktów przecięcia). Pierwszy to znana nam już porada <samp>before</samp>. Wstawiana jest w kod przed wykonaniem danego działania. Po jej wykonaniu wykonywany jest kod punktu przecięcia.<br />
Drugim rodzajem porad są porady <samp>after</samp>. Tu sprawy trochę się komplikują. Po pierwsze mogą wystąpić trzy podrodzaje porady. Pierwsze to zwykłe porady. Wykonane będą zawsze po kodzie punktu przecięcia. Jeżeli wysypie się on z jakimkolwiek błędem nasza porada zostanie wykonana i dopiero po niej zostanie wyrzucony błąd. Drugie to porady <samp>afterthrowing</samp>, które wykonają się wtedy i tylko wtedy, gdy kod punktu przecięcia wywali wyjątek. Kod porady wykona się przed zwróceniem wyjątku lub po, bo całość nie jest jakoś specjalnie synchronizowana. Trzeci rodzaj to porady <samp>afterreturning</samp>, które to wykonają się tylko wtedy gdy kod w punkcie przecięcia zakończy się prawidłowo. Poniżej przykładowy aspekt, który ilustruje działanie wszystkich tych dróg:</p>
<p class="listing">Listing 1. Porada typu <samp>after</samp></p>
<pre class="java" name="code">
package pl.koziolekweb.blog.aspectj;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class ErrorHandlerAspect {

	@Pointcut("execution(* NKWD.*(..))")
	public void handleError(){}

	@After("handleError()")
	public void handleErrorAdvice(){
		System.out.println("Metoda wyrzuca błąd");
	}

	@AfterThrowing(value = "handleError()", throwing = "runtimeException")
	public void handleErrorThrowsAdvice(RuntimeException runtimeException) {
		System.out.println("Metoda wyrzuciła błąd: "
				+ runtimeException.getLocalizedMessage());
	}

	@AfterReturning("handleError()")
	public void handleErrorNotThrowAdvice(){
		System.out.println("Metoda nie wyrzuciła błędu");
	}
}
</pre>
<p>Pobaw się z dodawaniem deklaracji wyjątku do klasy <samp>NKWD</samp> i zobacz co się stanie.<br />
Trzeci rodzaj porad to porady <samp>around</samp>. Są one szczególnie przydatne wszędzie tam, gdzie zazwyczaj do wykonywania jakiś czynności wykorzystujemy wzorzec metody szablonowej. Jednocześnie szablon nie realizuje samego algorytmu, a jedynie pozwala na wykonanie czynności takich jak logowanie startu i końca akcji, blokowanie obiektów (ukochany <samp>ReadWriteLock</samp>), rozpoczynanie i kończenie transakcji, proste profilowanie. Kolejnym wzorcem, który można zastąpić tym rodzajem porady jest dekorator. Bardzo dobrym pomysłem jest dekorowanie obiektów w sposób przezroczysty dla klienta. Niestety klient musi w takim wypadku korzystać z interfejsu do komunikacji z obiektem (co jest bardzo fajne) i uzyskiwać obiekty z jakiejś fabryki (co jest upierdliwe zarówno dla klienta jak i programisty). Oczywiście jest Spring, EJB3.x czy Pico, ale jakoś nie widzę sensu ich użycia tylko dla jednego małego dekoratora (pamiętaj, używanie frameworków powoduje gwałtowne rozrastanie się kodu wynikowego). Zresztą nie zawsze da się użyć frameworku.<br />
Problemem z tym rodzajem porady jest konieczność wstawienia jakiegoś elementu, który pozwalał by na określenie jaki kod ma być wykonany przed, a jaki po wykonaniu kodu punktu przecięcia. AspectJ dostarcza odpowiedniego pseudo słowa kluczowego <samp>proceed()</samp>. Jest to pseudo słowo kluczowe ponieważ w praktyce jest to metoda <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Napiszmy profiler, który będzie sprawdzał ile czasu zajmuje użytkownikowi wpisanie hasła. Przy okazji mały refaktoring kodu <samp>NKWD</samp>:</p>
<p class="listing">Listing 2. Nowa wersja <samp>NKWD</samp></p>
<pre class="java" name="code">
package pl.koziolekweb.blog.aspectj;

import java.util.Scanner;

public class NKWD {

	private boolean isAuth = false;

	public void auth(){
		if (isAuth) {
			return;
		} else {
			String password = readPassword();
			isAuth = validatePassword(password);
			if (!isAuth) {
				throw new RuntimeException("Wypad na Łubiankę");
			}
		}
	}

	private String readPassword() {
		System.out.print("podaj hasło: ");
		Scanner scanner = new Scanner(System.in);
		String password = scanner.next();
		return password;
	}

	private boolean validatePassword(String password) {
		return "dupa".equals(password);
	}
}
</pre>
<p>Czas na nasz nowy aspekt <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p class="listing">Listing 3. Aspekt profilujący.</p>
<pre class="java" name="code">
package pl.koziolekweb.blog.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class InputProfilingAspect {

	@Pointcut("call(* java.util.Scanner.next(..))")
	public void profile() {
	}

	@Around("profile()")
	public Object profileAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
		long start = System.nanoTime();
		Object processResult = joinPoint.proceed();
		long stop = System.nanoTime();
		System.out.println("Czas wpisania hasła: "
				+ ((stop - start) * 0.000000001) + " sekundy");
		return processResult;
	}
}
</pre>
<p>Kolejnym problemem jest konieczność zachowania sygnatury dekorowanej metody. Zatem w przypadku wykorzystania składni @AspectJ jak i .aj należy zadbać by porada zwracała odpowiedni obiekt. Na całe szczęście <samp>proceed</samp> zwraca <samp>Object</samp>, a odpowiednie rzutowanie zostaje wykonane poza naszą ingerencją przez weavera. Co jednak w przypadku gdy metoda przyjmuje parametry? Sprawdźmy ile czasu zajmie wypisanie komunikatu powitalnego dla konkretnego użyszkodnika. </p>
<p class="listing">Listing 3. Aspekt profilujący z parametrami.</p>
<pre class="java" name="code">
package pl.koziolekweb.blog.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MessageProfilingAspect {

	@Pointcut("call(* Service.welcome(String)) &#038;&#038; args(string)")
	public void profile(String string){}

	@Around("profile(string)")
	public void proflieAdvice(ProceedingJoinPoint joinPoint, String string) throws Throwable{
		long start = System.nanoTime();
		joinPoint.proceed(new Object[]{string});
		long stop = System.nanoTime();
		System.out.println("Czas wpisania wiadomości: "
				+ ((stop - start) * 0.000000001) + " sekundy");
	}

}
</pre>
<p>Jak widać coś jest nie tak. Czasy się nie zgadzają. Czas wypisania komunikatu jest dłuższy niż czas wpisywania hasła. Wniosek, czas jest liczony globalnie. Cóż&#8230; takie życie. Wynika to z modelu jaki przyjęto dla tworzenia aspektów. Opisze to później, a na teraz należy pamiętać, że domyślnie aspekty są tworzone jako singletony.</p>
<h4>Podsumowania</h4>
<p>Wiemy już jakie mamy rodzaje porad. Jeżeli nie rozumiesz jak to działa to nie przejmuj się. Zrozumienie tego modelu tak jak zrozumienie modelu punktów przecięcia wymaga dużo czasu i jeszcze więcej praktyki. W następnej części omówię właśnie model punktów przecięcia. Jest to bardzo ważna i bardzo trudna rzecz. Dlatego też skupię się na podstawowych rodzajach punktów przecięcia.</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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/&amp;title=AspectJ+troch%C4%99+szczeg%C3%B3%C5%82%C3%B3w+%26%238211%3B+rodzaje+porad" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Del.icio.us" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' 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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/&amp;title=AspectJ+troch%C4%99+szczeg%C3%B3%C5%82%C3%B3w+%26%238211%3B+rodzaje+porad" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do digg" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' 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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Technorati" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' 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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/&amp;title=AspectJ+troch%C4%99+szczeg%C3%B3%C5%82%C3%B3w+%26%238211%3B+rodzaje+porad" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Stumble Upon" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' 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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/&amp;title=AspectJ+troch%C4%99+szczeg%C3%B3%C5%82%C3%B3w+%26%238211%3B+rodzaje+porad" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do Google Bookmarks" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' 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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/&amp;t=AspectJ+troch%C4%99+szczeg%C3%B3%C5%82%C3%B3w+%26%238211%3B+rodzaje+porad" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do FaceBook" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' 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/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/&amp;title=AspectJ+troch%C4%99+szczeg%C3%B3%C5%82%C3%B3w+%26%238211%3B+rodzaje+porad" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do wykop.pl" alt="dodaj 'AspectJ trochę szczegółów &#8211; rodzaje porad' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2009/12/29/aspectj-troche-szczegolow-rodzaje-porad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Podsumowanie wideo 4 spotkania WDPSG.</title>
		<link>http://koziolekweb.pl/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/</link>
		<comments>http://koziolekweb.pl/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 21:44:53 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Wydarzenia]]></category>
		<category><![CDATA[Wzorce projektowe]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[WDPSG]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=271</guid>
		<description><![CDATA[      
      Część 1 Część 2 Część 3 Dodaj do]]></description>
			<content:encoded><![CDATA[      
      <p>Część 1<br />
<embed id="VideoPlayback" src="http://video.google.pl/googleplayer.swf?docid=-3557411477196779408&#038;hl=pl&#038;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"> </embed><br />
Część 2<br />
<embed id="VideoPlayback" src="http://video.google.pl/googleplayer.swf?docid=7361094332542504019&#038;hl=pl&#038;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"> </embed><br />
Część 3<br />
<embed id="VideoPlayback" src="http://video.google.pl/googleplayer.swf?docid=-7833682760133420415&#038;hl=pl&#038;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"> </embed></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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/&amp;title=Podsumowanie+wideo+4+spotkania+WDPSG." title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Del.icio.us" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' 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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/&amp;title=Podsumowanie+wideo+4+spotkania+WDPSG." title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do digg" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' 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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Technorati" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' 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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/&amp;title=Podsumowanie+wideo+4+spotkania+WDPSG." title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Stumble Upon" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' 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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/&amp;title=Podsumowanie+wideo+4+spotkania+WDPSG." title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do Google Bookmarks" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' 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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/&amp;t=Podsumowanie+wideo+4+spotkania+WDPSG." title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do FaceBook" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' 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/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/&amp;title=Podsumowanie+wideo+4+spotkania+WDPSG." title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do wykop.pl" alt="dodaj 'Podsumowanie wideo 4 spotkania WDPSG.' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2008/12/13/podsumowanie-wideo-4-spotkania-wdpsg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Singleton inaczej</title>
		<link>http://koziolekweb.pl/2008/12/10/singleton-inaczej/</link>
		<comments>http://koziolekweb.pl/2008/12/10/singleton-inaczej/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 23:27:04 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Antywzorce]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Wzorce projektowe]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Singleton]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=213</guid>
		<description><![CDATA[      
      Po dzisiejszym spotkaniu WDPSG nasunął mi się pewien wniosek. Rozmawialiśmy sobie o wzorcu Singleton i jego zastosowaniach. Dyskusja była bardzo ciekawa i rzuciła nowe światło na problem wzorca Singleton. Jednak po kolei. Patrząc na źródła wiedzy o wzorcu na polskiej i angielskiej wikipedii można dojść do wniosku, że Singleton jest bardzo prostym wzorcem. Wrażenie to [...]]]></description>
			<content:encoded><![CDATA[      
      <p>Po dzisiejszym spotkaniu <a href="http://groups.google.com/group/warszawa-dp">WDPSG</a> nasunął mi się pewien wniosek. Rozmawialiśmy sobie o wzorcu Singleton i jego zastosowaniach. Dyskusja była bardzo ciekawa i rzuciła nowe światło na problem wzorca Singleton. Jednak po kolei.<br />
Patrząc na źródła wiedzy o wzorcu na <a href="http://pl.wikipedia.org/wiki/Wzorzec_singletonu">polskiej</a> i <a href="http://en.wikipedia.org/wiki/Singleton_pattern">angielskiej</a> wikipedii można dojść do wniosku, że Singleton jest bardzo prostym wzorcem. Wrażenie to potęgowane jest przez dość prosty diagram UML przewijający się we wszystkich publikacjach związanych z tym wzorcem. Wygląda on tak:<br />
<a href="http://koziolekweb.pl/wp-content/uploads/2008/12/singleton.png"><img src="http://koziolekweb.pl/wp-content/uploads/2008/12/singleton.png" alt="" title="singleton" width="212" height="151" class="alignleft size-medium wp-image-214"/></a><br />
Bardzo prosty i bardzo przejrzysty diagram mówiący nam&#8230; no właśnie co mówi nam ten diagram? Otóż sugeruje on, że klasa Singletona poza metodami biznesowymi jest też odpowiedzialna za samą siebie w zakresie zarządzania swoją liczebnością. No właśnie popatrzmy jeszcze raz na cechy jakie powinna spełniać implementacja by móc mówić o Singletonie. </p>
<ul>
<li>Można stworzyć co najwyżej jedną instancję, obiekt, danej klasy.</li>
<li>Instancja jest tworzona przy pierwszym użyciu.</li>
</ul>
<p>O ile pierwszy punkt jest jasny to drugi jest już moim tworem. Ma on na celu rozróżnienie klas singletonów od klas, których wszystkie metody są statyczne. Zakładam więc, że singleton to taki obiekt, który tworzony jest dopiero gdy jest potrzebny, a nie przy ładowaniu klasy. Dobrze zatem spójrzmy jeszcze raz na punkt pierwszy. Moim zdaniem, co znajduje potwierdzenie na angielskiej wiki, singletonem jest każdy obiekt, który potrafi ograniczyć ilość swoich instancji. Oznacza to, że jeżeli nasz obiekt udostępnia tylko pięć instancji samego siebie to też jest singletonem. Tu widać tą małą niedogodność związaną z nazwą wzorca. Powinna ona raczej brzmieć Kontroler Ilości Instancji (ang. <i>Instance Number Controller</i>). Lepiej by oddawała sens tego wzorca. Jednak nie ważne. Ważniejszym pytaniem jest to czy klasa powinna sama dbać o ilość swoich instancji. Jeżeli patrzymy na diagram UML to pierwszą odpowiedzią jest tak. Jak pisał <a href="http://koziolekweb.pl/2008/11/07/zrozumiec_tao/">J. Kerievski</a> </p>
<blockquote><p>Diagram UML wzorca jest tylko jednym z rozwiązań</p></blockquote>
<p>Tak samo diagram singletona jest jednym z rozwiązań, które są przed nami stawiane. Rzeczą wręcz głupią jest patrzenie na niego i traktowanie jak przenajświętszej ikony w ikonostasie diagramów wzorców projektowych.<br />
Problem ze wzorcem singleton polega przede wszystkim na złym jego wykorzystaniu. Zarówno na poziomie architektury systemu, projektu jak i implementacji. W literaturze omawia się zazwyczaj błędy popełnione w dwóch pierwszych przypadkach. Wielu ekspertów i specjalistów ds. wdrożeń przytacza setki przykładów nieprawidłowego wdrażania singletonów w systemach. Nie spotkałem się jednak z przykładem złej implementacji. Wynika to z trudności wykazania, że dana implementacja jest nieprawidłowa. Znacznie łatwiej jest pokazać, że popełniono błąd w projekcie niż w implementacji. Pytanie dlaczego? Moim zdaniem wynika to z uświęcenia diagramu UML wzorca. Bardzo łatwo poddać się w tym przypadku myśleniu &#8220;skoro to jest tak proste to nie należy tego już ulepszać&#8221;. Źródła tego sposobu postrzegania znajdują się w generalnej koncepcji wzorców, która mówi, że wprowadzone wzorce powinny upraszczać kod, domyślnie kasować pudełka z diagramu obiektów. Skoro zatem kod (abstrakcja reprezentowana przez UML) jest bardzo prosty to nie można już bardziej go uprościć. Wzorzec singleton jest doskonały, ponieważ nie da się już go bardziej uprościć.<br />
Jednocześnie jeżeli poczytamy o sposobach zamiany wzorca singleton na inny to często przytaczany jest wzorzec fabryki abstrakcyjnej, która dostarcza zawsze tego samego obiektu. Poniższy kod reprezentuje właśnie takie rozwiązanie:</p>
<p class="listing">Listing 1. Fabryka czy Singleton oto jest pytanie.</p>
<pre name="code" class="java">
package eu.runelord.blog.singleton;

public class Main {

	public static void main(String[] args) {
		ISingleton singleton = SingletonFactory.getSingleton();
		singleton.helloWorld();
	}

}

class SingletonFactory {

	private static ISingleton singleton;

	public static ISingleton getSingleton() {
		if (singleton == null)
			synchronized (SingletonFactory.class) {
				if (singleton == null)
					singleton = new ISingleton() {

						@Override
						public void helloWorld() {
							System.out.println("Hello World");

						}
					};
			}
		return singleton;
	}
}

interface ISingleton {
	public void helloWorld();
}</pre>
<p>Piękny przykład fabryki, która dostarcza nam jednej i tylko jednej instancji klasy singletonu. No właśnie, czy na pewno jest to <u>tylko</u> fabryka&#8230;<br />
Wróćmy na chwilę do naszej listy wymagań. Czy nasze nowe rozwiązanie spełnia punkt pierwszy? Na pewno ponieważ udostępnia jedną instancję. Czy spełnia punkt drugi? Też spełnia ponieważ obiekt jest tworzony dopiero przy pierwszym użyciu. Zatem&#8230;</p>
<h4>Fabryka czy Singleton oto jest pytanie?</h4>
<p>No właśnie czy przedstawione powyżej rozwiązanie jest fabryką czy singletonem? Odpowiedź brzmi jest zarówno fabryką jak i singletonem. W tym przypadku nasza fabryka jest jednocześnie specyficzną implementacją, która spełnia założenia singletonu. Z drugiej strony rozwiązanie to jest singletonem, który realizowany jest w oparciu o fabrykę.<br />
Problem z tym konkretnym rozwiązaniem jest taki, że odrzuciłem standardowy diagram UML na korzyść innej drogi. Sam diagram skomplikował się lecz rozwiązanie nadal spełnia wszystkie warunki. Dodatkowo jest znacznie prostsze.<br />
Pytanie brzmi czy moje podejście do problemu jest lepsze? Otóż to zależy. Przedstawiłem jedno ze standardowych rozwiązań, które pretenduje do miana zamiennika dla singletonu. Tak naprawdę 99% złych wdrożeń tego wzorca odbywa się na etapie implementacji, a nie projektowania. Prezentując takie rozwiązanie pomijane jest inne znacznie prostsze, które nawet wygląda jak &#8220;prawdziwy&#8221; jedno klasowy singleton. Oto i ono:</p>
<p class="listing">Listing 2. Rasowy singleton w nowej odsłonie</p>
<pre name="code" class="java">
package eu.runelord.blog.singleton;

public class Main {

	public static void main(String[] args) {
		ISingleton singleton = Singleton.getSingleton();
		singleton.helloWorld();
	}

}

class Singleton implements ISingleton {

	private static Singleton singleton;

	public static Singleton getSingleton() {
		if (singleton == null)
			synchronized (SingletonFactory.class) {
				if (singleton == null)
					singleton = new Singleton();
			}
		return singleton;
	}

	private Singleton(){}

	@Override
	public void helloWorld() {
		System.out.println("Hello World");
	}

}
</pre>
<p>Czy różni się ono od poprzedniego? Nie! Jedyną różnicą jest konsolidacja kodu fabryki i obiektu biznesowego w ramach jednej klasy. Jednocześnie jeżeli przedstawilibyśmy komuś ten kod i zapytali o wzorce to odpowiedź będzie brzmiała &#8220;To jest Singleton.&#8221;.</p>
<h4>O co cały ten szum&#8230;</h4>
<p>Mówiłem już, że 99% złych singletonów to dzieci błędnej implementacji. Nie projektu, a właśnie błędnej implementacji. Zanim przejdę do omówienia tego problemu popatrzmy na listę wad singletona:</p>
<ul>
<li>Singleton jest trudny do testowania</li>
<li>Singletonu nie można rozszerzyć</li>
<li>Singleton łamie zasadę SRP</li>
<li>Singleton łamie zasadę OCP</li>
<li>Singleton jest trudny w testowaniu</li>
</ul>
<p>Programiści to osoby o bardzo zróżnicowanym charakterach i osobowościach. Jednak jeżeli miałbym wybrać jedną cechę, która łączy wszystkich programistów to wybrałbym silne poczucie indywidualizmu. Na spotkaniu WDPSG określiłem siebie jako programistę &#8211; artystę. Jest tak ponieważ tak jak każdy artysta poza warsztatem rzemieślniczym posiadam silne poczucie własnej odrębności nawet w grupie osób o podobnych zainteresowaniach.<br />
Po tej malej dygresji popatrzmy jeszcze raz na naszą listę. Czy nie macie wrażenia, że większość problemów związanych z singletonami wynika tak naprawdę z błędów w implementacji wzorca? Przyjrzyjmy się nowej wersji &#8220;klasycznego&#8221; diagramu UML prezentującego singleton:<br />
<a href="http://koziolekweb.pl/wp-content/uploads/2008/12/singleton1.png"><img src="http://koziolekweb.pl/wp-content/uploads/2008/12/singleton1.png" alt="" title="singleton1" width="193" height="232" class="size-medium wp-image-220" /></a><br />
Takie nieortodoksyjne podejście i wprowadzenie interfejsu pozwala nam na pozbycie się trzech problemów. Nasz singleton jest już rozszerzalny. Rozszerzyć możemy go poprzez implementację interfejsu. Jeżeli nie chcemy pisać dużej ilości kodu można prowadzić dodatkowy obiekt adaptera, który będzie delegował zachowania do oryginalnego obiektu. My będziemy musieli tylko zaimplementować zmiany. Tym samym nasz singleton nie łamie już zasady OCP. W ogólności nie łamana jest też zasada SRP ponieważ wzorzec wymusza jakąś kontrolę ilości instancji. Sposób jej realizacji może być różny. Można zastosować fabrykę i po problemie. Pozostaje nam jeden problem związany z testowaniem. Tu można wyróżnić dwa rodzaje singletonów.<br />
Pierwszy z nich to singletony bezstanowe. Ich zadanie polega na dostarczaniu metod i nie robieniu tego w sposób statyczny. Te singletony testuje się bardzo, bardzo prosto. Ponieważ na etapie inicjacji testu nie musimy ustawiać żadnych właściwości obiektu nie ma więc potrzeby jakiegoś specjalnego jego traktowania. Powiem nawet więcej, singleton będzie nam ułatwiał życie gdyż inicjację testowanego obiektu trzeba wykonać tylko raz. W tym przypadku problem jest sztuczny, czyli nie istnieje.<br />
Druga grupa to singletony stanowe. Przechowują one pewne dane i tym samym mają stan. Pół biedy jeżeli wszystkie pola są dostępne i można wywołać dla nich metody ustawiające (settery). W takim wypadku wystarczy na etapie czyszczenia po teście zerować pola i ustawiać je na nowo przed każdym testem. Znacznie gorzej ma się sprawa pól do których jedyną metodą dostępu jest refleksja.<br />
Uwaga, będę omawiał teraz zagadnienia związane z Javą i raczej nie znam metod rozwiązania tego problemu w innych językach.<br />
W takim przypadku musimy poszukać jakiegoś obejścia. Kiedyś przedstawiłem już jedno z <a href="http://koziolekweb.pl/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/">rozwiązań</a>. Jest ono dość kontrowersyjne, ale się sprawdza. Szczególnie, że można je dość łatwo zaimplementować jako rozszerzenie JUnita.<br />
Gdzie jest w tym myk? Otóż cała magia tego rozwiązania polega na wyrzuceniu wszystkich metod biznesowych do interfejsu. W ten oto prosty sposób realizując założenia wzorca singleton nadal mamy swobodę dostarczania innego rozwiązania. Programiści zazwyczaj nie ekstrahują interfejsu biznesowego i starają się zwalić winę na projektantów. Projektanci też nie są bez winy ponieważ dostarczają programistom diagram UML, w którym bezmyślnie kopiują nie do końca dobre rozwiązania.</p>
<h4>Podsumowanie</h4>
<p>Wzorzec singleton jest może prosty, ale trzeba umieć go stosować. Wiedza ta potrzebna jest zarówno architektom, projektantom jak i zwykłym programistom ponieważ błędy rodzą się na wszystkich etapach.<br />
Wzorzec singleton jest specyficznym rodzajem fabryki i można to wykorzystać.<br />
W końcu, diagram UML wzorca singleton nie jest świętością i nie należy stosować go w takiej postaci wszędzie. Można zaimplementować singleton na inne sposoby i choć diagram staje się trochę bardziej skomplikowany to nadal jest to singleton.</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/2008/12/10/singleton-inaczej/&amp;title=Singleton+inaczej" title="dodaj 'Singleton inaczej' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Singleton inaczej' do Del.icio.us" alt="dodaj 'Singleton inaczej' 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/2008/12/10/singleton-inaczej/&amp;title=Singleton+inaczej" title="dodaj 'Singleton inaczej' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Singleton inaczej' do digg" alt="dodaj 'Singleton inaczej' 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/2008/12/10/singleton-inaczej/" title="dodaj 'Singleton inaczej' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Singleton inaczej' do Technorati" alt="dodaj 'Singleton inaczej' 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/2008/12/10/singleton-inaczej/&amp;title=Singleton+inaczej" title="dodaj 'Singleton inaczej' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Singleton inaczej' do Stumble Upon" alt="dodaj 'Singleton inaczej' 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/2008/12/10/singleton-inaczej/&amp;title=Singleton+inaczej" title="dodaj 'Singleton inaczej' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Singleton inaczej' do Google Bookmarks" alt="dodaj 'Singleton inaczej' 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/2008/12/10/singleton-inaczej/&amp;t=Singleton+inaczej" title="dodaj 'Singleton inaczej' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Singleton inaczej' do FaceBook" alt="dodaj 'Singleton inaczej' 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/2008/12/10/singleton-inaczej/&amp;title=Singleton+inaczej" title="dodaj 'Singleton inaczej' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Singleton inaczej' do wykop.pl" alt="dodaj 'Singleton inaczej' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2008/12/10/singleton-inaczej/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Singleton i Łańcuch konstruktorów</title>
		<link>http://koziolekweb.pl/2008/11/19/singleton-i-lancuch-konstruktorow/</link>
		<comments>http://koziolekweb.pl/2008/11/19/singleton-i-lancuch-konstruktorow/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 10:22:32 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Wzorce projektowe]]></category>
		<category><![CDATA[4programmers]]></category>
		<category><![CDATA[Artykuł]]></category>
		<category><![CDATA[Chain Constructors]]></category>
		<category><![CDATA[Singleton]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[      
      Popełniłem wczoraj dwa artykuły na 4programmers. Pierwszy dotyczy wzorca Singleton, a drugi wzorca Chain Constructors (łańcuch konstruktorów). Zapraszam do lektury. Dodaj do]]></description>
			<content:encoded><![CDATA[      
      <p>Popełniłem wczoraj dwa artykuły na <a href="http://4programers.net">4programmers</a>. Pierwszy dotyczy wzorca <a href="http://4programmers.net/In%C5%BCynieria_oprogramowania/Wzorce_projektowe/Singleton">Singleton</a>, a drugi wzorca <a href="http://4programmers.net/In%C5%BCynieria_oprogramowania/Wzorce_projektowe/%C5%81a%C5%84cuch_konstruktor%C3%B3w">Chain Constructors</a> (łańcuch konstruktorów). Zapraszam do lektury.</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/2008/11/19/singleton-i-lancuch-konstruktorow/&amp;title=Singleton+i+%C5%81a%C5%84cuch+konstruktor%C3%B3w" title="dodaj 'Singleton i Łańcuch konstruktorów' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do Del.icio.us" alt="dodaj 'Singleton i Łańcuch konstruktorów' 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/2008/11/19/singleton-i-lancuch-konstruktorow/&amp;title=Singleton+i+%C5%81a%C5%84cuch+konstruktor%C3%B3w" title="dodaj 'Singleton i Łańcuch konstruktorów' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do digg" alt="dodaj 'Singleton i Łańcuch konstruktorów' 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/2008/11/19/singleton-i-lancuch-konstruktorow/" title="dodaj 'Singleton i Łańcuch konstruktorów' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do Technorati" alt="dodaj 'Singleton i Łańcuch konstruktorów' 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/2008/11/19/singleton-i-lancuch-konstruktorow/&amp;title=Singleton+i+%C5%81a%C5%84cuch+konstruktor%C3%B3w" title="dodaj 'Singleton i Łańcuch konstruktorów' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do Stumble Upon" alt="dodaj 'Singleton i Łańcuch konstruktorów' 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/2008/11/19/singleton-i-lancuch-konstruktorow/&amp;title=Singleton+i+%C5%81a%C5%84cuch+konstruktor%C3%B3w" title="dodaj 'Singleton i Łańcuch konstruktorów' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do Google Bookmarks" alt="dodaj 'Singleton i Łańcuch konstruktorów' 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/2008/11/19/singleton-i-lancuch-konstruktorow/&amp;t=Singleton+i+%C5%81a%C5%84cuch+konstruktor%C3%B3w" title="dodaj 'Singleton i Łańcuch konstruktorów' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do FaceBook" alt="dodaj 'Singleton i Łańcuch konstruktorów' 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/2008/11/19/singleton-i-lancuch-konstruktorow/&amp;title=Singleton+i+%C5%81a%C5%84cuch+konstruktor%C3%B3w" title="dodaj 'Singleton i Łańcuch konstruktorów' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Singleton i Łańcuch konstruktorów' do wykop.pl" alt="dodaj 'Singleton i Łańcuch konstruktorów' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2008/11/19/singleton-i-lancuch-konstruktorow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trzeba mieć refleks synku&#8230; o testowaniu Singletonów</title>
		<link>http://koziolekweb.pl/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/</link>
		<comments>http://koziolekweb.pl/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 23:36:00 +0000</pubDate>
		<dc:creator>Koziolek</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Inżynieria Oprogramowania]]></category>
		<category><![CDATA[Singleton]]></category>

		<guid isPermaLink="false">http://koziolekweb.pl/?p=50</guid>
		<description><![CDATA[      
      Przypowieść świąteczna Dawno, dawno temu na stercie żył sobie Obiekt Pewnej Klasy (OPK). OPK był bardzo smutny, gdyż nie miał kolegów z którymi mógłby się wymieniać danymi i bawić w gry synchronizacyjne. Dlatego też OPK prosił Programistę: - Programisto stwórz mi kolegę bym mógł z nim pracować i się bawić po pracy Programista widząc, że [...]]]></description>
			<content:encoded><![CDATA[      
      <h4>Przypowieść świąteczna</h4>
<p>
<p>Dawno, dawno temu na stercie żył sobie Obiekt Pewnej Klasy (OPK). OPK był bardzo smutny, gdyż nie miał kolegów z którymi mógłby się wymieniać danymi i bawić w gry synchronizacyjne. Dlatego też OPK prosił Programistę:</p>
<p>
<ul style="list-style-type: none; list-style-image: none; list-style-position: outside;">
<li>- Programisto stwórz mi kolegę bym mógł z nim pracować i się bawić po pracy</li>
<p></ul>
<p>
<p>Programista widząc, że OPK chce dobra usłuchał jego prośby. Stworzył Kolejny OPK i go zainicjował po czym wrócił do do picia piwa i oglądania filmików.</p>
<p>
<p>OPK i KOPK dość szybko stwierdziły, że do brydża trzeba czterech, a potem już we czwórkę, że piłka kopana to co najmniej 22 uczestników. I tak oto O-tyPK mnożyły się i zapełniały RAM i zabierały procesor. Koniec końców, gdy skończyło się piwo, a filmiki z powodu braku zasobów komputera drastycznie zwolniły Programista zajrzał na stertę, zasmucił się i rzekł:</p>
<p>
<ul style="list-style-type: none; list-style-image: none; list-style-position: outside;">
<li>- Dlaczego żeś mi to uczynił OPK?</li>
<p>
<li>Na co OPK odpowiedział</li>
<p>
<li>- Bo mnie nie przetestowałeś idioto&#8230;</li>
<p>
<li>- Oż w żopu&#8230; ale i tak masz przestane, bo będziesz Singletonem <img src='http://koziolekweb.pl/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> - rzekł Programista i zabrał się do przerabiania OPK.</li>
<p></ul>
<p>
<p>Programista kodował całą noc, refaktoryzował kod i przebudowywał referencje. Jednak pamiętając, że obiekt smutny będzie, gdy nie będzie mógł grać w ukochaną synchronizację stworzył mu pola finalne by już nigdy nie pragnął synchronizacji. Po czym powołał OPK do życia i rzekł:</p>
<p>
<ul style="list-style-type: none; list-style-image: none; list-style-position: outside;">
<li>- Za karę, że mnożyłeś się bez opamiętania uczyniłem Cię Singletonem. nigdy już nie będziesz pragnął grać w Synchronizację. Jeszcze Cię tylko przetestuję.</li>
<p>
<li>OPK popatrzył na siebie i rozradowany rzekł:</li>
<p>
<li>- A Chuja se przetestuj mondziole&#8230; Mam pola <span style="font-weight:bold;">final</span> i <span style="font-weight:bold;">private</span> co raz utworzone nie może być zmienione więc mnie nie przetestujesz, bo konfigurację dostarczasz tylko raz w konstruktorze. </li>
<p></ul>
<p>
<p>To powiedziawszy OPK dumny z siebie zasiadł w statycznej pamięci.</p>
<p>
<h4>Problem</h4>
<p>
<p>Czego uczy nas ta przypowieść? Otóż Singleton jest bardzo dobrym wzorcem wszędzie tam gdzie wiemy, że nie potrzeba więcej niż jednego obiektu danej klasy oraz, wtedy gdy chcemy zaoszczędzić zasoby. Jednakże singletony ciężko się testuje. Dlaczego? Przyjrzyjmy się tej klasie:</p>
<p>
<p class="listing">Listing 1. Klasa Singleton z polem prywatnym i finalnym</p>
<pre name="code" class="java">
package eu.runelord.blog;

public class Singleton {
	private static Singleton INSTANCE;

	private final String name;

	public static Singleton getInstance() {
		if (INSTANCE == null)
			INSTANCE = new Singleton();

		return INSTANCE;
	}

	private Singleton() {
		this.name = null;
	}

	public String toString() {
		return name;
	}
}
</pre>
<p>
<p>Mamy tu typowy problem. Pole <span style="font-style:italic;">name</span> jest prywatne i finalne jednocześnie. Może się to wiązać z np. odczytem konfiguracji tego pola z pliku properties przy starcie aplikacji i chęci zagwarantowania jej niezmienności. Pytanie brzmi jak przetestować taki obiekt by móc wgrać kilka różnych konfiguracji? Najprościej jest zmienić modyfikatory pól na czas testów. Pomysł głupi ponieważ utrudnia automatyzację testów. Pomysł drugi wykorzystać oddzielne ClassLoadery dla każdego testu. Nieźle, ale trzeba dość dużo pisać w dodatku można popełnić masę błędów. Trzecia metoda użyć mechanizmów Reflection API.</p>
<p>
<p> Moja propozycja jest trochę inna. Skoro singleton pozwala na konfigurację z pliku wskazanego przez programistę to wystarczy w każdym teście podawać inny plik i po zakończeniu nullować pole przetrzymujące referencję do naszego obiektu. Przykładowa aplikacja:</p>
<p>
<p class="listing">Listing 2. Aplikacja która umie nullować Singleton</p>
<pre name="code" class="java">
package eu.runelord.blog;

import java.lang.reflect.Field;

public class App {
	public static void main(String[] args) throws Exception {
		Singleton singleton = Singleton.getInstance();
		System.out.println(singleton);

		Class singletonClass = Singleton.class;
		Field fieldName = singletonClass.getDeclaredField("name");

		fieldName.setAccessible(true);
		System.out.println(fieldName.get(singleton));
		fieldName.set(singleton, "dupa");
		System.out.println(fieldName.get(singleton));

	}
}
</pre>
<p>
<p>Kluczowym elementem całej operacji jest umożliwienie dostępu do pola <span style="font-style:italic;">INSTANCE</span> za pomocą metody <samp>setAccessible()</samp>.</p>
<p>
<p>Metoda jest bardzo prosta i przy skomplikowanych testach może się nie sprawdzać, ale na początek wystarczy.</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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/&amp;title=Trzeba+mie%C4%87+refleks+synku%26%238230%3B+o+testowaniu+Singleton%C3%B3w" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Del.icio.us"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/delicious.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Del.icio.us" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' 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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/&amp;title=Trzeba+mie%C4%87+refleks+synku%26%238230%3B+o+testowaniu+Singleton%C3%B3w" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do digg"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/digg.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do digg" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' 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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Technorati"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/technorati.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Technorati" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' 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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/&amp;title=Trzeba+mie%C4%87+refleks+synku%26%238230%3B+o+testowaniu+Singleton%C3%B3w" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Stumble Upon"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/stumbleupon.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Stumble Upon" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' 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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/&amp;title=Trzeba+mie%C4%87+refleks+synku%26%238230%3B+o+testowaniu+Singleton%C3%B3w" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Google Bookmarks"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/google.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do Google Bookmarks" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' 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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/&amp;t=Trzeba+mie%C4%87+refleks+synku%26%238230%3B+o+testowaniu+Singleton%C3%B3w" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do FaceBook"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/facebook.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do FaceBook" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' 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/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/&amp;title=Trzeba+mie%C4%87+refleks+synku%26%238230%3B+o+testowaniu+Singleton%C3%B3w" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do wykop.pl"><img src="http://koziolekweb.pl/wp-content/plugins/social-bookmarking-reloaded/wykop.png" title="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do wykop.pl" alt="dodaj 'Trzeba mieć refleks synku&#8230; o testowaniu Singletonów' do wykop.pl" /></a></div>
<!-- Social Bookmarking Reloaded END -->]]></content:encoded>
			<wfw:commentRss>http://koziolekweb.pl/2008/03/22/trzeba-miec-refleks-synku-o-testowaniu-singletonow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

