Hyviä käytäntöjä koodia kirjoitettaessa: Vältä toistoa, artikkelin käännös

  • Kharadus
  • Kharadus hahmo Aiheen kirjoittaja
  • Vieras
  • Vieras
21.01.2014 10:01 #6329 : Kharadus
Kharadus loi aiheen: Hyviä käytäntöjä koodia kirjoitettaessa: Vältä toistoa, artikkelin käännös
Alkuperäinen artikkeli löytyy osoitteesta magazine.joomla.org/issues/issue-jan-2014/item/171...ractices-don-t-repeat-yourself

Hyviä käytäntöjä koodia kirjoitettaessa: Vältä toistoa


Olen isä. Tuon on tapana kuulostaa jonkinlaiselta tunnustukselta, mutta suurin osa ihmisistä, jotka tuntevat minut tietävät, että rakastan lapsia. Minulla on kolme lasta ja tulevaisuudessa toivon joukon vielä kasvavan. Olen oppinut vanhempana olosta paljon: opein muun muassa, että lapsien kanssa on olemassa outo ilmiö, missä he eivät kuule mitä sanon, ellen toista itseäni useita kertoja. Tämä ilmiö on mielenkiintoinen, koska se ei ole voimassa kaikenaikaa, vaan yleensä pelkästään tietyissä tapauksissa, joissa heitä on pyydetty tekemään jotakin, mitä he eivät erityisemmin halua tehdä. Ja minä väsyn itseni toistamiseen, se käy pidemmän päälle varsin rasittavaksi.



Näillä main lukijani varmaan alkavat ihmettelemään miten tämä liittyy mitenkään koodaamiseen tai hyviin kehityskäytäntöihin. Tänään aiheenani on ’Älä toista itseäsi’.

Wikipedia määrittelee Älä toista itseäsi (Don’t Repeat Yourself) –periaatteen seuraavasti:

Jokaisen tiedon palasen tulee omata yksittäinen, epätulkinnanvarainen sekä määräävä tulkinta järjestelmän sisällä.’

Jokaisen tiedon palasen:
Kehitystyössä tällä voidaan viitata vaikkapa luokkaan, toimintoon tai jopa pelkästään palaseen koodia toiminnon sisällä.

yksittäinen, epätulkinnanvarainen sekä määräävä:
koodin tulisi esiintyä vain kerran, ja sen tulee olla selkeästi kirjoitettu.

järjestelmän sisällä: komponenttisi, moduulisi, liitännäisesi, sovelluksesi jne.

Jos otamme nämä palaset yhteen ja kirjoitamme ne uudestaan käyttäen uutta termistöämme, päädymme suunnilleen tähän:

Kaikki koodi, jota komponenttisi sisältää, tulisi ilmetä vain yhdessä sijainnissa ja sen tulisi olla selkeästi kirjoitettua.’

Tuo kuulostaa jo ihan järkeenkäyvältä. Määriteltyämme Älä toista itseäsi -periaatteen selkeämmässä muodossa katsotaan vähän tarkemmin esimerkkejä siitä, kuinka toteuttaa sitä omassa koodissasi.

Esimerkki huonosta koodista


function getSingleItem($id)
{
// assume all variables needed
$query = $this->db->getQuery(TRUE)
->select($this->db->quoteName(array('i.*', 'c.name', 'a.something')))
->from($this->db->quoteName('#__myitems', 'i'))
->join('LEFT', $this->db->quoteName('#__categories', 'c') . ' ON (' .
$this->db->quoteName('i.category_id') . ' = ' . $this->db->quoteName('c.category_id') . ')')
->join('LEFT', $this->db->quoteName('#__attributes', 'a') . ' ON (' .
$this->db->quoteName('a.item_id') . ' = ' . $this->db->quoteName('i.item_id') . ')')
->where($this->db->quoteName('i.item_id') . ' = '. (int) $id);
$this->db->setQuery($query);
$item = $this->db->loadObject();
}

