Jump to content
php.lv forumi

OOP stils


hu_ha

Recommended Posts

Gribeeju apjautaaties zinoshiem cilveekiem, kaa juus veidojat klases savos web izstraadaajumos.

Piem, ja ir nepiecieshama klase, Posts, kuraa ir funkcija, kas paredzeeta datu paraadiishanai uz ekraana.

 

class Posts
  {
    var $sql='select * from ...';
    var $norormeejuma_mas=array("class1","class2",...);

   function show_posts()
        {
          $result=mysql_query($this->sql);
             while ($myrow = mysql_fetch_array($result))
                {
                  $text.='<div class="'.$this->$norormeejuma_mas[$i++].'">'.$myrow['n_title'].'</div>';
                 }
          return($text);
         }
   }

 

Tad jautaajumi sekojoshi:

1) vaicaajumu peec datiem

a) veidot klases iekshpusee (t.i. sql vaicaajums tiek glabaats klases mainiigajaa)

b) veidot klases funkcijaa

c) veidot galvenajaa programmaa (kur tiek izsaukta) un nodot caur klases funkciju

d) cits variants...

 

2) kaa veidot rakstu izvadi (jaaizvada 5 raksti), ja tiek veidots shabonam liidziigs pasaakums?

a) funkcija atgriezh 5 rakstu rezultaatu, kursh funkcijaa tiek jau noformeets (ielikts div elementos etc)

b) veidot katram rakstam savu klasi (?)

c) noformeetos 5 rakstu rezultaatus atgriezt kaa masiivu un shablonaa paredzeet ciklu un attieciigi izvadi

d)....

 

3) kaa veidot funkciju kas nofomee no datu baazes izguutos rezultaatus, t.i., ieguustu rezultaatu no datu baazes un tagad noformeeju div elementos. kaa uzdot div elementu class atribuutus?

a) nodot tos caur klasei izveidotu masiivu

b) paredzeet funkcijaa kaa konstantu un paljauties, ka visu izdariis ar css paliidziibu (t.i. ja gribees mainiit css klases nosaukumu, tad tas buus jaadara ar roku visaa funkcijaa)

c) nodot no galvenaas programmas (kur tiek izsauktas klases funkcijas)

 

mani neinteresee piemeeri, bet gan ideja kaa taada. kursh skaitaas labaaks stils un biezhaak tiek izmantots...

jau ieprieksh paldies.

Link to comment
Share on other sites

Par labumu nezinu, bet es daru šitā:

 

1) b

  • neņemu a tāpēc, ka gadījumā, ja tev būs klase, kur būs teiksim 20 vai vairāk dažādi SQLi, fiksi un ātri sapīsies viņos. Domāju, ka variants b uzlabo lasāmību, jo tu lasi tikai to, ko tev vajag zināt pie attiecīgās klases metodes, nav jālasa cauri visa klase.
  • neņemu c tāpēc, ka klašu ideja ir tāda, ka to lietotājam nav jāzin, kā tās darbojas, bet tikai jānodod parametri. Attiecīgi, ja tu nodod SQL pieprasījumu kādas klases kādai metodei, tad tu prasi, lai klases lietotājs zinātu ne tikai to, kā klase darbojas, bet arī to, kāda ir apakšā esošā datubāzes struktūra. Kamēr tu kaut ko taisi viens pats, tikmēr jau var darīt visādi.. ;)

attiecībā uz tavu Posts klases piemēru - es daru mazliet savādāk:

class Posts
 {
  function getPosts(){
     $sql = MySQL::instance();
     $qry = "SELECT * FROM posts";
     $sql -> query($qry);
     return $sql -> getAssoc();

  }
  function show_posts()
       {
            $postList = $this -> getPosts();
            foreach ($postList as $post){
                 $text.='<div>'.$post['n_title'].'</div>';
            }
                
         return $text;
        }
  }

 

attiecīgi, ja vajag glabāt CSS klasi, kā biji norādījis, tad man liekas, ka labāk to būtu darīt iekš datubāzes ja jau reiz tā ir katram postam atšķirīga ;)

 

 

