Sākums / Programmēšana / Model-View-Controller arhitektūras principi (2. daļa)

10. septembris, 2010 | RSS

Model-View-Controller arhitektūras principi (2. daļa)

10. janvāris, 2010 | Nav komentāru | Programmēšana

Ar šo rakstu centīšos parādīt to, kā iepriekš apskatīto kodu būtu iespējams sadalīt pēc Model View Controller arhitektūras principiem. Veidi kā to izdarīt ir dažādi un katra ietvara (framework) MVC realizācija var atšķirties. Šis konkrētais piemērs būs uz manis izstrādātā PHP ietvara balstīts.

/public_html

Publiski pieejamais kods (css, bildes, javascript faili u.tml.)

/private

Php faili, kuros atrodas kods, kas veic pašas aplikācijas pieprasījumu apstrādi un izpildi, datu atlasīšanu no datu bāzes u.tml.

/public_html/index.php

Lielākoties PHP MVC ietvaros tiek lietots Frontend pattern arhitektūra, t.i. kad visi pieprasījumi tiek apstrādāti centralizēti. Tā arī šeit ir realizēts, tas, ka katrs pieprasījums izsauc index.php failu, no kura tālāk jau tiek izsaukta attiecīgās ietvara klases un metodes, kas veic pieprasījuma apstrādi un atbilstošās Controller klases un metodes atrašanu.

$c = new Framework_Bootstrap();
$c->route();

Bez augstāk esošā koda, vēl arī index.php failā tiek definēti ceļi uz aplikācijas komponentēm.

/public_html/.htaccess

Lai varētu nodrošināt to, ka katrs pieprasījums tiek veikts caur index.php failu, .htaccess failā  ir jāieraksta sekojošais:

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css|swn|html|xml|txt|swf)$ index.php

/private/library

Atrodas ietvara klašu faili, kā arī 3rd party klašu bibliotēkas, piemēram, bilžu apstrādes klase, PDF ģenerēšanas klašu bibliotēka u.c.

/private/config/db.php

Datu bāzes konfigurācijas fails.

<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'user');
define('DB_PSW', 'psw');
define('DB_NAME', 'databasename');
?>

/private/app/models

Atrodas klases, kas veic darbības ar datu bāzi (Model slānis). Katrai datu bāzes tabulai parasti tiek izveidota viena atsevišķa Model klase, piemēram, šinī gadījumā tas ir Product.php.

<?php
class Product extends Framework_Db
{
private $_table = 'product';
private $_pk = 'productId';

function getAll(){
$query  = "SELECT * FROM $this->_table";
return $this->selectAll($query);
}

function insert($productName){
$data = array(
'productName' => $productName
);
return parent::insert($this->_table, $data);
}
}
?>

Kā redzams piemērā iepriekšējo datu bāzes vaicājumu

SELECT * FROM product

esam pārvietojuši atsevišķā Model klases metodē, kas pēc tam dos iespēju to izsaukt pēc vajadzības, nepārrakstot vairākkārtīgi pašu datu bāzes vaicājumu. Tāpat arī šeit tiek likti visi pārējie datu bāzes vaicājumi, kas attiecas uz datu bāzes tabulu product, piemēram, metode insert($productName). Klase Product tiek paplašināta ar ietvara klasi Framework_Db, kas nodrošinās sql vaicājumu sagatavošanu un datu atgriešanu no datu bāzes.

/private/app/backend

Satura pārvaldības sistēma (CMS), kas ir atsevišķi atdalīta no lapas apmeklētājiem publiski pieejamās daļas, piemēram, atrodas subdomēnā cms.mansdomens.lv. Šāda pieeja ļauj izstrādāt no lapas apmeklētājiem publiski pieejamās lapas satura, atdalītu sistēmu, bet tomēr atļaujot kopīgi izmantot Model klases, piemēram, datu ievietošana tabulā product, var būt nepieciešama, gan lapas lietotājiem, gan lapas administratoram, kas rediģē aplikācijas datu bāzi speciāli izveidotā cms sistēmā.

/private/app/frontend

Publiski pieejamā sadaļa. Tā kā zem frontend un backend esošā failu struktūra ir līdzīga, tad tālāk apskatīsim tikai frontend sadaļu.

/private/app/frontend/layouts

Atrodas view slāņa layout faili, kuri kalpo kā pamata html šablons, kurā noteiktās vietās tiek pievienots mainīgais lapas saturs.

/private/app/frontend/layouts/index.phtml

</pre>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Paraugs</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
 <?=$this->layout['center']?>
</body>
</html>

<?=$this->layout['center']?> vietā tiek ievietots konkrētā piepasījuma view fails, kuru apskatīsim vēlāk.

/private/app/frontend/modules

Tā kā tiek veidota modulāra aplikācija, tad tiek veidoti moduļi, kas katrs sevī var saturēt vairākas Controller un View komponentes.

/private/app/frontend/modules/product/controllers

Product moduļa Controller slānis.

/private/app/frontend/modules/product/controllers/PrintController.php

Product moduļa Controller klase.

<?php
class Product_PrintController extends Framework_Controller {
 function indexAction(){
 require_once PATH_TO_MODELS.'Product.php';
 $o_product = new Product();
 $this->view['product'] = $o_product->getAll();
 $this->layout['center'] = $this->render('index');
 $this->layout();
 }
}
?>

Web aplikācijas adrese, lai izsauktu product moduļa PrintController klases indexAction() metodi, būs mansdomens.lv/product/print vai mansdomens.lv/product/print/index.

Kā redzams PrintController klases indexAction() metodē, tad tiek izsaukta Model slāņa Product klases metode getAll(), kas atgriež masīvā visu produktu sarakstu un šis masīvs tiek noglabāts mainīgajā $this->view['product'], kura vērtībām pēc tam varēs piekļūt view slāņa failos.

Metode $this->render(‘index’); ģenerē attiecīgā Controller, attiecīgās Action metodes view failu (/private/app/frontend/modules/product/views/print/index.phtml).

$this->layout(); izsauc /private/app/frontend/layouts/index.phtml failu, kurā tiek ierakstīts $this->layout['center'] esošā view faila vērtība, līdz ar to iegūstot gatavu html lapu, kas ir redzama lietotājam.

/private/app/frontend/modules/product/views/print/index.phtml

Product moduļa View slāņa fails. Šeit tiek likts html izejas kods, kas tiek iekļauts layouts html failos.

<table>
<tr>
<th>produkts</th>
<?
foreach($this->view['product'] as $row) {?>
 <tr><td><?=$row['productName']?></td></tr>
<? }?>
</tr>
</table>

Šīs ir tikai viens no veidiem, kā varētu realizēt Model View Controller arhitektūru. Lai iegūtu labāku priekšstatu par šo tik izplatīto arhitektūru, iesaku pašiem praktiski pamēģināt vairākus piemērus, lai izprasto šo tēmu labāk:

Komentēt 590 skatījumi, 1 no tiem šodien |

Komentēt

Virszemes TV