<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Tag design</title>
    <link>http://blog.zabiello.com/articles/tag/design</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Szablony i wzorzec MVC</title>
      <description>&lt;h2&gt;Wzorzec &lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://pl.wikipedia.org/wiki/MVC"&gt;&lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/a&gt; to skr&#243;t od ang. Model &amp;#8211; View &amp;#8211; Controler (czyli Model &amp;#8211; Widok &amp;#8211; Kontroler). Jest to jeden z popularniejszych &lt;a href="http://pl.wikipedia.org/wiki/Wzorzec_projektowy_%28informatyka%29"&gt;wzorc&#243;w projektowych&lt;/a&gt; (czy &amp;#8220;wzorc&#243;w architektonicznych w oprogramowaniu&amp;#8221; jak si&#281; mog&#261; czepia&#263; niekt&#243;rzy pury&#347;ci) W uproszczeniu, wzorce projektowe to standardowe, sprawdzone rozwi&#261;zania dla typowych problem&#243;w programistycznych (g&#322;&#243;wnie dotycz&#261; programowania obiektowego). Ich przeciwie&#324;stwem s&#261; &lt;a href="http://pl.wikipedia.org/wiki/Antywzorce"&gt;anty-wzorce&lt;/a&gt;, czyli to, jak nie nale&#380;y programowa&#263;. Typowym antywzorcem jest &lt;em&gt;spaghetti-code&lt;/em&gt;, wymieszanie logiki biznesowej z warstw&#261; prezentacji, wszystkiego razem w jednym &#347;mietniku. To typowy styl programowania wi&#281;kszo&#347;ci niedo&#347;wiadczonych programist&#243;w &lt;span class="caps"&gt;PHP&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;W skr&#243;cie, wzorzec &lt;span class="caps"&gt;MVC&lt;/span&gt; polega na takim podziale kodu, aby sk&#322;ada&#322; si&#281; z trzech, funkcjonalnie oddzielnych cz&#281;&#347;ci.&lt;/p&gt;


	&lt;h3&gt;Model&lt;/h3&gt;


	&lt;p&gt;Modelem nazywamy t&#261; cz&#281;&#347;&#263; kodu aplikacji, kt&#243;ra jest odpowiedzialna za kontakt z danymi biznesowymi, gdziekolwiek s&#261; sk&#322;adowane (zwykle w relacyjnej bazie danych). Model nie tylko s&#322;u&#380;y do pobierania i modyfikacji danych biznesowych, ale tak&#380;e zajmuje si&#281; ich sp&#243;jno&#347;ci&#261; i integralno&#347;ci&#261; poprzez odpowiednie mechanizmy walidacji danych. Model s&#322;u&#380;y wi&#281;c za zar&#243;wno stra&#380;nika jak i dysponenta danych biznesowych. Bardzo elegancko wida&#263; to w &lt;a href="http://rubyonrails.pl"&gt;Ruby on Rails&lt;/a&gt; gdzie przyk&#322;adowy kod pe&#322;ni&#261;cy rol&#281; modelu wygl&#261;da&#263; mo&#380;e tak:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Project&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;belongs_to&lt;/span&gt; &lt;span class="symbol"&gt;:portfolio&lt;/span&gt;
  &lt;span class="ident"&gt;has_one&lt;/span&gt; &lt;span class="symbol"&gt;:project_manager&lt;/span&gt;
  &lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:milestones&lt;/span&gt;
  &lt;span class="ident"&gt;has_many&lt;/span&gt; &lt;span class="symbol"&gt;:deliverables&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:through&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:milestones&lt;/span&gt;

  &lt;span class="ident"&gt;validates_presence_of&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:description&lt;/span&gt;
  &lt;span class="ident"&gt;validates_acceptance_of&lt;/span&gt; &lt;span class="symbol"&gt;:non_disclosure_agreement&lt;/span&gt;
  &lt;span class="ident"&gt;validates_uniqueness_of&lt;/span&gt; &lt;span class="symbol"&gt;:short_name&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Widok&lt;/h3&gt;


	&lt;p&gt;Widok s&#322;u&#380;y do generowania tego, co mogliby&#347;my okre&#347;li&#263; jako prezentacj&#281; naszej aplikacji. Przy czym nie jest okre&#347;lone jak ta prezentacja ma wygl&#261;da&#263;. Og&#243;lnie prezentacj&#261; jest to wszystko, co aplikacja &amp;#8220;wypluwa&amp;#8221; na zewn&#261;trz. Nie musi to by&#263; &#380;aden &amp;#8220;interfejs u&#380;ytkownika&amp;#8221; jak wypisuj&#261; bzdury co niekt&#243;rzy. Model &lt;span class="caps"&gt;MVC&lt;/span&gt; nie zak&#322;ada przecie&#380; tego, kto ma by&#263; &lt;em&gt;odbiornikiem&lt;/em&gt;  wysy&#322;anego strumiena danych. Mo&#380;e to by&#263; zar&#243;wno pani Genowefa miotaj&#261;ca si&#281; po internecie za pomoc&#261; Internet Explodera jak i rozbudowany czytnik kana&#322;&#243;w &lt;span class="caps"&gt;RSS&lt;/span&gt;, albo jakie&#347; dowolne urz&#261;dzenie odbieraj&#261;ce generowany strumie&#324; danych (w tym ostatnim wypadku nie musi to by&#263; w og&#243;le aplikacja webowa) Generowany strumie&#324; danych nie musi by&#263; w og&#243;le &#380;adnym tekstem. Mog&#261; to by&#263; bowiem r&#243;wnie dobrze strumie&#324; danych binarnych.&lt;/p&gt;


	&lt;p&gt;Zreszt&#261; tak w&#322;a&#347;nie dzia&#322;aj&#261; aplikacje webowe, kt&#243;re dzia&#322;aj&#261; wg zasady client-server. Tzn. klient wysy&#322;a &#380;&#261;danie, a serwer odpowiada. Przegl&#261;darka Iinternetowa wysy&#322;a &#380;&#261;danie do serwera &lt;span class="caps"&gt;WWW&lt;/span&gt;, a on odpowiada jej strumieniem danych. (w wypadku aplikacji webowych serwer wysy&#322;a wpierw tekst z nag&#322;&#243;wkiem informuj&#261;cym co b&#281;dzie wysy&#322;ane, bo to wynika z zasad protoko&#322;u &lt;a href="http://pl.wikipedia.org/wiki/HTTP"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;BTW&lt;/span&gt;, z tego wynika wa&#380;na lekcja odno&#347;nie adres&#243;w &lt;a href="http://pl.wikipedia.org/wiki/URL_%28informatyka%29"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/a&gt;. To co wklepujemy w przegl&#261;darce nie musi mie&#263; &#380;adnego zwi&#261;zku z jakimikolwiek &#347;cie&#380;kami na serwerze. Wszystkie technologie, u&#380;ywaj&#261;ce jawnych rozszerze&#324; plik&#243;w (.asp, .php, .jsp, .aspx itp) s&#261; g&#322;upie, bo po pierwsze, sugeruj&#261; &#380;e to co&#347; w adresie z ko&#324;c&#243;wk&#261; .php to zawsze jest konkretny plik po konkretnym katalogu. Po drugie, bez sensu eksponuj&#261; u&#380;yt&#261; technologi&#281;, co wi&#261;&#380;e troch&#281; r&#281;ce tym, kt&#243;rzy by chcieli zmieni&#263; wewnetrzny system generuj&#261;cy strony &lt;span class="caps"&gt;WWW&lt;/span&gt; ale bez ruszania starych adres&#243;w &lt;span class="caps"&gt;URL&lt;/span&gt;. Po trzecie, spidery takie jak Google nie lubi&#261; indeksowa&#263; stron generowanych dynamiczne. Je&#347;li zobacz&#261; w adresie znak zapytania to najcz&#281;&#347;ciej to, co za nim stoi jest ignorowane. Odbija sie to na &amp;#8220;pozycjonowaniu&amp;#8221; tak napisanej aplikacji. I po czwarte takie adresy (z rozszerzeniami i parametrami po znaku zapytania) s&#261; najzwyczajniej brzydkie i trudne do zapami&#281;tania. Nie znaczy to, &#380;e tak (/?x=1&amp;#38;y=2&amp;#38;z=4)w og&#243;le nie przekazywa&#263; parametr&#243;w. Chodzi tylko o to, aby to robi&#263; to oszcz&#281;dnie i tylko wtedy, kiedy jest to naprawd&#281; koniecznie.&lt;/p&gt;


	&lt;h3&gt;Kontroler&lt;/h3&gt;


	&lt;p&gt;Kod, kt&#243;ry spina wszystko razem i stanowi serce aplikacji to kontroler. To on pobiera dane z bazy za pomoc&#261; modelu i to on wybrane dane wysy&#322;a do widoku aby je jako&#347; zaprezentowa&#322; dla odbiorcy. Kontroler tak&#380;e dba o takie kwestie jak autoryzacja i autentykacja u&#380;ytkownik&#243;w (okre&#347;la kto mo&#380;e mie&#263; dost&#281;p do poszczeg&#243;lnych cz&#281;&#347;ci aplikacji). Kontroler zajmuje si&#281; te&#380; sposobem przep&#322;ywu danych zgodnie z potrzebami logiki biznesowej.&lt;/p&gt;


	&lt;h2&gt;Szablony i Helpery&lt;/h2&gt;


	&lt;p&gt;Czym s&#261; szablony? Szablony przynale&#380;&#261; do warstwy Widoku wzorca &lt;span class="caps"&gt;MVC&lt;/span&gt;. Otrzymuj&#261; dane z kontrolera i na tej podstawie generuj&#261; kod &lt;span class="caps"&gt;HTML&lt;/span&gt; jaki jest wysy&#322;any do przegl&#261;darki. Szablony powinny by&#263; raczej proste tak, aby mo&#380;na by&#322;o &#322;atwo modyfikowa&#263; spos&#243;b prezentacji bez godzin &#347;l&#281;czenia nad kodem. Najcz&#281;&#347;ciej kwesti&#261; prezentacji zajmuj&#261; si&#281; r&#243;&#380;nej ma&#347;ci webmasterzy i designerzy, czyli og&#243;lniej osoby, kt&#243;re niekoniecznie s&#261; zaawansowanymi programistami.&lt;/p&gt;


	&lt;p&gt;W wypadku kiedy spos&#243;b prezentacji jest z&#322;o&#380;ony, aby nie komplikowa&#263; szablonu stosuje si&#281; do pomocy&amp;#8230; pomocnika ;) G&#322;&#243;wnym zadaniem helpera jest takie wstepne przetworzenie danych (jakie kontroler wrzuci&#322; do szablonu) aby szablon mog&#261;cy je wy&#347;wietli&#263; by&#322; jak najprostszy i jak najbardziej czytelny. Helper dane pobiera od szablonu, modyfikuje je i odsy&#322;a je z powrotem. Dzi&#281;ki temu logika niezb&#281;dna do wygenerowania prezentacji jest w szablonie znacznie uproszczona.&lt;/p&gt;


	&lt;p&gt;Szablony mo&#380;na podzieli&#263; na kilka rodzaj&#243;w, stosownie do oczekiwanych od nich funkcji. Ale o tym (i o strategii wyboru w&#322;a&#347;ciwych szablon&#243;w) ju&#380; w &lt;a href="http://blog.zabiello.com/articles/2007/01/06/templates-and-mvc-2"&gt;drugiej cz&#281;&#347;ci&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 03 Jan 2007 20:30:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:24eef7ec-0037-4de2-b03c-eb6582b028a8</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/03/templates-and-mvc</link>
      <category>mvc</category>
      <category>templates</category>
      <category>design</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
