Jump to content
php.lv forumi

vai leitot RETURN vai tomēr ne (diskusijas turpinājums)


Recommended Posts

 

Piemērs:

A={
  el:$('#somelement'),
  show:function(){
    this.el.show();
  }
};
//...
A.show();
Kāpēc, lai šeit show kaut ko atgrieztu?Kā jau Kavacky minēja, defaultā tiek atgriezts udefined un, ja nekas cits nav nepieciešams, tad return nav nepieciešams.

Kā būtu, ja šajā gadījumā atgrieztu 'this', lai pēctam varētu rakstīt A.show().hide() ?

Link to post
Share on other sites
  • Replies 149
  • Created
  • Last Reply

Top Posters In This Topic

OOP, procedūras (šajā kontekstā, metodes, kas neko neatgriež) varēru atgriezt `this` objektu — lai vēlāk būtu iespējama arī čeinošana.

Link to post
Share on other sites

$account->decMoney($total); - raise exeption. Noķer kontroleris. Ko man darīt, ja es gribu turpat pamēģināt citu maksāšanas metodi vai iešķiet userim soda punktus? Uzreiz tas try catch pārvēršas par tiem pašiem if else

 

Nepārvēršas, ja katra atbilstošā izsaucamā funkcija pati pareizi apstrādā iespējamos kļūdu gadījumus.

Piemēram, ja ir vairāki veidi kā pirkts itemus - par naudu un par virtuālo zeltu.

Īss pilns piemērs kā es +- taisītu ajax requestu savā FW:

 

 

class Ajax_Account extends AjaxController{
  function buyItem(){
    $itemid=Request::post('itemid',"int");
    $amount=Request::post('amount',"int",array("min"=>1,"max"=>100000));
    $type=Request::post('type',"int",array("min"=>1,"max"=>2));
    $account=Model_account::auth();
    $item=Model_item::get($itemid);
    if ($type==1) $account->decMoney($item->priceInMoney()*$ammount); //buy for money
    if ($type==2)  $account->decItem(Model_item::goldid, $item->priceInGold()*$ammount); //buy for gold
    $account->addItem($itemid,$ammount);
    db::commit();
  }
}
 

Tātad kā šeit strādās eksepšani.

1)Request::post izsauks exsepšanu, ja dotais parametrs nebūs post datos, vai neatbildīs validācijas nosacījumiem. Tas būs sistēmas eksepšana, ja post mainīgā nebūs, vai jūzera eksepšans, no kura uzformē uzrea paziņojumu, ja runa būs par atbilstību nosacījumiem.

2)Model_account::auth() atgriezīs ielogotā lietotāja account modeli, ja lietotājs nebūs ielogojies, izsauks lietotāja eksepšanu, kuru pārķers front kontroleris un uzformēs kā kļūdas paziņojumu, ka lietotājam jābūt ielgojušam.

3) ->decMoney attiecīgi izsauks lietotāja eksepšanu, ja nepietiks nauda un arī tas pats fron kontroleris to uzformēs kā lietotāja paziņojumu, ka trūkst nauda

4) ->decItems to pašu, ko decMoney, tikai cits paziņojums eksepšanā.

5) ->addItems atticīgi izsauks lietotāj ekspešanu, ja inventorijs pilns.

6) db::commit(); ja neviens eksepšans nav izsaukts, tad nokomito visas darbības ar db.

 

 

Kā būtu, ja šajā gadījumā atgrieztu 'this', lai pēctam varētu rakstīt A.show().hide() ?

Ja vajadzīgs čainings, tad protams var atgriezt this, bet, piemēram, es taisu widgetus ar jquery ui widget factory un tur viss strādā nedaudz savādāk un widgeta metodēm nav nepieciešam čainings, jo tās izsauc jqueryui wf stilā, piemērām $('#somelement').mywidget('show'); Edited by codez
Link to post
Share on other sites

Es nebiju domājis šādi

    if ($type==1) $account->decMoney($item->priceInMoney()*$ammount); //buy for money
    if ($type==2)  $account->decItem(Model_item::goldid, $item->priceInGold()*$ammount); //buy for gold

 

Bet

 

if(!$account->decMoney($item->priceInMoney()*$ammount)){
    if(!$account->decItem(Model_item::goldid, $item->priceInGold()*$ammount)){
        ej_strādāt_nes_piķi();
    }
}


 

Vnk apstrādājot ar try catch nekas tur daudz īsāk nesanāks.

Link to post
Share on other sites

$account->decMoney($total); - raise exeption. Noķer kontroleris. Ko man darīt, ja es gribu turpat pamēģināt citu maksāšanas metodi vai iešķiet userim soda punktus? Uzreiz tas try catch pārvēršas par tiem pašiem if else

 

Neizdomāt neesošas problēmas, to tev darīt.

Link to post
Share on other sites

Try catch arī ir tāds bonuss, ka piemēram if not file_exists {write to file}, tad kad sāksies write to file, tad citā vietā tas pats kods jau ir izveidojis file. Domāju, ka tādu bugu ir īpaši patīkami meklēt. Savukārt try catch gadījumā, tas būs eksepšens ErrorFileExists un augstāk minētā problēma nepastāv.

 