function getManyItems($ids)
{
// assume all variables needed
$query = $this->db->getQuery(TRUE)
->select($this->db->quoteName(array('i.*', 'c.name', 'a.something')))
->from($this->db->quoteName('#myitems', 'i'))
->join('LEFT', $this->db->quoteName('#categories', 'c') . ' ON (' . $this->db->quoteName('i.category_id') . ' = ' .
$this->db->quoteName('c.category_id') . ')')
->join('LEFT', $this->db->quoteName('#__attributes', 'a') . ' ON (' . $this->db->quoteName('a.item_id') . ' = ' .
$this->db->quoteName('i.item_id') . ')')
->where($this->db->quoteName('i.item_id') . ' IN '. implode(',', $ids));
$this->db->setQuery($query);
$item = $this->db->loadObject();

Näyttääkö yläpuolisessa koodissa olevan toistoa? Pitäisi näyttää. Loin jälkimmäisen funktion kopioimalla ensimmäisen funktion muuttaen vain yhtä riviä. (Vinkki: katso where-lauseketta). Miltä tämä koodi näyttäisi, jos kirjoittaisin sen uudestaan toistamatta koodirivejä? Seuraavaksi yksi mahdollinen esimerkki.

Esimerkki paremmasta koodista

function getSingleItem($id)
{
// assume all variables needed
$query = $this->getQuery();
$query->where($this->db->quoteName('i.item_id') . ' = '. (int) $id);
$this->db->setQuery($query);
$item = $this->db->loadObject();
}

function getManyItems($ids)
{
// assume all variables needed
$query = $this->getQuery();
$query->where($this->db->quoteName('i.item_id') . ' IN '. implode(',', $ids));
$this->db->setQuery($query);
$item = $this->db->loadObject();
}

function getQuery()
{
$query = $this->db->getQuery(TRUE)
->select($this->db->quoteName(array('i.*', 'c.name', 'a.something')))
->from($this->db->quoteName('#myitems', 'i'))
->join('LEFT', $this->db->quoteName('#categories', 'c') . ' ON (' . $this->db->quoteName('i.category_id') . ' = ' .
$this->db->quoteName('c.category_id') . ')')
->join('LEFT', $this->db->quoteName('#__attributes', 'a') . ' ON (' . $this->db->quoteName('a.item_id') . ' = ' .
$this->db->quoteName('i.item_id') . ')');

return $query;
}


Sen sijaan, että query-funktio uudelleen kirjoitettaisiin kahdesti, kerran molempien funktioiden sisälle, olen poistanut toistuvan koodin ja kirjoittanut sen tilalle kolmannen funktion, joka osaa suorittaa haun kummasta tahansa toisesta funktiosta. Vaikuttaa kovin yksinkertaiselta, ja monet kehittäjät suosivat jo tämäntyyppistä koodia tehdäkseen koodistaan parempaa.

Edut


Miksi itsensä toistamista tulisi välttää? Koodin kirjoittamisella vain kerran on monia etuja. Toki se on jo koodaajalle helpompaa säästäen koodin kirjoitukseen menevää aikaa, mutta se myös vähentää mahdollisuutta bugien syntymiselle. Vähemmän koodia tarkoittaa vähemmän mahdollisuuksia ongelmakohtien synnylle. Olemme kaikki varmasti törmänneet tapaukseen, jossa tunnin haeskelun jälkeen ongelmaksi ilmenee puuttuva puolipilkku, minulle se ainakin on tapahtunut. On tässä muitakin etuja, kun huomaat joutuvasi lisäämään toisen taulukon osaksi hakua, koska asiakkaasi tarvitsee enemmän tietoa tietokannasta, tarvitsee sinun päivittään vain yksi query-toiminto.

Toivon, että monet kehittäjät ovat jo tietoisia Älä toista itseäsi –periaatteesta. Jos tämä on uusi käsite, onnittelut, nyt tiedät mitä tarkoittaa DRY (Don’t Repat Yourself, Älä toista itseäsi) –koodin kirjoittaminen. Halusin aloittaa tämän sarjan helpolla aiheella, ja vaikkemme käsitelleetkään jokaista periaatteen teknistä yksityiskohtaa, keskityimme sen keskeisimpään ajatukseen. Tulevissa julkaisuissa tutustumme tarkemmin muihin hyvän kehitystyön periaatteisiin.

Kirjaudu tai Rekisteröidy liittyäksesi keskusteluun.

Valvojat: jkwebdesignGamossJiiKoo
Sivu luotiin ajassa: 0.085 sekuntia