Programátorské cvičení VI.


Vypsaná školení


Máme tu předposlední díl programátorského cvičení. Baví vás? Už teď ale můžu prozradit, že tato cvičení budou brzo součástí něčeho mnohem většího. Dnešní cvičení patří k jednodušším a mnoho z vás jej už využívá. Pokud ne, měli byste brzo začít!

Takže jaký je váš dnešní úkol:

Zbavte se magických konstant a duplicitního kódu.

Co je magická konstanta? Magická konstanta je kousek dat (například řetězec, číslo), který se vyskytuje ve zdrojovém kódu bez toho, aby měl nějaké pojmenování, které určí význam.

Co je:
sleep(3 * 86400)

Nic, člověku, který po vás přijde, může přijít divné, proč má výpočet zastavit na 3 * nějaké divné číslo.

const DAY = 86400;
Co je:
sleep(3 * DAY)

Aha, program má zastavit na 3 dny! Ale pořád máme v kódu magickou konstantu: 3. Proč mám stát 3 dny?

Co je:

sleep($config->import->daysToWaitToNext * DAY);

To je najednou zjevné: kolik dní se má po importu počkat na další import?

Odstranění magických konstant zpřehlednilo kód.

Duplicitní kód není jen kód, který vypadá na první pohled stejně. Duplicitní kód může kolikrát vypadat i dost odlišně a přesto v něm lze najít společného jmenovatele.

// vygenerovat pole
function gen_arr() {
        return array_map(function($row) {
                return (object)array("x"=>$row%2, "y"=>$row);
        }, range(1, 10));
}
$items = gen_arr();

// prvni funkce
$accumulator1 = 0;
$func1 = function($row) use (&$accumulator1) {
        if ($row->x) {
                $accumulator1 += $row->y;
        }
        return $row->y;
};

// druha funkce
$accumulator2 = array();
$func2 = function ($row) use (&$accumulator2) {
        $rowArr = (array)$row;
        $accumulator2 = array_merge($accumulator2, array($rowArr));
        return $rowArr['y'];
};

$items1 = array_map($func1, $items);
$items2 = array_map($func2, $items);

//////////// ------------------

// spolecny jmenovatel
$returnY = function($row) { return $row->y; };

// prvni funkce
$accumulator1b = 0;
$func1b = function($row) use ($returnY, &$accumulator1b) {
        if ($row->x) {
                $accumulator1b += $row->y;
        }
        return $returnY($row);
};

// druha funkce
$accumulator2b = array();
$func2b = function($row) use ($returnY, &$accumulator2b) {
        $accumulator2b = array_merge($accumulator2b, array((array)$row));
        return $returnY($row);
};

$items1b = array_map($func1b, $items);
$items2b = array_map($func2b, $items);


// overim, ze je vse v poradku
var_dump(
        $accumulator1 == $accumulator1b,
        $accumulator2 == $accumulator2b,
        $items1 == $items1b,
        $items2 == $items2b
);

/** ocekavame vystup:
 * bool(true)
 * bool(true)
 * bool(true)
 * bool(true)
 */

Tento příklad není právě z praxe, každopádně ukazuje, že i kusy kódu, které vypadají ne moc podobně, můžou obsahovat společnou funkcionalitu.

Zbavení se magických konstant a duplicitního kódu učiní náš kód čitelnější (většinou) a lépe udržovatelný (vždy). Tak hurá do toho!

Kategorie

Agile
Cestování
Life Hacking
Minimalismus
Podnikání & Startupy
Použitelnost
Programování

Copyright © 2010 Jiří Knesl; 777 002 104 jiri.knesl@gmail.com RSS
Followujte mě na twitteru