Python`ā "Easier to ask for forgiveness than permission." http://docs.python.org/2/glossary.html#term-eafp

Link to post
Share on other sites

 

if(!$account->decMoney($item->priceInMoney()*$ammount)){    
  if(!$account->decItem(Model_item::goldid, $item->priceInGold()*$ammount)){               ej_strādāt_nes_piķi();    }} 

 

 

 

Vnk apstrādājot ar try catch nekas tur daudz īsāk nesanāks.

Šādā gadījumā ar try catch tas būs aptuveni:

 

 

try{
  $account->decMoney($item->priceInMoney()*$amount);
  $account->decItem(Model_item::goldid, $item->priceInGold()*$amount);
} catch (SomeException $e) {
  ej_strādāt_nes_piķi();
} 

 

 

 

Bet vienlīdz sarežģīti šie šķiet tāpēc, ka abos funkcijas atgriež tikai vienu kļudas stāvokli, kurš nav jāpadod tālāk. Pie tam praksē šāda pēkšnas manuālas kļūdu apstrādes man personīgi vajadzīgas ļoti reti. Bet tikko sāk šīs metodes izmantot metodēs, kuras tiek izmantotas tālāk un tikko viena darbība ir spējīga atgriezt vairākus kļūdu stāvokļus, tā eksepšanu mehānisms paliek tik pat sarežģīts, kamēr kļūdu stāvokļa atgriešanas ar return sarežģītība pieaug strauji.

Piemēram, ja tu gribi uztaisīt Model_account metodi, kura sūta itemus citam lietājam:

Class Model_account extends Model{
  function sendItem($account2, $itemid, $amount){
    $this->decItem($itemid,$amount);
    $account2->addItem($itemid,$amount);
    $transaction=new Model_Transaction();
    $transaction['from']=$this['id'];
    $transaction['to']=$account2['id'];
    $transaction['itemid']=$itemid;
    $transaction['$amount']=$amount;
    $transaction->insert();
  }
}

 

 

 

Tālāk ajax actionā:

Class Ajax_account extends AjaxController{
  function sendItemTo(){
    $account=Model_account::auth();
    $account->sendItem(
      Model_account::get(Request::post('account2','int')),
      Request::post('itemid','int'),
      Request::post('amount','int')
    );
    db:commit();
  }
}

 

 

 

Un tagad pamēģini šo visu uzrakstīt ar kļudu stāvokļa padošanu tālāk, ar visiem kļūdu paziņojumiem, pārbaudēm, vai lietotājs ir ielogojies, utml. Sanāks krietni vien garām, sarēžģītāk un grūtāk labojams kods. Esmu pārbaudījis.

Edited by codez
Link to post
Share on other sites

Parasti jau formu validācija notiek caur formu validātoru, nevis kontrolerī.

Ko nozīmē parasti?

Parādi piemēru kā tas ir un kāpēc tas ir labāk.

Es esmu secinājis, ka validāciju visērtāk ir veikt attiecīgajā ajax kontrolera acctionā datiem, kas attiecas uz konkrēto darbību, vai modelī datiem, kas attiecas uz modeļa vērtībām.

Link to post
Share on other sites

Parasti, es esmu tā darījis. Gan, kad lietoju Kohana, gan tagad, kad lietoju Django.

 

Ar Django doma tāda, ka tu kontrolerī uztaisi formu, kurai padot request datus, un, kontrolerī izsacot `is_valid` uz formas, tu uzzini vai dati ir valīdi vai nav, plus, forma satur serializētos datus. Iekšā formā, definē fieldus, validācijas rūļus un kastom metodes, kas validē padotos datus. Ja kkas nav labi, forma noķer `ValidationError`. Te ir tas punkts, ka šis eksepšens var tik izmests kastom metodē, no predefinētā rūļa vai da jebkur — šis ir tas plus. Protams, var darīt arī savādāk, piemēram, validēt kodu iekš kontrolera. Šis gan man nepatīk, jo esmu par īsiem kontroleriem un _reusable_ objektiem!

Edited by daGrevis
Link to post
Share on other sites

Mana pieredze rāda, ka tāda custom forma nu ļoti reti ir vajadzīga. Parasti formas tiek taisītas no modeļiem, lai būtu DRY (ja mainās modeļi, tad mainās viss automātiski - sql, formas, validācijas utt).

 

Tavā piemērā to pašu type var iebāzt kā GET parametru un amount attiecas uz modeļiem.

Link to post
Share on other sites

Mana pieredze rāda, ka tāda custom forma nu ļoti reti ir vajadzīga. Parasti formas tiek taisītas no modeļiem, lai būtu DRY (ja mainās modeļi, tad mainās viss automātiski - sql, formas, validācijas utt).

Kur tad atrodās visi validācijas nosacījumi, ja nav cutom formas klases?

Tavā piemērā to pašu type var iebāzt kā GET parametru un amount attiecas uz modeļiem.

amount nu nekādi neattiecas uz modeli.

Ammount šijā gadījumā norāda itemu skaitu, kuru var nopirkt veikalā. Un viņa maksimālā vērtība nevar tikt validēta modelī, jo modelī item skaits var mainīties arī citu nosacījumu dēļ, piemēram, vien lietotājs sūta otram, vai itemi tiek iztērēti, vai vinnēti loterijā, utt. Tātad ammount attiecas uz konkrēto kontrolera darbību - pirkt un ir jāvalidē kontektstā ar to. Es vēl varētu piekrist, ja kontroleris ir milzīgs, ka validācija tiešām tiek atdalīta atsevišķā formas klasē, bet man ir pietiekami daudz iemeslu kāpēc tā nedarīt.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...