Kërkoj falje që në disa vënde përdor terme angleze por thjeshtë për mua është e pamundur ti përkthej apo përshtas ato në shqip!
Metodikat që do ti trajtojmë në këtë mësim janë:
- Çfarë është OOP (Object Orientated Programming)?
- Çfarë është model projektimi (design pattern)?
- Çfarë është një objekt interface?
- Çfarë është dhe si ta përdorim një model përshtatës (Adapter)?
Çfarë është OOP?
Programimi i orientuar në objekte të mundëson kodimin në një mënyrë më të lehtë dhe praktike, gjithashtu të lehtëson mirëmbajten e kodit.
Kjo teknik programimi na mundëson ndarjen e kodimit në pjesë të ndryshme të funksioneve, që na lehtëson lexushëmërinë dhe kuptueshmërinë, dhe në të njëjtën kohë na mundëson ri-përdorimin në programe tjera dhe hap mundësinë për përdorje te projektimit të modeleve (design patterns).
Shumë ngatërrojnë definimin mes një objekti dhe klase! Një klasë është një recetë që përshkruan se çka një objekt është, ka dhe bën. Kurse objekti është vetë instanca e asaj klase.
Shembull:
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | /** |
| 03 | * Kjo është klasa |
| 04 | */ |
| 05 | class Feniksi_Object{ |
| 06 | public $_name; |
| 07 | |
| 08 | public function testim(){ |
| 09 | echo 'testim ...'; |
| 10 | } |
| 11 | } |
| 12 | |
| 13 | /** |
| 14 | * Kurse një objekt është vetë instanca e asaj "klase" |
| 15 | */ |
| 16 | $object = new Feniksi_Object(); |
| 17 | ?> |
Një klasë ofron 3 mënyra deklarimi për metodat dhe variablat e saj:
Public (Publike): Metodat publike të një klase mund të lexohet (përdorën) nga kudo, si nga vetë klasa gjithashtu dhe nga vetë objekti.
Private: Kjo metodë mund të lexohet (përdorët) vetëm brenda vet klasës, e jo përmes objektit e as nga implementimet apo zgjerimet (extends).
Protected (Mbrojtur): Është gati njësoj sikur metoda private por ka dallim pasi që kjo metodë mundëson ta përdorësh dhe nga implementimet dhe zgjerimet (extends) nga klasa të tjera. Por jo direket nga vetë instanca/objekti.
Shembull:
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | class Feniksi_Object{ |
| 03 | public $_public = 'public'; |
| 04 | private $_private = 'private'; |
| 05 | protected $_protected = 'protected'; |
| 06 | |
| 07 | function test(){ |
| 08 | echo $this->_public; |
| 09 | echo $this->_private; |
| 10 | echo $this->_protected; |
| 11 | } |
| 12 | } |
| 13 | $object = new Feniksi_Object(); |
| 14 | |
| 15 | echo $object->_public; // Output: public |
| 16 | echo $object->_private; // Output: Gabim fatal |
| 17 | echo $object->_protected; // Output: Gabim fatal |
| 18 | |
| 19 | $object->test(); //Output: public private protected |
| 20 | |
| 21 | class Feniksi_Object2 extends Feniksi_Object{ |
| 22 | // Ne mundem ti re-deklarojmë metodat publike dhe te mbrojtura por jo ato private! |
| 23 | protected $_protected = 'protected2'; |
| 24 | |
| 25 | function test(){ |
| 26 | echo $this->_public; |
| 27 | echo $this->_private; |
| 28 | echo $this->_protected; |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | $object2 = new Feniksi_Object2(); |
| 33 | |
| 34 | echo $object2->_public; // Output: public |
| 35 | echo $object2->_private; // Output: undefined |
| 36 | echo $object2->_protected; // Output: Gabim fatal |
| 37 | |
| 38 | $object2->test(); //Output: public undefined protected2 |
| 39 | ?> |
Besoj që shembulli ishte i lehtë që të kuptohet prandaj s’kam nevojë të shpjegoj dallimet për çdo rresht! Gjithsesi nqs keni pyetje mos hezitoni, por shkruajini tek komentet!
Çfarë është një model Model projektimi (design pattern)?
Është një zgjidhje e përgjithshme për një problem të zakonshëm qe ndodh ne projektimin e programeve. Një model nuk është i përkryer por thjeshtë është një përshkrim i problemit dhe si ta zgjidhësh atë, jo një zgjidhje e gatshme që ta kopjoni direkt ne kodin tuaj!
Çfarë është objekt interface?
Objekt interface të lejon të vendosësh rregullat për implementimin e një objekti dhe cilat metoda një objekt duhet ti zbatojë dhe t’u përmbahet! Të gjitha metodat e deklaruara në një interface duhen të jenë publike dhe objekti që implementon një interface duhet të implementojë të njëjtat metoda përndryshe do të shfaqet një gabim fatal.
Një shembull në praktikë është të krijojmë një interface për libra dhe çdo libër qe e implementon atë interface duhet të zbatojë ato metoda që ne i vendosim në interface. Shembull:
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | interface Feniksi_Book_Interface{ |
| 03 | public function getAuthor(); |
| 04 | public function getTitle(); |
| 05 | public function setAuthor($author); |
| 06 | public function setTitle($title); |
| 07 | } |
| 08 | |
| 09 | class Feniksi_Book implements Feniksi_Book_Interface{ |
| 10 | protected $_author; |
| 11 | protected $_title; |
| 12 | public function getAuthor(){ |
| 13 | return $this->_author; |
| 14 | } |
| 15 | public function getTitle(){ |
| 16 | return $this->_title; |
| 17 | } |
| 18 | public function setAuthor($author){ |
| 19 | $this->_author = $author; |
| 20 | return $this; |
| 21 | } |
| 22 | |
| 23 | public function setTitle($title){ |
| 24 | $this->_title = $title; |
| 25 | return $this; |
| 26 | } |
| 27 | } |
| 28 | ?> |
Në shembullin më lart shohim në interface që kemi katër metoda/funksione (getAuthor, getTitle, setAuthor, setTitle) dhe atë interface e implementojmë në modelin tonë te quajtur “Feniksi_Book”. Si ç’shihet modeli ka të njëjtat metoda si interface që implementon.
Pse të përdorim objekt interface?
Thjesht sepse i udhëzon të tjerët që të implementojnë metodat e duhura në modelin e tyre! Edhe nëse s’punoni në një ekip, ju udhëzon ju të ndiqni një logjikë të caktuar.
Çfarë është modeli përshtatës (Adapter pattern)?
Modeli përshtatës është një interface e një apo më shumë përshtatësve të ndryshëm! Çfarë është një përshtatës në ketë rast? Të marrim një shembull. Të gjithë e dimë që karikuesit e pajisjeve elektronike janë të ndryshëm në kontinente të ndryshme. Dmth: në Amerikë përdorin sistem tjetër kurse në Evropë përdorim sistem tjetër. Përshtatësi (adapteri) në këtë rast është një karikues universal për karikues të tjerë.
Për të krijuar një model përshtatës, së pari krijojmë një interface. Si ç’thamë më herët, këtë e bëjmë për ti udhëzuar përshtatësit e tjerë të përdorin funksione të njëjta por me logjikë të ndryshme. Në shembullin që do ta marrim më poshtë do të krijojmë një përshtatës databaze me një përshtatës specifik për MySQL duke përdorur PDO_MYSQL extension.
| PHP | | Kopjo Kodin | | ? |
| 1 | <?php |
| 2 | interface Feniksi_Db_Adapter_Interface{ |
| 3 | public function connect(array $array = array()); |
| 4 | public function insert($name, $data); |
| 5 | public function update($name, $data, $where); |
| 6 | public function delete($name, $where); |
| 7 | public function query($query, $bind = array()); |
| 8 | } |
| 9 | ?> |
Ky është interface me disa funksione minimale që çdo përshtatës duhet ti implementojë. Pastaj vazhdojmë me një klasë abstrakte. Këtë e bëjmë për të ndarë ndonjë logjikë programuese te përbashkët mbes adapterave. Dhe patjetër implementojmë interface në të!
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | abstract class Feniksi_Db_Adapter_Abstract implements Feniksi_Db_Adapter_Interface{ |
| 03 | protected $_conn = null; |
| 04 | protected $_options = array(); |
| 05 | |
| 06 | public function connect(array $array = array()){} |
| 07 | public function insert($name, $data){} |
| 08 | public function update($name, $data, $where){} |
| 09 | public function delete($name, $where){} |
| 10 | public function query($query, $bind = array()){} |
| 11 | |
| 12 | public function setOptions(array $options = array()){ |
| 13 | $this->_options = $options; |
| 14 | |
| 15 | return $this; |
| 16 | } |
| 17 | } |
| 18 | ?> |
Një ndër funksionet e përbashkët ne këtë rast është setOptions()! Funksionet tjera janë të implementuara nga interface dhe nuk kanë asnjë logjik programuese ende! Këtë e bëjmë tani në përshtatësin specifik për MySQL.
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | class Feniksi_Db_Adapter_Pdo_Mysql extends Feniksi_Db_Adapter_Abstract { |
| 03 | |
| 04 | public function __construct($options = array()){ |
| 05 | $this->connect($options); |
| 06 | } |
| 07 | |
| 08 | public function connect(array $options = array()){ |
| 09 | if(count($options) > 0){ |
| 10 | $this->setOptions($options); |
| 11 | }elseif(count($this->_options) == 0){ |
| 12 | throw new PDOException('Duhet te vendosni opsionet e duhura!'); |
| 13 | } |
| 14 | |
| 15 | $this->_conn = new PDO('mysql:host=' . $this->_options['host'] . ';dbname=' . $this->_options['dbname'], $this->_options['user'],$this->_options['password']); |
| 16 | } |
| 17 | public function insert($tblName, $data = array()){ |
| 18 | // Logjikë programuese |
| 19 | } |
| 20 | // Funksionet tjera |
| 21 | } |
| 22 | ?> |
Klasa më lart është përshtatësi i cili është specifik për MySQL. Duke e zgjeruar (extends) klasën abstrakte na mundëson ndarjen e kodit në të, gjithashtu implementon funksionet e duhura nga interface. Si ç’e shihni në këtë përshtatës kemi një funksion __construct(); që ndërton një objekt dhe ai pranon një “array” me opsionet e duhura, dhe e vetmja gjë që bën në rastin më lart është të jetë bartës i opsioneve që nga ndërtimi i objektit dhe të thërrasë funksionin connect();. Në këtë të fundit funksion kemi logjikën për lidhjen me databazën sipas PDO_MYSQL extension!
Dhe për fund na nevojitet një klasë për mbajtjen e përshtatësit, që do të funksionojë si interface (hyrje) për përshtatësin tonë. Dmth: përmes kësaj klase në përdorim funksionet dhe logjikën e përshtatësit.
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | class Feniksi_Db{ |
| 03 | protected $_adapter; |
| 04 | public function __constructor(Feniksi_Db_Adapter_Abstract $adapter){ |
| 05 | $this->_adapter = $adapter; |
| 06 | } |
| 07 | |
| 08 | public function getAdapter(){ |
| 09 | return $this->_adapter; |
| 10 | } |
| 11 | } |
| 12 | ?> |
Siç e shihni është një klasë shumë e thjeshtë me një ndërtues (constructer) dhe funksioni tjetër është vetë thirrja/marrja e përshtatësit (adapter-it).
Këtu më poshtë e shikoni se si mund ta përdorni këtë përshtatës:
| PHP | | Kopjo Kodin | | ? |
| 01 | <?php |
| 02 | $db = new Feniksi_Db( |
| 03 | new Feniksi_Db_Adapter_Pdo_Mysql( |
| 04 | array( |
| 05 | 'host' => 'localhost', |
| 06 | 'dbname' => 'feniksi', |
| 07 | 'user' => 'root', |
| 08 | 'password' => 'kodisekret' |
| 09 | ) |
| 10 | ) |
| 11 | ); |
| 12 | $dbAdapter = $db->getAdapter(); |
| 13 | $dbAdapter->insert('tblName', array('...key...' => '...value...')); |
| 14 | ?> |
Pra ta shpjegoj pak. Së pari krijojmë objektin Feniksi_Db me përshtatësin e duhur (që në këtë rast është Feniksi_Db_Adapter_Pdo_Mysql) dhe me opsionet e duhura. Pastaj krijojmë një variabël $dbAdapter dhe marrim instancën e sapo krijuar të përshtatësit dhe përmes asaj instance përdorim funksionet që i kemi krijuar më lart. Në shembull shihet funksioni insert(), në të cilin ende nuk kemi vendosur ndonjë logjikë por këtë do ta bëjmë ne mësimin e radhës.
Shpresoj që sa do pak te keni mësuar diçka te re, nqs nuk keni diçka te qartë ju lutem shkruani ne komente dhe me gjithë dëshirë do mundohem të ju a shpjegoj me thellësisht!





Mbase te “pse te perdorim interfaces” mund te shtosh edhe qe perdorimi i tyre e ben shume te lehte punen ne grup, pasi nese do te shikosh cfare ben nje klase e shkruar nga dikush tjeter menyra me e qarte/paster/thjeshte eshte ti hedhesh nje sy interface.
Mendoj se eshte shkrim mjaft mase i mire per fillestare te OOP. Por dua te shtoj se me kujtohet qe nga teoria qe kam bere ne shkolle, dy pikat me te rendesishme te OOP jane “inheritance” dhe “polymorphysm”. A ke ndermend ta vazhdosh shkrimin me pjese te tjera mbi keto tema ??
Ne fakt, Interfaces jane nje menyre e mire per ti treguar vetes apo te tjereve se cfare API (ne kuptim metaforik) do perdoret. Flamuri e ka shpjeguar mire besoj me pjesen “…udhezon te tjeret…”.
Edhe pse s’eshte shpjeguar, Inheritance eshte ilustruar qe ne kodin e dyte: “Feniksi_Object2 extends Feniksi_Object”. Per Polymorphism ka kohe
Flamur, shoh qe variablave i vendos nje _ (underscore). Zakon nga PHP4?
E vura re qe eshte ilustruar, por nuk eshte permendur apo diskutuar e pata fjalen.
_ ne fillim te variables apo funksionit vendoset kryesisht per te treguar se eshte protected ose private
Ate e di sepse kam punuar ne PHP4
. Atehere nuk kishim scope per variablat sepse te gjitha ishin publike e prandaj perdoreshin _. Tani s’eshte nevoja e prandaj e pyeta “Zakon nga PHP4?”
ne PHP4 kam qene duke mesuar dhe s’kam patur eksperience fare, por prape mendoj se te ndihmon te dish nese nje funksion/variable eshte accessible apo jo nga nje klase vetem duke pare emrin
Arsye tjeter qe Flamuri e perdor eshte se ai punon me Zend Framework, dhe ajo eshte cfare ata rekomandojne ne dokumentacionin e tyre (besoj)
Pershendetje,
Isha per udhetim per disa dite prandaj skam pasur kohe tju kthej pergjigje!
Arsyja pse perdori _ “underscore/vij posht” eshte mu per ate qe preferohet ne protected and private variables, por une pash qe e kam be ate edhe ne public gje qe se kam vrejt!
@Meti, sic e kam cek dhe ne fillim ky mesim eshte nje hyrje per nje seri mesimesh ne keto tema, dmth. design patterns and OOP. Dhe ne vijim do te flas dhe per “polymorphysm” dhe “inheritance”.
Shpresoj qe mesimin e radhes ta kem te gatshem nga java tjeter, deri ateher ju pershendes dhe cdo te mire.
Flamuri
Cuditem ku eshte Flamuri
Ke te drejte, Zend keshillon perdorimin e underscore per Private dhe Protected:
————–
For instance variables that are declared with the “private” or “protected” modifier, the first character of the variable name must be a single underscore. This is the only acceptable application of an underscore in a variable name. Member variables declared “public” should never start with an underscore.
————–
Personalisht nuk e perdor Zend dhe nje arsye eshte qe te imponojne stile kodimi
Mendoj se imponimi i nje stili te caktuar eshte gje pozitive kur je nje skuader programuesish dhe jo nje i vetem.
Une jam duke punuar me ZF gjithashtu dhe eshte shume e lehte per programuesit e tjere ketu ne zyren time per te kuptuar cfare ndodh ne nje aplikacion pasi i permbahemi te gjithe keshillave/imponimeve qe ben ZF