2) a, c

  • a - tauta runā, ka viss jāatstāj presentation layerim, tā kā ar to tā īsti neesmu iepazinies, tad lietoju un nesūdzos.
  • b - katram rakstam savu klasi? un ja nu gadījumā to rakstu ir 100? Var jau būt, ka nesapratu ideju.
  • c - teorētiski šis būtu labāks variants, ja domā par lapas uzturēšanu nākotnē, to izmantoju, taču retāk.

3) b

  • domāju, ka nav nepieciešamības mainīt CSS klašu nosaukumus. Pēc idejas, ja mēs runājam par vairāk vai mazāk semantisku webu, tad CSS klases nosaukums ir +/- aprakstošs, attiecīgi ja sistēma tiek izstrādāta, diez vai pēc kāda laika radikāli mainīsies attiecīgās daļas semantiskā jēga. Pie tam css klašu nosaukumiem jau nav tik būtiskas nozīmes - galvenās ir definīcijas. Ja iet runa par stila maiņu laika gaitā, tad patiesībā jau parasti klašu nosaukumus nemaz nemaina - maina tikai CSS definīcijas.

Link to comment
Share on other sites

Nu lieta taada, ka kaut ko jau es te rakstos pa taam klaseem, tik gribaas zinaat, kaa tas pareizaak un ka biezhaak dara..

nu aptuvenu priekshtatu guvu.. Tagad pacentiishos atrefereet vai visu pareizi esu sapratis :)

1) Tad cik noprotu, tad vaicaajumu labaak iebuuveet kaadaa funkcijaa un peec tam gar to varis negraabstiities, bet datus izguut izmantojot tikai funkcijas izsaukumu.

 

2) kas attiecas uz rezultaatu izvadi, tad laikam subjektiivs jautaajums.

to atbildi b) es iekljaavu, jo, varbuut ka kaut kaa hitra arii var klases ciklaa sagenereet

 

3) tad laikam buus jaataisa klashu nosaukumi kaa konstantes, kas iebuuveetas funkcijaa..

 

Vienk, es te praatoju par klashu vairaakkaarteeju izmantoshanu, proti, kaapeec gan neizmantot klasi posts arii komentaaru paraadiishanai. teoreetiski jau nekas nemainaas, tiek izvadiits posts un pusliidz liidziigaa stilaa arii komentaari. itkaa vareetu nodot tikai sql vaicaajumu, citus izskata (css klashu) mainiigos un izmantot taas pashas klases funkcijas..

protams, tad jau atkal rodas jaunas probleemas, ja nu komentaarus radikaali jaamaina, tad buus jaaveido jauna klase shaa vai taa..

 

nu taa nu es te praatoju, varbuut veel kaadi ieteikumi, ko taa starp citu vajadzeetu zinaat? :)

p.s. kaklz paldies

Link to comment
Share on other sites

  • 8 months later...

Ehm... Klases jau nebūvē pēc tā, kur viņas pielieto. Lasīju pavirši, bet salikās, ka klase Posts ir izveidota tikai tāpēc, ka kaut kur projectā ir vieta, kur jādrukā komentārus.

Klases būvē atbilstoši zobratiņiem, kas to visu pasākumu kustina. Skat kā - saliec 100 zobratiņus pareizi vienu ar otru kopā - vot tev i ātrumkārba!! (jauna klase). Saliec pareizi kopā ātrumkārbu ar motoru, stūri, riteņiem etc... vot tev i mašīna (atkal jauna klase).

 

Baigi interesanti pie tam ir tas, ka es te lasu šito forumu (šodien tikai iesāku) un nespēju nobrīnīties - lielākā daļa tautas raksta no sērijas:

class Posts {
 function print_posts() {
    return '<pilns ar HTMLu>';
 }
}

kāda reāli no tā jēga??? tas ir tipa tas pats, kas rakstīt bez klasēm, tikai kodu mākslīgi sabāzt klasēs, jo tāpat jau pēc tam notiek parsings pa visu PHP dokumentu, kurš ir mikslis no HTML (vai includēm) un PHP gabaliem un atšķirībā no include(something) tu lieto echo $posts->print_posts();

Tad jau labāk:

$p = new Posts();
$p->get_posts($_GET['article_id']);
include('templates/post_showing_template.inc');

 

