<?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/"
	>

<channel>
	<title>Blog programisty</title>
	<atom:link href="http://web-design.net.pl/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://web-design.net.pl/blog</link>
	<description>Dobre praktyki w programowaniu, wzorce projektowe J2EE, OOP w PHP</description>
	<pubDate>Sun, 04 Apr 2010 16:58:03 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cechy dobrego projektu - 4. Zasada open / close</title>
		<link>http://web-design.net.pl/blog/2009/05/cechy-dobrego-projektu-4-zasada-open-close/</link>
		<comments>http://web-design.net.pl/blog/2009/05/cechy-dobrego-projektu-4-zasada-open-close/#comments</comments>
		<pubDate>Wed, 06 May 2009 21:47:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cechy dobrego projektu]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/blog/?p=120</guid>
		<description><![CDATA[software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification [Bertrand Meyer]
Nasz kod powinien być zamknięty na modyfikację i otwarty na rozszerzanie. Inaczej mówiąc: rozwijając projekt, nie powinniśmy zmieniać istniejącego kodu, a jedynie go rozszerzać.
Gdy zmieniamy coś w istniejącym kodzie, bardzo łatwo zepsuć inną funkcjonalność, która z tego fragmentu kodu [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification [Bertrand Meyer]</p></blockquote>
<p>Nasz kod powinien być zamknięty na modyfikację i otwarty na rozszerzanie. Inaczej mówiąc: rozwijając projekt, nie powinniśmy zmieniać istniejącego kodu, a jedynie go rozszerzać.</p>
<p>Gdy zmieniamy coś w istniejącym kodzie, bardzo łatwo zepsuć inną funkcjonalność, która z tego fragmentu kodu korzysta.<br />
Zgodnie z zasadą <strong>open/close</strong> należy unikać modyfikacji istniejącego kodu.</p>
<p>Przykład:<br />
Piszemy prostą aplikację, która wypisuje zawartość pliku tekstowego na ekran numerując linie pliku. </p>
<p>Do dyspozycji mamy funkcję <code>render_file()</code> która ma za zadanie wypisać na wyjście zawartość pliku z ponumerowanymi liniami. Funkcja <code>render_file()</code> używa klasy <code>SimpleSequence</code>, która umożliwia wygenerowanie kolejnych liczb naturalnych.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> SimpleSequence
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #b1b100;">return</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> render_file<span style="color: #009900;">&#40;</span><span style="color: #000088;">$file_name</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
     <span style="color: #000088;">$seq</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleSequence<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file_name</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span>
     <span style="color: #009900;">&#123;</span>
          <span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">%s</span>: <span style="color: #009933; font-weight: bold;">%s</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$seq</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>        
     <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>index.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">render_file<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;myfile.txt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Założenia są spełnione. Nasz program działa prawidłowo.</p>
<p>Jednak co w przypadku, gdy będziemy musieli zmienić jego działanie i numerować linie pliku za pomocą liter &#8220;a&#8221; - &#8220;z&#8221;?</p>
<p>Będziemy musieli zmienić zawartość funkcji <code>render_file()</code>, a więc nie jest spełniona zasada <strong>open/close</strong>.</p>
<p><strong>Jak zrobić to lepiej?</strong></p>
<p>Zmodyfikujmy nieco nasz program przez dodanie interfejsu ISequence.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span> ISequence
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> SimpleSequence implements ISequence
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">i</span><span style="color: #339933;">++;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> render_file<span style="color: #009900;">&#40;</span><span style="color: #000088;">$file_name</span><span style="color: #339933;">,</span> ISequence <span style="color: #000088;">$seq</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
     <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file_name</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span>
     <span style="color: #009900;">&#123;</span>
          <span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">%s</span>: <span style="color: #009933; font-weight: bold;">%s</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$seq</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>        
     <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>index.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">render_file<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;myfile.txt&quot;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleSequence<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><strong>Co zyskujemy?</strong><br />
NIE MUSIMY zmieniać ani implementacji metody <code>render_file()</code>, ani klasy <code>SimpleSequence</code>.</p>
<p>Teraz aby wypisać zawartość pliku &#8220;numerując&#8221; linie kolejnymi literami alfabety wystarczy zaimplementować nową klasę implementującą interfejs <code>ISequence</code>, np. <code>AlphaSequence</code>. Klasa ta za pomocą metody <code>next()</code> będzie zwracać kolejne litery alfabetu.</p>
<p>index.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> AlphaSequence implements ISequence
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$chars</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'abcdefghijklmnopqrstuvwxyz'</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">chars</span><span style="color: #009900;">&#91;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">i</span><span style="color: #339933;">++</span> <span style="color: #339933;">%</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">chars</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
render_file<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;myfile.txt&quot;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">new</span> AlphaSequence<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>To tylko prosty przykład. Tak naprawdę konieczność stosowania tej zasady poznajemy, gdy pracujemy z setkami tysięcy linii kodu. W praktyce wygląda to tak, że każda zmiana istniejącego kodu może powodować nieoczekiwane zmiany w istniejących już elementach naszego projektu (tu bardzo ważna jest zasada &#8220;Low coupling, high cohesion&#8221; - minimalizacja zależności pomiędzy modułami, maksymalizacja spójności modułów).</p>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/05/cechy-dobrego-projektu-4-zasada-open-close/feed/</wfw:commentRss>
		</item>
		<item>
		<title>OOP: Singleton - kiedy użyć tylko jednego obiektu klasy?</title>
		<link>http://web-design.net.pl/blog/2009/05/wzorce-oop-1-singleton/</link>
		<comments>http://web-design.net.pl/blog/2009/05/wzorce-oop-1-singleton/#comments</comments>
		<pubDate>Tue, 05 May 2009 19:28:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Wzorce OOP]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/blog/?p=102</guid>
		<description><![CDATA[Potrzebujesz jednej instancji (obiektu) klasy w czasie uruchomienia aplikacji? Potrzebujesz, aby instancja klasy dostępnej z dowolnego miejsca w kodzie? Możesz użyć wzorca singleton.
Najprostsza klasa implementująca wzorzec singleton w PHP wygląda następująco:

class Singleton
&#123;
    private static $instance = null;
    private __construct&#40;&#41; &#123;&#125;;
    public static getInstance&#40;&#41;
    [...]]]></description>
			<content:encoded><![CDATA[<p>Potrzebujesz jednej instancji (obiektu) klasy w czasie uruchomienia aplikacji? Potrzebujesz, aby instancja klasy dostępnej z dowolnego miejsca w kodzie? Możesz użyć wzorca <strong>singleton</strong>.</p>
<p>Najprostsza klasa implementująca wzorzec singleton w PHP wygląda następująco:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Singleton
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #990000;">static</span> <span style="color: #000088;">$instance</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #990000;">static</span> getInstance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$instance</span> <span style="color: #339933;">==</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> 
            <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$instance</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Singleton<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$instance</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Przykład użycia - tworzymy klasę, która udostępnia szczegóły zapytania HttpRequest:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Request.class.php:</span>
<span style="color: #000000; font-weight: bold;">class</span> Request
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$params</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #990000;">static</span> <span style="color: #000088;">$instance</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_merge</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #990000;">static</span> getInstance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$instance</span> <span style="color: #339933;">==</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> 
            <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$instance</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Singleton<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$instance</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$default</span><span style="color: #339933;">=</span><span style="color: #000000; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> 
            ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$default</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Teraz instancji klasy Request możemy używać w wielu miejscach w kodzie, np. w pliku kontrolera:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// index.php:</span>
<span style="color: #000000; font-weight: bold;">function</span> showPage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">echo</span> <span style="color: #0000ff;">'Hello, '</span> 
        <span style="color: #339933;">.</span> Request<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Name&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'World'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>    
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>jak również w innym, dowolnym miejscu naszego projektu:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// OtherClass.php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> OtherClass
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> processForm<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
       <span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> Request<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span> 
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Invalid name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Zalety:</strong><br />
- <strong>jednokrotna inicjalizacja</strong> (w powyższym przykładzie konstruktor jest wywoływany co najwyżej raz w czasie uruchomienia skryptu).<br />
- możliwość przenoszenia danych <strong>pomiędzy warstwami</strong> (np. obiekt <code>Request</code> może być użyty zarówno w kontrolerze, jak i widoku).<br />
- użycie Singletona jest lepsze od zmiennych globanych. <strong>Nie zaśmieca przestrzeni zmiennych globalnych</strong>. Za pomocą Singletona można <strong>zahermetyzować</strong> w jednej klasie powiązane ze sobą dane.</p>
<p><strong>Wady:</strong><br />
- Wzorzec Singleton użyty niewłaściwie może wprowadzać chaos w kodzie (podobnie jak zmienne globalne). </p>
<p><strong>Kiedy używać?</strong></p>
<p>Wzorzec singleton jest często używany do implementacji:<br />
- obiektów, przechowujących informacje o stanie aplikacji,<br />
- obiektów które powinny istnieć przez cały czas trwania aplikacji,<br />
- fabryk abstrakcyjnych (<a href="http://en.wikipedia.org/wiki/Abstract_factory_pattern">AbstractFactory</a>)</p>
<p>Przykłady użycia:</p>
<p>Klasa <code>Log</code> - używana w wielu miejscach zapisuje logi do pliku:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">Log</span><span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">message</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;start...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><a href="http://en.wikipedia.org/wiki/Abstract_factory_pattern">Fabryka abstrakcyjna</a> - tworzy instancję określonej fabryki (o wzorcu fabryki postaram się napisać w kolejnych postach)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$type</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;MyProductFactory&quot;</span><span style="color: #339933;">;</span>
AbstractFactory<span style="color: #339933;">::</span><span style="color: #004000;">getIstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">createFactory</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Fasada. Wyobraźmy sobię klasę <code>CheckoutFacade</code>. Metoda <code>placeOrder()</code> wykonuje kilka logicznie powiązanych ze sobą operacji. Metoda ta zapisuje dane z koszyka i dane klienta do bazy danych z zamówieniami, oraz wysyła maila z potwierdzeniem zamówienia.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$facade</span> <span style="color: #339933;">=</span> CheckoutFacade<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$facade</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">placeOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$CartData</span><span style="color: #339933;">,</span> <span style="color: #000088;">$CustomerData</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><small>Podany przykład użycia wzorca <strong>Singleton</strong> przy implementacji klasy <code>Request</code> ma pewne wady (o tym postaram się napisać w kolejnych postach). Jednak w prostych aplikacjach webowych się sprawdza.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/05/wzorce-oop-1-singleton/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cechy dobrego projektu - 3. Minimum złożoności</title>
		<link>http://web-design.net.pl/blog/2009/04/dobry-projekt-3-minimum-zlozonosci/</link>
		<comments>http://web-design.net.pl/blog/2009/04/dobry-projekt-3-minimum-zlozonosci/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 20:50:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cechy dobrego projektu]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/?p=32</guid>
		<description><![CDATA[Jak radzić sobie z dużymi problemami lub skomplikowanymi wymaganiami funkcjonalnymi naszego projektu?

Duże problemy dziel na mniejsze &#8220;podproblemy&#8221;, tak aby można było je rozwiązać niezależnie od siebie (zasada dekompozycji).
Eliminuj mało istotne szczegóły problemu, wyodrębniaj cechy wspólne (zasada abstrakcji).


Przykład: 
Tworzona przez nas aplikacja ma za zadanie wczytywać katalog produktów do bazy danych. Program powinien mieć możliwość wczytania [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Jak radzić sobie z dużymi problemami lub skomplikowanymi wymaganiami funkcjonalnymi naszego projektu?</strong></p>
<ul>
<li><strong>Duże problemy dziel na mniejsze &#8220;podproblemy&#8221;</strong>, tak aby można było je rozwiązać niezależnie od siebie (<strong>zasada dekompozycji</strong>).</li>
<li>Eliminuj mało istotne szczegóły problemu, <strong>wyodrębniaj cechy wspólne</strong> (<strong>zasada <a href="http://pl.wikipedia.org/wiki/Abstrakcja_(programowanie)">abstrakcji</a></strong>).</li>
</ul>
<p><img src="http://web-design.net.pl/blog/wp-content/uploads/2009/04/podproblemy-abstr.png" alt="podproblemy-abstr" title="podproblemy-abstr" class="alignnone size-full wp-image-56" /></p>
<h3>Przykład: </h3>
<p>Tworzona przez nas aplikacja ma za zadanie wczytywać katalog produktów do bazy danych. Program powinien mieć możliwość wczytania danych do katalogu z pliku Excel&#8217;a znajdującego się na lokalnym dysku lub połączyć się z serwerem FTP i pobrać plik w formacie CSV.</p>
<h4>Złe podejście:</h4>
<p>Wydaje nam się, że problem jest na tyle prosty, że całość możemy zapisać w jednej metodzie, np.:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">void</span> <span style="color: #000000; font-weight: bold;">import</span><span style="color: #009900;">&#40;</span>bool downloadFromFtp<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>downloadFromFtp<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">// ...    </span>
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Metoda <code>import()</code> w zależności od wartości parametru <code>downoadFromFtp</code> otworzy plik CSV i wczyta dane do naszej bazy danych lub pobierze plik w formacie .xls przez ftp i wczyta produkty do bazy.</p>
<p>
Jednak <strong>co w przypadku, gdy klient zamówi dodatkową funkcjonalność </strong>- możliwość pobrania katalogu produktów w formacie XML przez web service? Musimy znowu zagłębiać się w szczegóły napisanej wcześniej metody <code>import()</code>. Musimy zmieniać argumenty przekazywane do tej metody i wszystkie miejsca w których metoda ta była używana. Oprócz tego, że piszemy procedurę odczytu z pliku XML, musimy napisać jeszcze raz procedurę zapisu do bazy produktów w sklepie.<br />
Metoda <code>import()</code> robi się co raz większa i co raz mniej czytelna.<br />
Ponadto - jeżeli zmieni się struktura naszej bazy produktów w sklepie, będziemy musieli zmienić kod w 3 miejscach - przy implementacji zapisu danych pobranych z pliku Excel, CSV i XML.</p>
<p>Spróbujmy więc rozwiązać problem inaczej&#8230;</p>
<h4>Dobre podejście: (zgodne z zasadą dekompozycji i abstrakcji).</h4>
<p>W pierwszym kroku, zamiast zajmować się szczegółami odczytu plików Excel, CSV i połączenia z FTP <strong>próbujemy wydzielić część wspólną</strong>. Wiemy, że nasz program powinien pobierać katalog produktów z różnych źródeł i zapisywać go do naszej bazy. Dlatego możemy utworzyć następujący interfejs (Java):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> ProductImporter <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> Products importProducts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Gdy mamy już wspólny interfejs, możemy przejść do szczegółów. Implementujemy 2 niezależne od siebie importery - jeden z lokalnego pliku Excel&#8217;a, a drugi z pliku CSV znajdującego się na serwerze:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CsvProductImporter <span style="color: #000000; font-weight: bold;">implements</span> ProductImporter <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> Products importProducts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// ....implementacja</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>a osobno importer z pliku Excel na zdalnym serwerze ftp</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> FtpXlsProductImporter <span style="color: #000000; font-weight: bold;">implements</span> ProductImporter <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> Products importProducts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// ....implementacja</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Nasze importery zwracają jednakowy format danych - kolekcję produktów. Teraz implementujemy operację zapisu tych danych do naszej bazy, np.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ProductManager <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> store<span style="color: #009900;">&#40;</span>Products products<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Zalety takiego podejścia:</strong></p>
<ul>
<li><strong>Aby umożliwić wczytywanie danych z innego źródła</strong> (np. z pliku XML), nie musimy przerabiać istniejącego kodu - wystarczy, że zaimplementujemy nową klasę importera, np. XmlProductImporter</li>
<li><strong>Importery są niezależne od struktury danych w bazie</strong>. Gdy zmieni nam się struktura danych w bazie, nie musimy modyfikować poszczególnych importerów</li>
<li><strong>Kompozycja klas i interfejsów jest bliska naturalnemu opisowi problemu</strong>, przez to bardziej czytelna i łatwiejsza w zrozumieniu</strong>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/04/dobry-projekt-3-minimum-zlozonosci/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nie tylko refaktoring</title>
		<link>http://web-design.net.pl/blog/2009/04/nie-tylko-refaktoring/</link>
		<comments>http://web-design.net.pl/blog/2009/04/nie-tylko-refaktoring/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 20:15:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Bez kategorii]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/blog/?p=73</guid>
		<description><![CDATA[Polecam ciekawą lekturę Mariusza Sieraczkiewicza o refactoringu, pisaniu ładnego, czytelnego kodu - &#8220;i nie tylko&#8221;: http://www.bnsit.pl/files/nie_tylko_refaktoring.pdf
]]></description>
			<content:encoded><![CDATA[<p>Polecam ciekawą lekturę Mariusza Sieraczkiewicza o refactoringu, pisaniu ładnego, czytelnego kodu - &#8220;i nie tylko&#8221;: <a href="http://www.bnsit.pl/files/nie_tylko_refaktoring.pdf">http://www.bnsit.pl/files/nie_tylko_refaktoring.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/04/nie-tylko-refaktoring/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cechy dobrego projektu - 2. Oszczędność (KISS, DRY)</title>
		<link>http://web-design.net.pl/blog/2009/04/dobry-projekt-2-oszczednosc-kiss-dry/</link>
		<comments>http://web-design.net.pl/blog/2009/04/dobry-projekt-2-oszczednosc-kiss-dry/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 23:49:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cechy dobrego projektu]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/?p=29</guid>
		<description><![CDATA[„Książka jest skończona nie wtedy, gdy nie można do niej nic dodać, ale wtedy gdy nie można z niej nic usunąć”.
Nie komplikuj kodu (zasada KISS - z ang. Keep It Simple, Stupid). Staraj się zaprojektować możliwie prostą strukturę aplikacji. Unikaj niepotrzebnych elementów. 
Dbaj o dobrą hermetyzację klas. Używaj najbardziej restrykcyjnych modyfikatorów dostępu do właściwości klas, [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>„Książka jest skończona nie wtedy, gdy nie można do niej nic dodać, ale wtedy gdy nie można z niej nic usunąć”.</p></blockquote>
<p><strong>Nie komplikuj kodu</strong> (zasada <a href="http://pl.wikipedia.org/wiki/KISS_(regu%C5%82a)">KISS </a>- z ang. Keep It Simple, Stupid). Staraj się zaprojektować możliwie prostą strukturę aplikacji. Unikaj niepotrzebnych elementów. </p>
<p>Dbaj o dobrą <a href="http://pl.wikipedia.org/wiki/Enkapsulacja">hermetyzację</a> klas. Używaj najbardziej restrykcyjnych modyfikatorów dostępu do właściwości klas, na ile to możliwe (private, protected).</p>
<p>Zamiast używać wielu podobnych mechanizmów, spróbuj zaprojektować jeden, którego będziesz mógł użyć w każdym wypadku.</p>
<p>Gdy coś napiszesz, zastanów się, czy nie dałoby się tego zapisać prościej. </p>
<p>Nawet w tak banalnym przykładzie (PHP):</p>
<pre>
if( $condition ) {
    return true;
} else {
   return false;
}
</pre>
<p>warto się zastanowić - czy nie lepiej użyć prostszego zapisu, np tak:</p>
<pre>return ( bool ) $condition;</pre>
</p>
<p><strong>Nie powtarzaj się</strong> (zasada <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>- Dont&#8217; Repeat Yourself). &#8220;kopiuj i wklej&#8221; to operacja, której trzeba się wystrzegać pisania kodu. Jeżeli kusi Cię możliwość szybkiego skopiowania kodu z innego fragmentu projektu, pomyśl o przeniesieniu go do osobnej funkcji, klasy bazowej.</p>
<p>Reguła <a href="http://en.wikipedia.org/wiki/Rule_of_three_(programming)">Rule Of Three</a> dopuszcza co prawda jednokrotne skopiowanie kodu, ale trzeci raz nie powinno kopiować się powielać tego samego kodu.</p>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/04/dobry-projekt-2-oszczednosc-kiss-dry/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cechy dobrego projektu - 1. Czytelność</title>
		<link>http://web-design.net.pl/blog/2009/04/dobry-projekt-1-zrozumialosc/</link>
		<comments>http://web-design.net.pl/blog/2009/04/dobry-projekt-1-zrozumialosc/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 23:48:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cechy dobrego projektu]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/?p=27</guid>
		<description><![CDATA[Tworząc kod pamiętaj o tym, że w przyszłości Ty sam lub inny programista będzie chciał go zrozumieć. Warto również pamiętać, że w projektach informatycznych przyszłość nadchodzi szybciej niż nam się wydaje  

Dlatego:
Korzystaj ze sprawdzonych, uniwersalnych schematów.
Unikaj programistycznej prowizorki, rozwiązań tymczasowych, obejść &#8220;na skróty&#8221; (tzw. workaround).
Trzymaj się ustalonych, jednolitych standardów kodowania i nazewnictwa (np. nazwy [...]]]></description>
			<content:encoded><![CDATA[<p>Tworząc kod pamiętaj o tym, że w przyszłości Ty sam lub inny programista będzie chciał go zrozumieć. Warto również pamiętać, że w projektach informatycznych <em>przyszłość nadchodzi szybciej niż nam się wydaje</em> <img src='http://web-design.net.pl/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>
Dlatego:</p>
<p><strong>Korzystaj ze sprawdzonych, uniwersalnych schematów</strong>.</p>
<p><strong>Unikaj programistycznej prowizorki</strong>, rozwiązań tymczasowych, obejść &#8220;na skróty&#8221; (tzw. <a href="http://en.wikipedia.org/wiki/Workaround">workaround</a>).</p>
<p>Trzymaj się ustalonych, <strong>jednolitych standardów kodowania i nazewnictwa</strong> (np. nazwy klasy z dużej litery, prywatne składowe poprzedzane podkreśleniem &#8220;_&#8221;, nazwy interfejsów od litery I).</p>
<p>Pisz <strong>samodokumentujący</strong> się kod, dbaj o komentarze na etapie <strong>tworzenia kodu.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/04/dobry-projekt-1-zrozumialosc/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cechy dobrego projektu</title>
		<link>http://web-design.net.pl/blog/2009/04/cechy-dobrego-projektu/</link>
		<comments>http://web-design.net.pl/blog/2009/04/cechy-dobrego-projektu/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 21:18:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Bez kategorii]]></category>

		<category><![CDATA[Cechy dobrego projektu]]></category>

		<guid isPermaLink="false">http://web-design.net.pl/?p=3</guid>
		<description><![CDATA[Próbowałeś wielokrotnie wykorzystać swój kod? Gdy projekt rozrastał, miałeś ochotę napisać wszystko od początku?
Jeżeli tak, to być może znajdziesz na tym blogu coś dla siebie.
Na studiach uczono nas o &#8220;cechach dobrego projektu&#8221; - było to kilka prostych reguł nie popartych przykładami. Dopiero podczas pracy przy komercyjnych projektach te proste regułki okazały się &#8220;żelaznymi&#8221; zasadami. Nie [...]]]></description>
			<content:encoded><![CDATA[<p>Próbowałeś wielokrotnie wykorzystać swój kod? Gdy projekt rozrastał, miałeś ochotę napisać wszystko od początku?<br />
Jeżeli tak, to być może znajdziesz na tym blogu coś dla siebie.</p>
<p>Na studiach uczono nas o &#8220;<strong>cechach dobrego projektu</strong>&#8221; - było to kilka prostych reguł nie popartych przykładami. Dopiero podczas pracy przy komercyjnych projektach te proste regułki okazały się &#8220;żelaznymi&#8221; zasadami. Nie stosowanie się do nich wiąże się z trudnościami w rozwijaniu i utrzymaniu projektu.</p>
<p>Będzie trochę o zasadach i o sprawdzonych praktykach w inżynierii oprogramowania (w szczególności aplikacji webowych). Jeżeli o czymś będę pisał, to na podstawie własnych doświadczeń. Staram się popierać teorię mniej lub bardziej sensownymi przykładami.</p>
]]></content:encoded>
			<wfw:commentRss>http://web-design.net.pl/blog/2009/04/cechy-dobrego-projektu/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

