Tiszta kódolás
„A kód mindig rohad” - Gémes Tamás
„Code are simple and direct like a prose” - Grady Booch
Tartalomjegyzék
Általános alapvetések
Miért szükséges a tiszta kód? - kérdezhetjük. Egyszerű megközelítés: a fejlesztés idő, az idő pénz… De hol térül meg a befektetett idő, energia. A tiszta kód tanulható, csak eleinte jelent nehézséget és idővel rutinná válik. Ha ’smell’ kódot írunk, gyorsan lehet haladni, értjük is a saját magunk által megálmodott logikát, azonban, ha újra elővesszük a kódot, vagy másnak kell hozzányúlni (Code Legacy – Kód örökség), akkor fontos, hogy a pontos működést gyorsan megértsük és hozzá tudjunk fejleszteni. Grady Booch szerint úgy kell tudni olvasni, mint egy regényt. Nem szabad visszalapozni, egyértelműen sorról-sorra lehet értelmezni. Így a megértés és a hozzáírás fog lényegesen lerövidülni.
Duplikáció elkerülése
Ha már kétszer használunk kódot (számolást, visszatérést, megjelenést), saját függvényt, metódust írjunk. (Let DRY – Don’t Repeat Yourself). Egy megoldás csak egyszer implementáljunk. Ha redundánsan van jelen a kódban – let légyen az számítás, megjelenés, meghívás, stb., ha módosítani kell kényelmetlen és több hibázásra ad lehetőséget.
OCP
Open/Closed Principle – Legyen zárt a változtatásokra, de legyen nyitott a bővítésre. Egy új ’feature’ bevezetéséhez ne kelljen belenyúlni a régi kódba. Azonban a régi kódhoz tudnia kell kapcsolódni.
Code review
Csak abban az esetben, ha funkcionálisan megfelelően működik. Heti rendszerességgel a megírt kódokat közösen átvizsgáljuk. Így ki lehet szűrni a túlbonyolításokat, a code-smelleket, nem utolsó sorban tanulhatunk belőle, egymástól.
End-To-End felelősség
A kódért csoport felelősség van. Felel a tervező, a „designer”, a tesztelő, a kódoló és a manager is. Tervezéstől az üzemeltetésig. Ha ügyfél oldalról vizsgáljuk a felelősségi kérdést még inkább igaz ez – a cég a felelős. Ezért fontos, hogy a kódot mindenki magáénak érezze. Ha valaki ’out of project’ is ismerje, tegye bele a saját tudását. – visszacsatolva a Code review-ra
Kommentek
Kerüljük, ha csak lehet az öncélú kommentet („//” kerülése)… A saját, undeployed feladatoknál elfogadott. De távolítsuk el. Használjunk beszédesebb metódust, változó elnevezéseket. Később saját magunk sem emlékezünk rá mit is akartunk. Helyette saját (új) metódus bevezetése a célszerű.
// Check to see if the employee is eligible
// If full benefits
if(($employee->flags && $emloyee->age > 65) && $employee->dayOk)
helyett:
if ($employe->isEligibleForFullBenefits())
Hatékony is, mert elég a metódust updatelni és máris up-to-date a kódom. Azonban dolgozhatok duplán a kommentekkel, vagy rosszabb nem követem. A legnagyobb baj, ha „out-of-sync”-be kerülnek. Ezért code smell a comment is.
Elnevezések
Kerüljük a ’mental-mapping’-et.
$d = 7; //working day in the part of plant
helyett:
$plantWorkingDay = 7;
A mental-mapping egy belső térkép, szótár, amiből mi magunk tudjuk, hogy az adott változó (elnevezés) mögött milyen tartalom, funkció, eredmény van. Jobb esetben ezt kommenteljük, de a kód olvasásához nekünk is memorizálni kell - feleslegesen.
Elnevezés angolul (nyelvtani helyességgel), törekedve minél beszédesebb elnevezésre, csak az általánosan elfogadott rövidítések használatával (average = avg). De gondoljunk a szóbeli kommunikációra is, kiejthetőség elve és minél kevesebb legyen.
Rossz példa:
getPmtCryByPmtId() : array
Meghatározó a neve a célja, a funkciója alapján, a benne lévő tartalom. Boolean típusnál nevezzük létigével ($isBeutifullCode, $hasBrownHair). Legyen főnév, get/set, „transaction”, „saveUserName”! Meghatározó a neve a célja, funkciója. A metódus minden esetben akció, lehet boolean típus is, ekkor létige/válasz pl. isMoreMoney() : boolean -- [true/false]. payment() vs. executePayment(). Mennyisége, egy vagy több. $user (ebben csak egy van? Ha igen helyes), $users, $userList
Metódusok (és osztályok)
Funkciók
Egy metódus (vagy függvény) egy funkció. Egyet csináljon (de azt jól). A hívó fél absztrakciós szintjén vizsgálva kell a metódust, vagy függvényt megírni. Egy egyértelmű feladat és részfeladatai. (Pure function).
Argumentumok
Maximum 3, de minél kevesebb annál jobb. Ha több, szervezd ki. Rossz példa:
public function drawCircle($x, $y, int $radius, int $red, int $green, int $blue)
{
draw [$x, $y, $radius, [$red, $gree, $blue]];
}
Helyesen:
public function DrawCircleFromObject(CenterPoint $centerPoint, CircleParams $circleParams)
{
draw [$centerPoint->points(), $circleParams->radius(), $cirlceParams->colors()];
}
class CenterPoint
{
public function points()
{
return [1,2];
}
}
class CircleParams
{
public function colors()
{
return [20, 96,130]
}
public function colors()
{
return [5]
}
}
vagy:
<?php
class MenuConfig
{
public $title;
public $body;
public $buttonText;
public $cancellable = false;
}
$config = new MenuConfig();
$config->title = 'Foo';
$config->body = 'Bar';
$config->buttonText = 'Baz';
$config->cancellable = true;
function createMenu(MenuConfig $config) {
// ...
}
Elképzelhető több munka ma, de a jövőben, ha valaki olvassa a kódot sokkal egyszerűbb lesz megérteni a működést.
Kerülni kell a flag típusú argumentumot (true/fals). Mert itt már két értékkel tér vissza, vagy ’A’-t csinál vagy ’B’-t. Máris két funkciója van.
Mellékhatások kerülése. Vagyis, ha egy metódus a hatókörén kívül „kontárkodik”.
class User {
public function checkPassword (string $username, string $password)
{
if ($this->encriptPassword($password) === $password) {
setCookie (’userLoggedIn’, true);
return true;
}
}
}
Back-Endben gyakori, hogy módosítunk, vagy változtatunk és számolunk a lekért adatokkal. Command-query separation. Vagy módosítunk vagy számolunk, sosem egyben.
PHP
Változók, paraméterek
$camelCase Nem megengedett az ’_’ (alsóvonás) használata
Metódusok
camelCase() A keretrendszer sajátosságai miatt (is) nem használható sem az ’_’ (alsóvonás), sem a ’-’ (kötőjel).
Visszatérés típus definiálása a nyelv elvárásainak megfelelően. Null (ha) visszatérése engedélyezett.
(: ?string) jól. Rövid maximum 20 sor (egy sor 150 karakter)! Egy metódus = egy képernyő elve!
Osztályok
class CamelCase A keretrendszer sajátosságai miatt (is) nem használható sem az ’_’ (alsóvonás), sem a ’-’ (kötőjel). Nagy kezdőbetűvel.
Minden esetben elfogadott a fejlesztő public hatókörre állítja a metódusokat, azonban törekedne kell a bezártságra. Osztályon belül le kell zárni a hatókört (private, protected)
MySQL
Az elnevezések kisbetűvel írandók, a logikai bontásokhoz ’_’ alsóvonás használandó. pl.: ’foo_bar_id’, ’user_working_minutes’. Azonban ne legyen hosszabb, mint 64 karakter. A sorok azonosításához auto increment ID kezdő rekord (kulcs, index) szükséges. A nyelvtani logikával nem azonos a tábla név alkotása. A felhasználókat tömörítő tábla mivel több felhasználónak ad helyet, több sorban - logikusnak tűnik a plural „elnevezés” (users), azonban a tábla önmagában egy entitás ezért többesszámban (plural) zavaros. Ezért az egyesszám elfogadott. (’user’,’comment’, stb.)
JS
Lehetőség szerint (egynél több funkció esetén) egy külső .js fájl implementálása ajánlott, kötelező. „<script> function code() </script>”, nem megengedett. Kivétel jQuery implementálása (elengedhetetlen esetekben).
Változók
camelCase Hatókör körültekintő deklarálásával. (var vs let)
CSS
Osztály (class)
Elnevezések angolul (nyelvtani helyességgel), törekedve minél beszédesebb elnevezésre, csak az általánosan elfogadott rövidítések használatával (pl. average = avg); „.dashed-speareted”.
Azonosító (id)
Használatakor figyelembe kell venni az egyediség lehetőségét. A közös tag dashed-separeted, kell lennie. Az egyedi (unque) azonosítókat az ’_’ (alsóvonás) után tegyük. Példa „#line-user-id_1”