Web projectiem tas pasākums vēl ir salīdzinoši triviāls - vienīgās lietas, ko reāli gribās ir: 1) object persistance (1:1 klašu mapošana pret SQL tabulām); 2) lai nav pašam SQLi visu laiku jākomponē. Pārējam salīdzinoši po, izmantot klases vai nē. No klasēm ieguvums ir tikai tīrāks kods (kuru grūtāk lasīt vidusmēra cilvēkam).

Link to comment
Share on other sites

Apskatot topika sākumā uzstādīto problēmu... Redzu ka topiks vecs, bet varbūt kādam noderēs :-)

 

Klase Posts - ja mēs domājam objektos - kādu objektu weblapā šī klase reprezentē? Manā skatījumā - nekādu. Ja nu vienīgi kaut kādu abstraktu funkciju kopu, kas māk no DB izselektēt un atgriezt piecus rakstus (jau formatētus).

Krietni loģiskāk būtu definēt klasi Post, kura reprezentētu vienu rakstu kā tādu (tam atbilstu viens ieraksts datubāzes tabulā). Klase Post varētu sevī ietvert definīcijas (aprakstus) gan attiecībā uz datubāzes tabulas laukiem, gan saturēt kā mainīgos visu lauku vērtības, kad klase Post tiek reāli izveidota par KONKRĒTU objektu - KONKRĒTU rakstu. Tāpat arī klase Post varētu implementēt rakstam specifiskas funkcijas - piemēram - pievienot komentāru, pievienot bilžu galeriju, nomainīt autoru vai whatever.

Ja tas tiek organizēts šādi, tad līdz automātiskai SQL ģenerācijai ir viens solis - jāuzraksta klase piemēram DBRecord un mūsu apskatāmā klase Post ir jāatvasina no šīs klases. Klasei DBRecord būs pieejama visa informācija par Post laukiem, kā arī klasei Post būs pieejamas klases DBRecord funkcijas.

Un šajā modelī (hipotētiski), lai izselektētu kaut kādu rakstu:

$a = new Post();
$a->db_get_by_primarykey($vajadziigais_raksts);

Un nekādu SQL murgu. db_get_by_primarykey() ir klases DBRecord funkcija, kas SQLu ģenerē automātiski, izejot no klasē Post definētajiem mainīgajiem, izpilda šo SQLu un klases Post mainīgajos ieraksta izselektētās vērtības.

Tālāk jau operējam vienkārši:

 $a->set_field_value('comment_count', $comment_count);
 $a->db_update();

Arī db_update() ir klases DBRecord funkcija, kas māk izveidot un izpildīt UPDATE vaicājumu.

Pagaidām šis modelis neapskata vairāku ierakstu izselektēšanu vienā rāvienā - priekš tam būtu jāraksta jauna klase, piemēram DBRecordSet, kurai padodot objekta tipu un vairājuma parametrus, varētu saņemt pretī masīvu no objektiem, kurā katrs elements reprezentē konkrētu objektu. Vienkāršākais piemērs (izselektēt visus rakstus):

 $rs = new DBRecordSet(new Post());
 $results = $rs->db_select();
 include('templates/show_posts.inc');

Nu un show_posts.inc ir pieejams $results mainīgais (masīvs no Post objektiem), ar kuru tad var arī operēt (piem izdrukāt katra raksta komentāru skaitu):

 foreach($results as $article) {
   echo '<div class="post">'.$article->get_field_value('comment_count').'</div>';
 }

Lūk arī maģiskais presentation layeris, kuram neparko citu nav jāsatraucas, kā tikai izvadīt to kas jāizvada. Un iet ieskrieties visi Smarty un citi brīnumi, kas paredzēti tikai lai apgrūtinātu cilvēkiem dzīvi.

 

Nu ja. Karoch tas viss ir reāli iespējams (arī ar PHP4, tiesa gan ar PHP5 glaunāk) - es pats šādi jau labu laiku kodēju un nezinu bēdu :-)

Edited by ivka
Link to comment
Share on other sites

Ir stilīgi pacelt augšā vairāk kā pus gadu vecas tēmas ;)

 

