<?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>webbricks &#187; element</title>
	<atom:link href="http://blog.grzegorzpawlik.com/tag/element/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.grzegorzpawlik.com</link>
	<description>Doświadczenie, to coś, co zdobywamy tuż po chwili w której było nam potrzebne ...</description>
	<lastBuildDate>Tue, 07 Feb 2012 10:09:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Dług techniczny &#8211; przykład z życia wzięty</title>
		<link>http://blog.grzegorzpawlik.com/2010/03/dlug-techniczny-przyklad-z-zycia-wziety/</link>
		<comments>http://blog.grzegorzpawlik.com/2010/03/dlug-techniczny-przyklad-z-zycia-wziety/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 11:24:22 +0000</pubDate>
		<dc:creator>Greg</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[DRY]]></category>
		<category><![CDATA[dług techniczny]]></category>
		<category><![CDATA[element]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[View]]></category>

		<guid isPermaLink="false">http://blog.grzegorzpawlik.com/?p=867</guid>
		<description><![CDATA[Można się spierać co jest długiem technicznym, a co nie jest. Chciałbym Wam pokazać przykład kodu, który świetnie nadaje się do zobrazowania problemu. Problem: Na jeden ze stron jest wyszukiwarka- formularz, w którym po wpisaniu danych w inputach i selectach &#8230; <a href="http://blog.grzegorzpawlik.com/2010/03/dlug-techniczny-przyklad-z-zycia-wziety/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Można się spierać co jest długiem technicznym, a co nie jest. Chciałbym Wam pokazać przykład kodu, który świetnie nadaje się do zobrazowania problemu.</p>
<p><strong>Problem:</strong><br />
Na jeden ze stron jest wyszukiwarka- formularz, w którym po wpisaniu danych w inputach i selectach przesyła te dane jako parametry &#8220;named&#8221;, np.:<br />
example.com/controller/action/field1:value1/field2:value2<br />
Potrzebny jest kawałek kodu javascript, który wygeneruje odpowiedni link i wywoła ten adres</p>
<p><strong>Rozwiązanie 1:</strong></p>
<pre name="code" class="javascript">
function submitform()
{
    form = document.getElementById('car_form');
    name = form.elements["CarName"].value;
    registration_number = form.elements["CarRegistrationNumber"].value;
    entry = document.getElementById('CarEntry').value
    driver = document.getElementById('CarDriver').value
    linkForm = '<?php echo $html->url('/cars/find/')?>';
    location = linkForm+'name:'+name+'/registration_number:'+registration_number+'/entry:'+entry+'/driver:'+driver;
    document.forms["car_form"].action = location;
}
</pre>
<p>Jest ono poprawne. Warto się zastanowić, czy został w tym przypadku zaciągnięty dług techniczny? Na pewno będą tacy,  którzy od razu będą wiedzieć co z tym kodem jest nie tak. Inni będą to czuli w kościach. Resztę pocieszę mówiąc, że ta umiejętność przychodzi z czasem pod warunkiem, że chcesz się uczyć jak pisać dobry kod.</p>
<p>Ten formularz wisi sobie gdzieś w jakimś panelu admina w listingu samochodów. Jednak taka wyszukiwarka jest potrzebna też przy listingu kierowców. Oczywiście kopiujesz rozwiązanie i poprawiasz je do nowych warunków. Nie ma w tym nic złego pod warunkiem, że robisz to z odpowiednim nastawieniem: &#8220;kopiuję kod, żeby móc zauważyć części wspólne i przeprowadzić refactoring&#8221; (czasem łatwiej mieć dwa dublujące się elementy i na ich podstawie tworzyć uniwersalny element/funkcje niż wymyślać ją od zera). </p>
<p>No i zabierając się za refactoring &#8211; w tym wypadku chciałbym zbudować wspólny element (dla tych co raczej siedzą w RoR &#8211; partial), który wywołam sobie tam, gdzie potrzebuję &#8211; zaczynam widzieć, że teraz oto przyjdzie mi spłacić ów mistyczny dług techniczny. Na czym on polega? Otóż w moim przykładzie funkcja budująca url jest strasznie &#8220;sztywna&#8221;. Działa w tym i tylko w tym przypadku. Nie ma najmniejszych znamion uniwersalności. Dlatego teraz, zanim zacznę myśleć o elemencie, muszę tą funkcję przebudować na bardziej uniwersalną. Co to znaczy?</p>
<p>Powinna być w stanie złapać wszystkie inputy i selecty, które są istotne przy budowaniu url&#8217;a i iterując po nich sprytnie go zbudować. Mogła by wyglądać na przykład tak:</p>
<p><strong>Rowziązanie 2:</strong></p>
<pre name="code" class="javascript">
function submitform(){
    var params = "";

    $("#car_form input[type!=submit][name!=_method], #car_form select").each(
    	    function(index,element) {
        	    params +=
        	    		  element.name.substr(
        	    				  element.name.lastIndexOf("[")
        	    		  ).slice(1, -1)+
        	    		  ":"+
        	    		  element.value+
        	    		  "/";
    	    }
    );
    window.location.href = '<?php echo $html->url('/cars/find/')?>' + params;
    return false;
}
</pre>
<p>Teraz inputy i selecty są zbierane bardziej automatycznie ("#car_form input[type!=submit][name!=_method], #car_form select"), a nazwy parametrów są brane z parametru name tych inputów i selectów. Dzięki temu powinna działać dla każdego formularza. Mniejsza o szczegóły.</p>
<p>Jednak rozwiązanie 1 nie było złe. Było wręcz idealne (bo proste i zrozumiałe) tak długo, jak było potrzebne w jednym miejscu. Rozwiązanie 2 mogło zająć przynajmniej 4 razy tyle czasu co pierwsze. Dlatego dopóki nie było powtórzeń kodu - było dobre. Dług techniczny nie istniał. Jednak pojawił się w momencie, kiedy zacząłem refaktoring kodu. </p>
<p>Jak to możliwe, że dług techniczny pojawił się w momencie, kiedy zacząłem go "spłacać"?<br />
Czy istniał cały czas i był ukryty, a ja go nagle odkryłem?</p>
<p>Odpowiem na to pytanie nie wprost: Dług techniczny jest tylko pojęciem umożliwiającym zrozumienie ludziom, kŧórzy nie są programistami, dlaczego nie wolno im zachęcać programistów do chodzenia na skróty. Uzmysławia też (mam nadzieję) niedoświadczonym programistom jakie są niebezpieczeństwa związane z chodzeniem na skróty.</p>
<p><del datetime="2010-03-20T10:48:45+00:00">Leniwy</del> <a href="/?p=29">Dobry</a>, doświadczony programista w ogóle nie musi zagłębiać się w szczegóły czy dług techniczny istnieje, czy nie. <strong>Po prostu tworzy dobry kod</strong>.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.grzegorzpawlik.com/2010/03/dlug-techniczny-przyklad-z-zycia-wziety/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Skróć swoje listingi</title>
		<link>http://blog.grzegorzpawlik.com/2010/02/skroc-swoje-listingi/</link>
		<comments>http://blog.grzegorzpawlik.com/2010/02/skroc-swoje-listingi/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 17:00:48 +0000</pubDate>
		<dc:creator>Greg</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Inne]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[CakePHP 1.2]]></category>
		<category><![CDATA[DRY]]></category>
		<category><![CDATA[element]]></category>

		<guid isPermaLink="false">http://blog.grzegorzpawlik.com/?p=615</guid>
		<description><![CDATA[Pewnie w niemal każdym swoim widoku index.ctp masz fragment kodu podobny do tego: &#60;?php $i = 0; foreach ($tracks as $track): $class = null; if ($i++ % 2 == 0) { $class = ' class="altrow"'; } ?&#62; &#60;tr&#60;?php echo $class;?&#62;&#62; &#8230; <a href="http://blog.grzegorzpawlik.com/2010/02/skroc-swoje-listingi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Pewnie w niemal każdym swoim widoku index.ctp masz fragment kodu podobny do tego:</p>
<pre name="code" class="php">
&lt;?php
$i = 0;
foreach ($tracks as $track):
	$class = null;
	if ($i++ % 2 == 0) {
		$class = ' class="altrow"';
	}
?&gt;
	&lt;tr&lt;?php echo $class;?&gt;&gt;
		&lt;td&gt;
			&lt;?php echo $track['Track']['id']; ?&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;?php echo $track['Track']['name']; ?&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;?php echo $track['Car']['name']; ?&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;?php echo $track['Track']['begin']; ?&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;?php echo $track['Track']['end']; ?&gt;
		&lt;/td&gt;
		&lt;td&gt;
			&lt;?php echo $track['Track']['length']; ?&gt;
		&lt;/td&gt;
		&lt;td class="actions"&gt;
			&lt;?php echo $html-&gt;link(
			   __('Edycja', true),
			   array(
			      'action' =&gt; 'edit',
			      $track['Track']['id'] ,
			      $track['Car']['id']
			   )
			  );
			?&gt;

		&lt;/td&gt;
	&lt;/tr&gt;
&lt;?php endforeach; ?&gt;
&lt;/table&gt;
</pre>
<p>Chce Ci się pisać ten kod kilkadziesiąt razy w jednym projekcie? Mnie też nie. Dlatego napisałem prosty element, który to trochę automatyzuje (nazwałem go &#8220;list&#8221;):</p>
<pre name="code" class="php">
// app/views/elements/list.ctp
&lt;?php
   $i = 0;
   foreach($elements as $key =&gt; $element):
   $class = null;
   if ($i++ % 2 == 0) {
      $class = ' class="altrow"';
   }
?&gt;
   &lt;tr &lt;?php echo $class?&gt;&gt;
      &lt;?php foreach($fields as $path): ?&gt;
         &lt;td&gt;
            &lt;?php echo Set::classicExtract($element, $path) ?&gt;
         &lt;/td&gt;
      &lt;?php endforeach; ?&gt;
         &lt;?php if(isset($links)): ?&gt;
            &lt;td&gt;
               &lt;?php foreach($links as $name =&gt; $url): ?&gt;
                  &lt;?php
                     if(!is_array($url["params"])) {
                        $url["params"] = array($url["params"]);
                     }
                     foreach($url["params"] as $key =&gt; $path){
                        $url[$key] = Set::classicExtract(
                           $element,
                           $path
                        );
                     }
                     unset($url["params"]);
                  ?&gt;
                  &lt;?php echo $html-&gt;link($name, $url)?&gt;
               &lt;?php endforeach; ?&gt;
            &lt;/td&gt;
         &lt;?php endif; ?&gt;
   &lt;/tr&gt;
&lt;?php endforeach; ?&gt;
</pre>
<p>Jego użycie jest dość proste. Dla przykładu wygenerujemy ten sam &#8220;output&#8221; dla pierwszego listingu z tego postu:</p>
<pre name="code" class="php">
echo $this->renderElement(
         "list",
         array(
            "elements" => $tracks,
            "fields" => array(
               "Track.name", "Car.name", "Track.begin",
               "Track.end", "Track.length"
            ),
            "links"=> array(
               "edycja" => array(
                  "controller"=> "tracks", "action"=> "edit",
                  "params" => array(
                     "Track.id", "Car.id"
                  )
               )
            )
         )
      )
</pre>
<p>Opiszę poszczególne parametry przekazywane do tego elementu:</p>
<ul>
<li>&#8220;elements&#8221; &#8211; kolekcja (w tym wypadku tablica) elementów zwrócona na przykład przez $this->Track->find(&#8220;all&#8221;)</li>
<li>&#8220;fields&#8221; &#8211; pola, które mają się pojawić w komórkach tabeli</li>
<li>&#8220;links&#8221; &#8211; tu definiujemy jakie linki mają się pojawić w ostatniej kolumnie (zazwyczaj tam znajdują się &#8220;opcje&#8221;). Indeksy kolejnych elementów to nazwy linków (tutaj &#8220;edycja&#8221;).
<ul>
<li>&#8220;controller&#8221; i &#8220;action&#8221; są identycznie używane jak w metodzie <a href="http://api12.cakephp.org/class/html-helper#method-HtmlHelperlink">HtmlHelper::link()</a></li>
<li>&#8220;params&#8221; jest dość ciekawy. Jeśli chcemy w wygenerowanym linku mieć jeden parametr (najczęściej id), robimy to tak:
<pre name="code" class="php">
            "edycja" => array(
               "controller"=> "cars", "action"=> "edit", "params"=>"Car.id"
            ),
</pre>
<p>gdy parametrów ma być więcej &#8211; ścieżki do nich przekazujemy w tablicy (tak jak w przykładzie):</p>
<pre name="code" class="php">
                "edycja" => array(
                   "controller"=> "tracks", "action"=> "edit",
                   "params" => array(
                      "Track.id", "Car.id"
                   )
                )
</pre>
<p>Można także używać parametrów typu <a href="http://book.cakephp.org/pl/view/541/Named-parameters">&#8220;named&#8221;</a>, wystarczy podać dodatkowo indeksy:</p>
<pre name="code" class="php">
                "edycja" => array(
                   "controller"=> "tracks", "action"=> "edit",
                   "params" => array(
                     "parametr_1"=> "Track.id", "parametr_2"=> "Car.id"
                   )
                )
</pre>
</li>
</ul>
</ul>
<p>Zachęcam do korzystania z tego elementu i zgłaszania wszelkich niedociągnięć :)</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.grzegorzpawlik.com/2010/02/skroc-swoje-listingi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