Atzīšos godīgi, tagad mana izpratne par OOP ir krietni vien savādāka, nekā tā bija to vairāk kā pus gadu atpakaļ, proti tā vairāk līdzinās tavam piedāvātajam variantam, taču man diez kā nesimpatizē tāda pieeja. Kaut kur lasīju vienu labu teicienu par visādiem frameworkiem .. 'izmantojot kādu no frameworkiem tu automātiski piekrīti visiem framework iebūvētajiem noteikumiem'. Attiecīgi tikko tu sāc izmantot kaut vai tevis paša slavēto MVC pieeju, tā tu gandrīz automātiski arī zaudē PHP kā dinamiskas programmēšanas valodas spēku.

 

Kaut vai tā pati dinamiskā SQL ģenerēšana, ko tu liec priekšā - esmu izmēģinājis visvisādus piegājienus, taču vienā jaukā brīdī tu saproti, ka jebkurš automātiski ģenerēts SQL nav tikpat labs cik ar roku rakstīts, jo tieši ar roku rakstīto tu ideāli pielāgo katrai konkrētai situācijai, nevari paredzēt visas iespējamās nākotnes iespējas. Protams, Extend, override, bet tas manuprāt nav tas labākais risinājums, ja var to visu vienkāršot. Vecais labais KISS princips - Keep It Simple and Stupid :)

 

Diskusija par PHP un MVC būtībā būtu atsevišķas tēmas vērta ;) Man ir radies priekšstats, ka ir lietas, ko var un vajag no tā izmantot, taču pilnīgs PHP MVC ir lieka laika šķiešana.

 

Attiecībā uz PHP un OOP nevajag sākt skaldīt matus .. tikpat labi es tev varētu pārmest, ka tu XHTML lapu nebūvē ar XML rīkiem, nedefinē katru XHTML elementu kā jaunu klasi, utt.

Link to comment
Share on other sites

Neskaldu matus - piedāvāju pieeju :-) Kā arī MVC neslavēju - ja slavētu, tad pats lietotu, bet nelietoju odnako - skat. topiku par MVC.

 

Par automātiskajiem/manuālajiem SQLiem gan nepiekritīšu. Kaut vai aiz tā aspekta, ka neesmu redzējis nevienu serveri, kurš nebūtu PentiumMMX un mirtu nost dēļ DB pārslodzēm. Ā nē, tomēr vienu esmu redzējis (šito) B) . Bet nu ideja skaidra - nav labu vai sliktu SQL statementu (ja runājam par strādājošiem) - ir ātri un lēni :P. Ja ātrums nav problēma (un >90% gadījumos nav), tad dodu priekšrodu metodēm, kas ļauj ātrāk un efektīvāk (nevis skaistāk un pareizāk) kodēt.

Tieši te jau tas KISS arī darbojas:

try {
 $a = new Article($_GET['id']);
 $a->set_field_value('comment_count', $x);
 $a->update();
} catch(Exception $e) {
 header('Location: /error.php?ec='.$e->getMessage());
 die;
}

nevis

$id = abs(intval($_GET['id']));
$q = "UPDATE articles SET comment_count='.$x.' WHERE id=".$id;
$result = db_exec($q);
if(hvz_affected_rows($result)==0) {
 header('Location: /error.php?ec=154');
 die;
}

Un defaultajā gadījumā rindiņas no otrā koda ir jāraksta cauru dienu bez apstājas ilgu mēnešu garumā :( Pie kam ar objektiem, kas reprezentē ierakstus ir daudz ērtāk darboties nekā ar kaudzi mainīgo, kas atbilst konkrētiem laukiem.. aļa

list($id, $author, $title, $lead, $body, $comment_count) = hvz_getrow($result);

Edited by ivka
Link to comment
Share on other sites

Es ar īpašu jēgu no miljards klasēm neredzu.

Kāda jēga rakstīt

<?php
class echo_class {
var $text;
var $echo;
function ($text,$echo=0) {
   if ( $echo ) {
       echo $text;
       } 
   else {
       return($text);
       }
    }
}
?>

 

Plusi un mīnusi ko es saskatu klasēs un kapēc klases es cenšos izmantot tikai kur tās tiešām ir nepieciešamas:

plusi: *sakopē klases daudziem webprojektiem un izpaliek daudzu kodu rakstīšana

mīnusi: *nav īpaši dinamiski - ja kas jāmaina, tad jāpārčakarē visa klase

* grūti pielāgojama, te jau pieminētajiem, unikālajiem gadījumiem, kuru man ir vairāk kā vajag

* protams ka n-tās nevajadzīgās kodu rindas sabremzē skriptu

* un kā jau teica ļ. cien. Kaklz - KISS :)

 

Pats savos projektos izmantoju divas klases pēc vajadzības - template un mysql. Reizēm gadās vēl kāda cita, projekt-specifiska klasīte.

Protams tas ir tikai tādiem lielākiem projektiem. Neiešu tak taisīt template maziem saitiņiem vai mysql klasi pāris pieprasījumiem :)

Un kā pieminēja ļ. cien. Laacz - PHP pats par sevi ir templeitu sistēma :)

Link to comment
Share on other sites

Jap. Un stipti vieglāk un lētāk ir atrast HTMLizētāju ar minimālām PHP iemaņām nekā purnu, kurš kaut reizi būtu dzirdējis par Smarty, Velocity un tml. brīnumiem.

 

Bet ne par to šis bazars... Attiecībā uz klasēm - nu PAVISAM sliktu piemēru uzrakstīji :D ar domu - ļoti precīzu - ja kāds raksta šādi, tad viņam nav visi mājās vai arī krāns par īsu :unsure: Vispār jau ieraugot echo() vai <html> klases iekšpusē jāsāk domāt par sliktu stilu. Doma tāda, ka ar klasēm var panākt (ja māk) ļoti smuku un rejūzojamu kodu, kuru atkārtot daudzos projektos - tipa shopping carti, galerijas, forumi un viss pārējais kas nāk prātā. BET - kā jau Kaklz izteicās - ilgos gados neesam vienojušies par metodiku (atšķirībā teiksim no JSPistiem, kas visi kā viens lieto MVC/Struts) - tāpēc viens kaut ko uzrakstīs, otram no tā nebūs nekādas jēgas. Gribētu mazliet paturpināt tēmu - negribās lai par PHP, kurš savā piektajā versijā izārda JSP mazos gabaliņos (tūlīt man uzbruks... :ph34r: ) domā kā par bērnu valodu un par Javu/JSP kā par Olimpa virsotni, kurā banku mājas lapas un internetbankas jāraksta. Un tas notiek faktiski tikai dēļ šī viena iemesla - nespēja veidot sakarīgus koda gabalus, no kuriem būtu jēga arī kādam citam. Rezultātā - nekāda codebase neeksistē (tiešām neesmu dziļi pētījis tos Pear un PECL vai kā viņus tur, bet šķiet ka viņi bērnu autiņos) un PHP spēks ir vienāds ar spēcīgākā kodera spēku vai drīzāk izturību. Java uzvārījās ar savu strikto OOP manuprāt, kamēr PHP izauga no templašu valodas. Ja tu raksti OOP, tad tev gribot negribot jāaizdomājas par pieejas un jēgas jautājumiem, jo savādāk defaultā tiek sabraukts auzās. IMHO protams.

Ak jā - un par nedēļā uztaisāmām lapām protams ka nerunājam.

Link to comment
Share on other sites

heh. es jau nesaku, ka classes ir sliktas vai tikai gaiļu mērītāji taisa viņas. vienkārši cik esmu skatījies, daudz kur klases tiek lietotas pilnīgi bezjēdzīgi, kur varēja izlīst ar daudz vienkāršāku un ātrāku php koda gabalu bez klasēm.

 

bet nu jā. par to codebase runājot. cik es esmu braukājis pa visādām skriptu lapām un tādām lietām meklējot sev ko noderīgu, atklāju, ka mani pilnīgi nekas neapmierina. resp - katrs raksta kodu priekš sevis nevis priekš cita. arī manis rakstītais kods domājams nebūtu parocīgs, ērts vai kā citādi derīgs citam. kā arī ir vēl viens apstāklis - vienu un to pašu darbību var uzrakstīt daudzās dažādās variācijās. viens uzraksta tā, otrs šitā. citam nekas nepatīk un viņs uzraksta pa savam ;) tāda nu dzīve.

Link to comment
Share on other sites

×
×
  • Create New...