SlideShare uma empresa Scribd logo
1 de 20
Baixar para ler offline
Objektumorientált
mérések a gyakorlatban
Orcsik Antal
Arkon Zrt.
1
Orcsik Antal vagyok, lassan 8 éve dolgozom az Arkonnál, mint PHP fejlesztő.
2000 óta foglalkozom weboldalak fejlesztésével.
5 éve vagyok a köpönyeg.hu fejlesztője.
2011. július óta futtatunk méréseket a köpönyeg kódján, rögtön elkezdett érdekelni, hogy
pontosan mi is ez, és miért jó.
• hatékonyan működjön
• legyen átlátható
• könnyen újra lehessen hasznosítani
• gyorsan lehessen bele fejleszteni
• (minél inkább dokumentálva legyen)
Milyen a jó szoftver (kód)?
2
Alapvetően a piac követeli meg, hogy a szoftvert alkotó kód:
• hatékonyan működjön
Persze attól még, hogy jól működik a szoftver nem biztos, hogy jó a kód is!
• legyen átlátható
• könnyen újra lehessen hasznosítani
• gyorsan lehessen bele fejleszteni
• (minél inkább dokumentálva legyen)
Ezeknek a szempontoknak a fontossága pedig sokszorosára növekszik, ha a webről
beszélünk, ahol a folyamatos karbantartás és fejlesztés a mindennapi munka része. Az oldalak
aktív, nagy létszámú közönséget szolgálnak ki és óhatatlanul előfordulnak hibák, amiket
villámgyorsan kell javítani. Ha lehet, már kezdetektől fogva figyelni kell erre, egy megörökölt
rendszer esetében pedig talán még fontosabb.
• Tesszük a dolgunkat és ha valami
nagyon nagy szívás, ott gond van
• Nekieshetünk átnézni az egészet,
antipatternekre vadászva
• Mérjük meg…
Honnan tudhatjuk, hogy gond van
a kódunkkal?
3
Vegyük azt az esetet, hogy már van egy rendszerünk, mivel konkrét tapasztalaim ezena téren
vannak.
Feltételezhetjük, hogy az egész kódunk azért nem egy rakás szemét, mert az már messziről
látszik. Szeretnénk tehát kideríteni, van-e olyan része amin érmes lenne a korábban említett
szempontok miatt javítani.
1. Tesszük a dolgunkat és ha valahol nagyon nagy szívás van, ott gond is van
remekül fog kinézni, mikor egy gyorsjavítás kapcsán közöljük, hogy itt lenne pár nap extra
munka, mert csúnya a kód, nem is beszélve a lehetséges függőségekről, meg arról, hogy
hány dolgot fogunk közben eltörni. Jobb lenne talán ezt megelőzni...
2. Nekieshetünk átnézni az egészet, antipatternekre vadászva
ebből már születhetnek jó ötletek, átgondolt refaktorálási storyk, de meglehetősen
időigényes dolog, és kisebb dolgok, vagy nagyobb összefüggések elkerülhetik a
figyelmünket. Biztos van valami jobb megoldás...
3. Mérjük meg…
• Chidamber & Kemerer (1994)
A metrics Suite for Object Oriented Design
• Li & Henry (1993)
Maintenance Metrics for the Object Oriented
Paradigm
• Thomas J. McCabe (1976)
A Complexity Measure
Mit, hogyan, mivel?
4
Na persze, de mégis mit, és főleg hogyan?
Nem kell nekünk feltalálni a spanyol viaszt, az objektumorientált rendszerek mérhetőségével
kapcsolatban íródott már néhány remek publikáció a '90-es években (amikre egyébként
minden későbbi hivatkozik).
• [Chid94] Chidamber & Kemerer: A metrics Suite for Object Oriented Design
• [LiHe93] Li & Henry: Maintenance Metrics for the Object Oriented Paradigm
Amik elsőként fogalmazták meg mit lehet és kell is mérni, illetve, hogy az eredményeket
hogyan értékeljük. Meg kell viszont említenünk még egy nagyon fontos művet
• [McCa76] Thomas J. McCabe: A Complexity Measure
Thomas J. McCabe '76-ban megalkotta a Ciklomatikus Komplexitás fogalmát, azóta is ez az
alapja mindennek. Erre még később részetesebben is kitérek.
• Manuel Pichler (@manuelp)
http://www.manuel-pichler.de
• phpmd (PHP Mess Detector)
http://phpmd.org
• pdepend (PHP Depend)
http://pdepend.org
Mit, hogyan, mivel?
5
Ha már tudjuk mit kell mérni, akkor már csak eszközök kellenek. Ezeket sem kell nekünk
megírni, ezt megtette már helyettünk
Manuel Pichler (@manuelp) - http://www.manuel-pichler.de
Maguk az eszközök pedig:
• phpmd (PHP Mess Detector) - 2009
• pdepend (PHP Depend) - 2011
A pdepend Java és C programozók számára ismerős lehet, ezekhez a nyelvekhez is létezik ez
az eszköz.
Először a Mess Detectorról lesz szó.
• Unused Code Rules
• Unused Formal Parameter
• Unused Private Method
• Unused Private Field
• Unused Local Variable
PHP Mess Detector Rules 1.
function example($a, $b) {
return $a * 2;
}
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
6
A phpmd arra való, hogy feltérképezze a kódunkat és szóljon, ha valami szerinte nincs
rendben. A több tucat csomagokba rendezett szabály van, melyeket a kódunkra
alkalmazhatunk. A teljes lista elérhető a pmd online dokumentációjában (http://phpmd.org/
rules/index.html), lássunk a fontosabb csoportokat és néhány szabályt, amit én is használok:
• Unused Code Rules, nem használt kódrészletek
◦ Unused Formal Parameter
◦ Unused Private Method
◦ Unused Private Field
◦ Unused Local Variable
Ezek ugyan nem tűnnek komoly dolgoknak, de sokszor segítettek egy-egy hiba
felfedezésében. Volt egy eset, mikor elírtam egy változó nevét egy metódusban, a pmd pedig
szólt, hogy nem használom a metódus egyik paraméterét. Ezek sárga színnel jelennek meg a
listában, és csak figyelmeztetések, de kijavításuk általában egyszerű így ezt érdemes minél
hamarabb megtenni!
Vannak szükségtelennek tűnő figyelmeztetések is, pl. mikor egy interface megkövetel egy
paramétert a metódusban, de mi azt nem használjuk. Itt trükközhetünk is, de pont az ilyen
esetekre létezik a metódus vagy osztály szintű szabály elnyomás, amit a fejléc commentbe kell
tenni.
• Naming Rules
• Controversial Rules
• Design Rules
• Code Size Rules
• Exessive Method Length
• Cyclomatic Complexity
PHP Mess Detector Rules 2.
7
• Naming Rules
• Controversial Rules
Ezek a szabályok a metódusok és változók elnevezéseivel és használatával kapcsolatos
következetességre figyelnek, túl rövid vagy hoszzú változónevek, CamelCase, getX(), isX().
• Design Rules
Ezek arra figyelnek, hogy ne legyen a kódban exit, eval vagy goto, illetve bizonyos
öröklődéssel kapcsolatos jellemzőket, amikről majd később még lesz szó.
• Code Size Rules, pedig a kód méretével kapcsolatos szabályokat tartalmazza, pl.:
◦ Exessive Method Length, a különösen hosszú metódusokat nézi
◦ Cyclomatic Complexity, ami a metódusok Ciklomatikus Komplexitását figyeli, térjünk is
ki egy kicsit erre
• E: élek (5)
• N: pontok (5)
• P: kilépési pontok (1)
Cyclomatic Complexity 1.
CYCLO = E - N + 2P = 2
8
Korábban már említettem, hogy bizonyos Thomas McCabe nevéhez fűződik ez az érték. Ezzel
lehet a legjobban jellemezni egy kódrészlet, metódus vagy osztály bonyolultságát. Nem nehéz
kiszámolni sem, képzeljünk el a folyamat ábrát. Ez ugye egy gráf, élekkel és pontokkal. Ebből
a Ciklomatikus Komplexitást úgy kapjuk meg, ha az élek számából kivonjuk a pontok számát
és hozzáadjuk a kilépési pontok számának kétszeresét.
• E: élek
• N: pontok
• P: kilépési pontok
CYCLO = E - N + 2P
Cyclomatic Complexity 2.
function example($a) {
if ($a) {
for ($i=1;$i<$a;$i++) {
if ($i%2 && $a>10) {
echo $i;
}
}
}
}
• minden metódus alaból 1
• minden elágazás és kör +1
9
Na pesze senki ne ijedjen meg, lehet ezt egyszerűbben is:
• minden metódus komplexitása alapból 1
• amihez annyiszor adunk még egyet, ahány elágazás és kör van a kódban
Egy metódus komplexitása annak bonyolultságát határozza meg. Egy túlságosan komplex
metódus valószínűleg többet csinál, mint amit kéne neki, érdemes lehet szétszedni több
részre. Na de, mi számít túlságosan komplexnek? Mondjuk a 10.
Mikor 2011-ben bevezettük a phpmd-t, én is elkezdtem figyelni erre a dologra, és ma már úgy
kódolok, hogy fejben számolom a komplexitást. Ha egy metódus eléri a 10-et, akkor újra
átgondolom amit csinálok, és sok esetben sikerül egy nagyobb részletet kiszervezni úgy, hogy
azt máshol is fel tudom használni. Ezen felül leszoktat a terjengős elágazás erdőkről, és
megtanít rá, hogy kétszer is meggondoljuk mit és mikor vizsgálunk.
Cyclomatic Complexity 3.
if ($cond) {
$result = 1;
} else {
$result = 0;
}
$result = 0;
if ($cond) {
$result = 1;
}
switch ($cond) {
case “a”: $x = 1; break;
case “b”: $x = 2; break;
default: $x = 3;
}
$switch = array(
“a” => 1,
“b” => 2,
);
$x = 3;
if (isset($switch[$cond])) {
$x = $switch[$cond];
}
10
Mutatok még két nagyon egyszerű példát, komplexitás csökkentésre.
Tapasztalat
11
A szabályok finomhangolása után a köpönyeg nagyjából 400 pmd hibát tartalmazott, amit az
elmúlt egy évben refaktorálással körülbelül 100-ra csökkentettem, és a cél természetesen,
hogy végül egy se maradjon, bár vannak tipikusan kihívást jelentő komplexitás és metódus
hossz hibák.
Egyik-másik parser vagy ábra rajzoló a 20-30 komplexitást is eléri, amit csak igen kemény
munkával lehet rendbetenni.
PHP Depend
Áttekintő piramis
Absztrakció
Instabilitás
grafikon
12
Térjünk át akkor a következő eszközre.
A korábban említett publikációk számos értéket határoznak meg, a PHP Depend, a
dokumentéciója szerint (http://pdepend.org/documentation/software-metrics/index.html), közel
40 olyan metrika kiszámítására képes, amikből a kódunk minőségére következtethetünk,
viszont most csak néhányat emelnék ki.
A program két összefoglaló ábrát készít a kódunkról
• az Áttekintő piramist és
• az Absztrakció Instabilitás grafikont
Kezdjük az előzővel.
Piramis - Code Size
• CYCLO: Cyclomatic Complexity
• LOC: Lines of Code
• NOM: Number of Methods
• NOC: Number of Classes
• NOP: Number of Packages (Namespaces)
13
A piramis három sarka három mérési kategóriát jelöl, bennük pedig a mért adatok és az azok
hányadosaiból számolt értékes metrikák találhatóak:
• Code Size (a kód méretei) A komplexitás mellet nagyon fontos még a kód mérete, amit
PHP esetén négy értékkel határozunk meg:
◦ CYCLO: Cyclomatic Complexity, ismét itt
◦ LOC: Lines of Code, azaz a sorok száma
◦ NOM: Number of Methods, azaz a metódusok száma
◦ NOC: Number of Classes, azaz az osztályok száma
◦ NOP: Number of Packages (Namespaces), azaz a csomagok, vagy 5.3 óta a
névterek száma
Ezeknek viszont a hányadosai hordozzák a fontos információt.
A CYCLO/LOC egy sor átlagos komplexitása a LOC/NOM pedig egy metódus átlagos hossza.
Az előző 0.2 alatt van, az utóbbi pedig 13 alatt, akkor vagyunk a zöldben, de ez azt is jelenti,
hogy átlagosan 2,6 komplexitása lehet egy metódusnak, ha a zöldben szeretnénk maradni. Ez
jóval kevesebb, mint a 10, amit a phpmd-nél mondtam, de látszik, hogy arra kell törekedni,
hogy minél egyszerűbb és érthetőbb legyen egy metódus.
Nekem a LOC/NOM okozta a legtöbb gondot, mert a köpönyeg elég sok procedurális kódot
tartalmazott az MVC átírás előtt. Konkrétan 26-ról kellett szépen lassan ezt a számot lefelé
terelgetni.
Ököl szabály, hogy a kisebb jobb. Szóval a legjobb a kódunk akkor lesz, ha minél több
névteret hozunk létre, bennük lehetőleg kevés osztályt, néhány egyszerű és rövid metódussal.
Ezzel így valami nem stimmel, de majd később visszatérünk erre.
Piramis - Coupling
• CALLS: metódus hívások
• FANOUT: típus kényszer,
a rendszer más részéből
14
• Coupling (kapcsolódás) a program egyes részei közötti kapcsolatot is mérhetjük
◦ CALLS: ez különálló metódushívások száma
◦ FANOUT: ez pedig a metódusok paraméterlistájában lévő típus kényszereket számolja,
ha azok az alkalmazás egy másik ágához kapcsolódnak
A kapcsolódás már keményebb dió, itt azt kell megértenünk, hogy ha a CALLS/NOM, azaz a
kapcsolódás intenzitása, nagy az azt jelenti, hogy az egész szoftverünk durván néhány
metódusból áll, amik folyton egymást hívogatják. Ez arra utalhat, hogy nagyon kusza a
szoftverünk részegységei közötti kapcsolat, ami nem csak a hibák felderítésében okozhat
gondokat, de egy apró baki is képes lehet rendszer szintű gondokat okozni.
Piramis - Inheritance
• ANDC: Average Number of
Derived Classes (szélesség,
intenzitás)
• AHH: Average Hierarchy
Height (mélység)
15
Itt nincsenek hányadosok, ezt a két átlagot önmagában kell vizsgálnunk. Itt is érvényes az
ökölszabály, hogy a zöld a jobb, de árnyaltabb a kép.
• Inheritance (öröklődés) az öröklődést is leírhatjuk két értékkel
◦ ANDC: Average Number of Derived Classes, azaz a származtatott osztályok átlagos
száma. Ez az osztályok számának súlyozott átlaga, ahol minden osztály súlya a
közvetlen leszármazottainak száma.
Ez a szám az örökési rendszerünk szélességét mutatja meg, hogy mennyire vesszük
igénybe az öröklést, és annál kisebb, minél több a gyermektelen osztály.
◦ AHH: Average Hierarchy Height, azaz az öröklési hierachia átlagos magassága. Ez a
gyökér osztályok számának súlyozott átlaga, ahol minden osztály súlya a belőle kiinduló
öröklési fa legnagyobb mélysége.
Ez a szám pedig a arról tájékoztat, milyen mennyire mélyek az öröklések, és annál
kisebb, minél kevesebb a mély öröklési fa.
Az ANDC esetében pl. csúnyán a narancsba kerülünk, ha egy db absztrakt objektumból
örököltetünk mindent. De hát, miért ne tennénk, láttunk már ilyet, hogy minden egy Base object
leszármazottja, és ennek megvannak a jó oldalai is. Ennek ellenére ez a mérési rendszer azt
javasolja, az osztályaink inkább legyenek különállóak, mintsem egy terebélyes hierachia
részei, a pmd még figyelmeztetni is tud, ha ilyesmire utaló jeleket talál!
PHP Depend - Low, Avg, High!
16
Ez is most nagyon furcsa, hiszen van nagyon jó és szép rendszer, ami intenzíven alkalmazza
az öröklést, akkor ez mégis miért rossz? Nem az.
Nézzük meg a színkódot:
szürke: alacsony
zöld: átlagos
narancs: magas
A piramis öröklés sarkára különsen igaz, de a többire is, hogy a narancs nem “rossz”, hanem
“magas”. Ez az ábra pedig nem azt mutatja meg, hogy a kódunk milyen rossz vagy jó, hanem
azt, hogy “milyen”. Áttekintést ad arról, hogy a kódunkban milyen intenzitással használunk
öröklést, óriási osztályink, vagy csak kicsik, hosszú rövidek-e a metódusaink vagy hosszúak
és bonyolultak?
Nagyon jó, ha a piramisunk zöld, de nem cél! Ne felejtsük el, hogy az ideák kergetésében
nagyon könnyű szemelől téveszteni a célt.
Absztrakció és Instabilitás 1.
• ac: absztrakt osztályok
• cc: konkrét osztályok
A = ac / (ac + cc)
• Ce: efferens kapcsolatok
• Ca: afferens kapcsolatok
I = Ce / (Ce + Ca)
17
Ezen a látványos ábrán az egyes csomagokat (névtereket) láthatjuk az absztrakciójuk,
instabilitásuk és méretük függvényében.
Az absztrakció egyszerű, a csomagban található absztakt osztályok aránya az összeshez.
Minél több van belőlük, annál inkább jobbra helyezkedik el a kis golyó az ábrán.
A = ac / (ac + cc)
Az instabilitás már bonyolultabb. Vannak az Afferens kapcsolatok, azok a csomagok, amik
valahogy függenek a vizsgált csomag osztályaitól, illetve az Efferens kapcsolatok, azok a
csomagok, amiktől valahogy függenek a vizsgált csomag osztályai.
• Ca: Afferent Couplings, amik tőlem függenek
• Ce: Efferent Couplings, amiktől én függők
Az instabilitást úgy számolhatjuk ki, hogy az osztály saját függőségeinek számát elosztjuk az
összes függőséggel, vagyis egy csomag instabil, ha több indetől függ, mint amennyien tőle
függenek.
I = Ce / (Ce + Ca)
Absztrakció és Instabilitás 2.
?
18
Egy csomag akkor van az ideális zónában, ha az instabilitás és az absztrakció összege 1. Teht
egy olyam csomag, ami főleg másoktól függ, tipikusan ilyenek a kontrollerek, azokban ne
legyen túlsúlyban az absztrakt osztályok száma a konkrétakkal szemben. A másik oldalon
viszont, ha egy csomag főként absztrakt csomagokból áll, akkor inkább tőle függjenek más
csomagok, azaz legyen minél inkább stabil.
Jellemző, hogy olyan absztrakt csomag, amitől semmi nem függ nem vagyon van, hisz ki
gyártana ilyen csomagot?
Az már gyakrabban fordul elő, hogy egy konkrét csomag nem függ semmitől, sőt talán még
tőle függenek. Ezeket célszerű megvizsgálni és valahogy átszervezni.
Összefoglalás
• Előnyök
• sokkal gyorsabb, mint bármi más
• aprólékos (pmd)
• átfogó kép (pdepend)
• Hátrányok
• néha szigorú és ellentmondásos
19
A bemutatott két eszköz kiválóan alkalmas arra, hogy viszonylag gyorsan adjon információt a
kód állapotával kapcsolatban. Nálunk minden buildnek része, hogy ezek a mérések lefutnak,
hogy legalább élesítés előtt mindenképp lássuk, mit is csináltunk. Ha figyeljük a számokat
könnyen észrevehetjük, ha rossz irányba haladunk.
Előnyök
Hátrányok
Mindenképp javaslom, hogy futtassátok le ezeket a saját rendszereiteken is, ha még nem
tettétek és fontoljátok meg, hogy a talált problémákat kijavítsátok.
A személyes tapasztalatom, hogy az elmúlt évben úgy fejlesztettem, hogy ezeket szem előtt
tartottam és a köpönyeg ma sokkal jobb állapotban van, mint előtte, és fejleszteni is könnyebb.
Kérdések?
Orcsik Antal
http://blog.intiweb.hu/
aorcsik@gmail.com
@aorcsik
20

Mais conteúdo relacionado

Semelhante a Objektum-orinetált mérések a gyakorlatban

A mérnökké válás folyamata
A mérnökké válás folyamataA mérnökké válás folyamata
A mérnökké válás folyamatawaxey.gordon
 
Gonosz IkertestvéRek
Gonosz IkertestvéRekGonosz IkertestvéRek
Gonosz IkertestvéRekC4M7SX
 
Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...
Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...
Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...META-INF Kft.
 
Webalkalmazások teljesítményoptimalizálása
Webalkalmazások teljesítményoptimalizálásaWebalkalmazások teljesítményoptimalizálása
Webalkalmazások teljesítményoptimalizálásaFerenc Kovács
 
Szerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelvenSzerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelvenKrisztián Gyula Tóth
 
II. Elmélet - ERP rendszerek árazása.pptx
II. Elmélet - ERP rendszerek árazása.pptxII. Elmélet - ERP rendszerek árazása.pptx
II. Elmélet - ERP rendszerek árazása.pptxSzabolcs Gulyás
 
Szoftver bevezetés problémái
Szoftver bevezetés problémáiSzoftver bevezetés problémái
Szoftver bevezetés problémáitbodocz
 
III. Elmélet - Az ERP rendszerek implementációja 1..pptx
III. Elmélet - Az ERP rendszerek implementációja 1..pptxIII. Elmélet - Az ERP rendszerek implementációja 1..pptx
III. Elmélet - Az ERP rendszerek implementációja 1..pptxSzabolcs Gulyás
 
Cgi röviden ajmar
Cgi röviden ajmarCgi röviden ajmar
Cgi röviden ajmarbonami2014
 
Webműves Kelemen tanácsai, avagy mi kell a PHP falába?
Webműves Kelemen tanácsai, avagy mi kell a PHP falába?Webműves Kelemen tanácsai, avagy mi kell a PHP falába?
Webműves Kelemen tanácsai, avagy mi kell a PHP falába?Open Academy
 
Devops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztekDevops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztekZsolt Takács
 
I. Elmélet - Általános ismertető a ERP rendszerekről.pptx
I. Elmélet -  Általános ismertető a ERP rendszerekről.pptxI. Elmélet -  Általános ismertető a ERP rendszerekről.pptx
I. Elmélet - Általános ismertető a ERP rendszerekről.pptxSzabolcs Gulyás
 
GN4-UP2U update - Moodlemoot19
GN4-UP2U update - Moodlemoot19GN4-UP2U update - Moodlemoot19
GN4-UP2U update - Moodlemoot19Mihály Mészáros
 
Mitol konnektivista egy képzés
Mitol konnektivista egy képzésMitol konnektivista egy képzés
Mitol konnektivista egy képzésZsolt Kulcsár
 
CMS en túli webes megoldások
CMS en túli webes megoldásokCMS en túli webes megoldások
CMS en túli webes megoldásokTamas Rigo
 
IV. Elmélet - Az ERP rendszerek implementációja 2..pptx
IV. Elmélet - Az ERP rendszerek implementációja 2..pptxIV. Elmélet - Az ERP rendszerek implementációja 2..pptx
IV. Elmélet - Az ERP rendszerek implementációja 2..pptxSzabolcs Gulyás
 
VI. Elmélet - Kitekintés az ERP-n túlra .pptx
VI. Elmélet - Kitekintés az ERP-n túlra .pptxVI. Elmélet - Kitekintés az ERP-n túlra .pptx
VI. Elmélet - Kitekintés az ERP-n túlra .pptxSzabolcs Gulyás
 

Semelhante a Objektum-orinetált mérések a gyakorlatban (20)

A mérnökké válás folyamata
A mérnökké válás folyamataA mérnökké válás folyamata
A mérnökké válás folyamata
 
Gonosz IkertestvéRek
Gonosz IkertestvéRekGonosz IkertestvéRek
Gonosz IkertestvéRek
 
Budapest.rb 201010
Budapest.rb 201010Budapest.rb 201010
Budapest.rb 201010
 
Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...
Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...
Béla, mi élesedett tulajdonképpen? A request to release koncepció mire is ad ...
 
Webalkalmazások teljesítményoptimalizálása
Webalkalmazások teljesítményoptimalizálásaWebalkalmazások teljesítményoptimalizálása
Webalkalmazások teljesítményoptimalizálása
 
Szerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelvenSzerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelven
 
Szoftver tesztelés
Szoftver tesztelésSzoftver tesztelés
Szoftver tesztelés
 
II. Elmélet - ERP rendszerek árazása.pptx
II. Elmélet - ERP rendszerek árazása.pptxII. Elmélet - ERP rendszerek árazása.pptx
II. Elmélet - ERP rendszerek árazása.pptx
 
Szoftver bevezetés problémái
Szoftver bevezetés problémáiSzoftver bevezetés problémái
Szoftver bevezetés problémái
 
III. Elmélet - Az ERP rendszerek implementációja 1..pptx
III. Elmélet - Az ERP rendszerek implementációja 1..pptxIII. Elmélet - Az ERP rendszerek implementációja 1..pptx
III. Elmélet - Az ERP rendszerek implementációja 1..pptx
 
Cgi röviden ajmar
Cgi röviden ajmarCgi röviden ajmar
Cgi röviden ajmar
 
A.5 tudasbazisok
A.5 tudasbazisokA.5 tudasbazisok
A.5 tudasbazisok
 
Webműves Kelemen tanácsai, avagy mi kell a PHP falába?
Webműves Kelemen tanácsai, avagy mi kell a PHP falába?Webműves Kelemen tanácsai, avagy mi kell a PHP falába?
Webműves Kelemen tanácsai, avagy mi kell a PHP falába?
 
Devops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztekDevops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztek
 
I. Elmélet - Általános ismertető a ERP rendszerekről.pptx
I. Elmélet -  Általános ismertető a ERP rendszerekről.pptxI. Elmélet -  Általános ismertető a ERP rendszerekről.pptx
I. Elmélet - Általános ismertető a ERP rendszerekről.pptx
 
GN4-UP2U update - Moodlemoot19
GN4-UP2U update - Moodlemoot19GN4-UP2U update - Moodlemoot19
GN4-UP2U update - Moodlemoot19
 
Mitol konnektivista egy képzés
Mitol konnektivista egy képzésMitol konnektivista egy képzés
Mitol konnektivista egy képzés
 
CMS en túli webes megoldások
CMS en túli webes megoldásokCMS en túli webes megoldások
CMS en túli webes megoldások
 
IV. Elmélet - Az ERP rendszerek implementációja 2..pptx
IV. Elmélet - Az ERP rendszerek implementációja 2..pptxIV. Elmélet - Az ERP rendszerek implementációja 2..pptx
IV. Elmélet - Az ERP rendszerek implementációja 2..pptx
 
VI. Elmélet - Kitekintés az ERP-n túlra .pptx
VI. Elmélet - Kitekintés az ERP-n túlra .pptxVI. Elmélet - Kitekintés az ERP-n túlra .pptx
VI. Elmélet - Kitekintés az ERP-n túlra .pptx
 

Objektum-orinetált mérések a gyakorlatban

  • 1. Objektumorientált mérések a gyakorlatban Orcsik Antal Arkon Zrt. 1 Orcsik Antal vagyok, lassan 8 éve dolgozom az Arkonnál, mint PHP fejlesztő. 2000 óta foglalkozom weboldalak fejlesztésével. 5 éve vagyok a köpönyeg.hu fejlesztője. 2011. július óta futtatunk méréseket a köpönyeg kódján, rögtön elkezdett érdekelni, hogy pontosan mi is ez, és miért jó.
  • 2. • hatékonyan működjön • legyen átlátható • könnyen újra lehessen hasznosítani • gyorsan lehessen bele fejleszteni • (minél inkább dokumentálva legyen) Milyen a jó szoftver (kód)? 2 Alapvetően a piac követeli meg, hogy a szoftvert alkotó kód: • hatékonyan működjön Persze attól még, hogy jól működik a szoftver nem biztos, hogy jó a kód is! • legyen átlátható • könnyen újra lehessen hasznosítani • gyorsan lehessen bele fejleszteni • (minél inkább dokumentálva legyen) Ezeknek a szempontoknak a fontossága pedig sokszorosára növekszik, ha a webről beszélünk, ahol a folyamatos karbantartás és fejlesztés a mindennapi munka része. Az oldalak aktív, nagy létszámú közönséget szolgálnak ki és óhatatlanul előfordulnak hibák, amiket villámgyorsan kell javítani. Ha lehet, már kezdetektől fogva figyelni kell erre, egy megörökölt rendszer esetében pedig talán még fontosabb.
  • 3. • Tesszük a dolgunkat és ha valami nagyon nagy szívás, ott gond van • Nekieshetünk átnézni az egészet, antipatternekre vadászva • Mérjük meg… Honnan tudhatjuk, hogy gond van a kódunkkal? 3 Vegyük azt az esetet, hogy már van egy rendszerünk, mivel konkrét tapasztalaim ezena téren vannak. Feltételezhetjük, hogy az egész kódunk azért nem egy rakás szemét, mert az már messziről látszik. Szeretnénk tehát kideríteni, van-e olyan része amin érmes lenne a korábban említett szempontok miatt javítani. 1. Tesszük a dolgunkat és ha valahol nagyon nagy szívás van, ott gond is van remekül fog kinézni, mikor egy gyorsjavítás kapcsán közöljük, hogy itt lenne pár nap extra munka, mert csúnya a kód, nem is beszélve a lehetséges függőségekről, meg arról, hogy hány dolgot fogunk közben eltörni. Jobb lenne talán ezt megelőzni... 2. Nekieshetünk átnézni az egészet, antipatternekre vadászva ebből már születhetnek jó ötletek, átgondolt refaktorálási storyk, de meglehetősen időigényes dolog, és kisebb dolgok, vagy nagyobb összefüggések elkerülhetik a figyelmünket. Biztos van valami jobb megoldás... 3. Mérjük meg…
  • 4. • Chidamber & Kemerer (1994) A metrics Suite for Object Oriented Design • Li & Henry (1993) Maintenance Metrics for the Object Oriented Paradigm • Thomas J. McCabe (1976) A Complexity Measure Mit, hogyan, mivel? 4 Na persze, de mégis mit, és főleg hogyan? Nem kell nekünk feltalálni a spanyol viaszt, az objektumorientált rendszerek mérhetőségével kapcsolatban íródott már néhány remek publikáció a '90-es években (amikre egyébként minden későbbi hivatkozik). • [Chid94] Chidamber & Kemerer: A metrics Suite for Object Oriented Design • [LiHe93] Li & Henry: Maintenance Metrics for the Object Oriented Paradigm Amik elsőként fogalmazták meg mit lehet és kell is mérni, illetve, hogy az eredményeket hogyan értékeljük. Meg kell viszont említenünk még egy nagyon fontos művet • [McCa76] Thomas J. McCabe: A Complexity Measure Thomas J. McCabe '76-ban megalkotta a Ciklomatikus Komplexitás fogalmát, azóta is ez az alapja mindennek. Erre még később részetesebben is kitérek.
  • 5. • Manuel Pichler (@manuelp) http://www.manuel-pichler.de • phpmd (PHP Mess Detector) http://phpmd.org • pdepend (PHP Depend) http://pdepend.org Mit, hogyan, mivel? 5 Ha már tudjuk mit kell mérni, akkor már csak eszközök kellenek. Ezeket sem kell nekünk megírni, ezt megtette már helyettünk Manuel Pichler (@manuelp) - http://www.manuel-pichler.de Maguk az eszközök pedig: • phpmd (PHP Mess Detector) - 2009 • pdepend (PHP Depend) - 2011 A pdepend Java és C programozók számára ismerős lehet, ezekhez a nyelvekhez is létezik ez az eszköz. Először a Mess Detectorról lesz szó.
  • 6. • Unused Code Rules • Unused Formal Parameter • Unused Private Method • Unused Private Field • Unused Local Variable PHP Mess Detector Rules 1. function example($a, $b) { return $a * 2; } /** * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ 6 A phpmd arra való, hogy feltérképezze a kódunkat és szóljon, ha valami szerinte nincs rendben. A több tucat csomagokba rendezett szabály van, melyeket a kódunkra alkalmazhatunk. A teljes lista elérhető a pmd online dokumentációjában (http://phpmd.org/ rules/index.html), lássunk a fontosabb csoportokat és néhány szabályt, amit én is használok: • Unused Code Rules, nem használt kódrészletek ◦ Unused Formal Parameter ◦ Unused Private Method ◦ Unused Private Field ◦ Unused Local Variable Ezek ugyan nem tűnnek komoly dolgoknak, de sokszor segítettek egy-egy hiba felfedezésében. Volt egy eset, mikor elírtam egy változó nevét egy metódusban, a pmd pedig szólt, hogy nem használom a metódus egyik paraméterét. Ezek sárga színnel jelennek meg a listában, és csak figyelmeztetések, de kijavításuk általában egyszerű így ezt érdemes minél hamarabb megtenni! Vannak szükségtelennek tűnő figyelmeztetések is, pl. mikor egy interface megkövetel egy paramétert a metódusban, de mi azt nem használjuk. Itt trükközhetünk is, de pont az ilyen esetekre létezik a metódus vagy osztály szintű szabály elnyomás, amit a fejléc commentbe kell tenni.
  • 7. • Naming Rules • Controversial Rules • Design Rules • Code Size Rules • Exessive Method Length • Cyclomatic Complexity PHP Mess Detector Rules 2. 7 • Naming Rules • Controversial Rules Ezek a szabályok a metódusok és változók elnevezéseivel és használatával kapcsolatos következetességre figyelnek, túl rövid vagy hoszzú változónevek, CamelCase, getX(), isX(). • Design Rules Ezek arra figyelnek, hogy ne legyen a kódban exit, eval vagy goto, illetve bizonyos öröklődéssel kapcsolatos jellemzőket, amikről majd később még lesz szó. • Code Size Rules, pedig a kód méretével kapcsolatos szabályokat tartalmazza, pl.: ◦ Exessive Method Length, a különösen hosszú metódusokat nézi ◦ Cyclomatic Complexity, ami a metódusok Ciklomatikus Komplexitását figyeli, térjünk is ki egy kicsit erre
  • 8. • E: élek (5) • N: pontok (5) • P: kilépési pontok (1) Cyclomatic Complexity 1. CYCLO = E - N + 2P = 2 8 Korábban már említettem, hogy bizonyos Thomas McCabe nevéhez fűződik ez az érték. Ezzel lehet a legjobban jellemezni egy kódrészlet, metódus vagy osztály bonyolultságát. Nem nehéz kiszámolni sem, képzeljünk el a folyamat ábrát. Ez ugye egy gráf, élekkel és pontokkal. Ebből a Ciklomatikus Komplexitást úgy kapjuk meg, ha az élek számából kivonjuk a pontok számát és hozzáadjuk a kilépési pontok számának kétszeresét. • E: élek • N: pontok • P: kilépési pontok CYCLO = E - N + 2P
  • 9. Cyclomatic Complexity 2. function example($a) { if ($a) { for ($i=1;$i<$a;$i++) { if ($i%2 && $a>10) { echo $i; } } } } • minden metódus alaból 1 • minden elágazás és kör +1 9 Na pesze senki ne ijedjen meg, lehet ezt egyszerűbben is: • minden metódus komplexitása alapból 1 • amihez annyiszor adunk még egyet, ahány elágazás és kör van a kódban Egy metódus komplexitása annak bonyolultságát határozza meg. Egy túlságosan komplex metódus valószínűleg többet csinál, mint amit kéne neki, érdemes lehet szétszedni több részre. Na de, mi számít túlságosan komplexnek? Mondjuk a 10. Mikor 2011-ben bevezettük a phpmd-t, én is elkezdtem figyelni erre a dologra, és ma már úgy kódolok, hogy fejben számolom a komplexitást. Ha egy metódus eléri a 10-et, akkor újra átgondolom amit csinálok, és sok esetben sikerül egy nagyobb részletet kiszervezni úgy, hogy azt máshol is fel tudom használni. Ezen felül leszoktat a terjengős elágazás erdőkről, és megtanít rá, hogy kétszer is meggondoljuk mit és mikor vizsgálunk.
  • 10. Cyclomatic Complexity 3. if ($cond) { $result = 1; } else { $result = 0; } $result = 0; if ($cond) { $result = 1; } switch ($cond) { case “a”: $x = 1; break; case “b”: $x = 2; break; default: $x = 3; } $switch = array( “a” => 1, “b” => 2, ); $x = 3; if (isset($switch[$cond])) { $x = $switch[$cond]; } 10 Mutatok még két nagyon egyszerű példát, komplexitás csökkentésre.
  • 11. Tapasztalat 11 A szabályok finomhangolása után a köpönyeg nagyjából 400 pmd hibát tartalmazott, amit az elmúlt egy évben refaktorálással körülbelül 100-ra csökkentettem, és a cél természetesen, hogy végül egy se maradjon, bár vannak tipikusan kihívást jelentő komplexitás és metódus hossz hibák. Egyik-másik parser vagy ábra rajzoló a 20-30 komplexitást is eléri, amit csak igen kemény munkával lehet rendbetenni.
  • 12. PHP Depend Áttekintő piramis Absztrakció Instabilitás grafikon 12 Térjünk át akkor a következő eszközre. A korábban említett publikációk számos értéket határoznak meg, a PHP Depend, a dokumentéciója szerint (http://pdepend.org/documentation/software-metrics/index.html), közel 40 olyan metrika kiszámítására képes, amikből a kódunk minőségére következtethetünk, viszont most csak néhányat emelnék ki. A program két összefoglaló ábrát készít a kódunkról • az Áttekintő piramist és • az Absztrakció Instabilitás grafikont Kezdjük az előzővel.
  • 13. Piramis - Code Size • CYCLO: Cyclomatic Complexity • LOC: Lines of Code • NOM: Number of Methods • NOC: Number of Classes • NOP: Number of Packages (Namespaces) 13 A piramis három sarka három mérési kategóriát jelöl, bennük pedig a mért adatok és az azok hányadosaiból számolt értékes metrikák találhatóak: • Code Size (a kód méretei) A komplexitás mellet nagyon fontos még a kód mérete, amit PHP esetén négy értékkel határozunk meg: ◦ CYCLO: Cyclomatic Complexity, ismét itt ◦ LOC: Lines of Code, azaz a sorok száma ◦ NOM: Number of Methods, azaz a metódusok száma ◦ NOC: Number of Classes, azaz az osztályok száma ◦ NOP: Number of Packages (Namespaces), azaz a csomagok, vagy 5.3 óta a névterek száma Ezeknek viszont a hányadosai hordozzák a fontos információt. A CYCLO/LOC egy sor átlagos komplexitása a LOC/NOM pedig egy metódus átlagos hossza. Az előző 0.2 alatt van, az utóbbi pedig 13 alatt, akkor vagyunk a zöldben, de ez azt is jelenti, hogy átlagosan 2,6 komplexitása lehet egy metódusnak, ha a zöldben szeretnénk maradni. Ez jóval kevesebb, mint a 10, amit a phpmd-nél mondtam, de látszik, hogy arra kell törekedni, hogy minél egyszerűbb és érthetőbb legyen egy metódus. Nekem a LOC/NOM okozta a legtöbb gondot, mert a köpönyeg elég sok procedurális kódot tartalmazott az MVC átírás előtt. Konkrétan 26-ról kellett szépen lassan ezt a számot lefelé terelgetni. Ököl szabály, hogy a kisebb jobb. Szóval a legjobb a kódunk akkor lesz, ha minél több névteret hozunk létre, bennük lehetőleg kevés osztályt, néhány egyszerű és rövid metódussal. Ezzel így valami nem stimmel, de majd később visszatérünk erre.
  • 14. Piramis - Coupling • CALLS: metódus hívások • FANOUT: típus kényszer, a rendszer más részéből 14 • Coupling (kapcsolódás) a program egyes részei közötti kapcsolatot is mérhetjük ◦ CALLS: ez különálló metódushívások száma ◦ FANOUT: ez pedig a metódusok paraméterlistájában lévő típus kényszereket számolja, ha azok az alkalmazás egy másik ágához kapcsolódnak A kapcsolódás már keményebb dió, itt azt kell megértenünk, hogy ha a CALLS/NOM, azaz a kapcsolódás intenzitása, nagy az azt jelenti, hogy az egész szoftverünk durván néhány metódusból áll, amik folyton egymást hívogatják. Ez arra utalhat, hogy nagyon kusza a szoftverünk részegységei közötti kapcsolat, ami nem csak a hibák felderítésében okozhat gondokat, de egy apró baki is képes lehet rendszer szintű gondokat okozni.
  • 15. Piramis - Inheritance • ANDC: Average Number of Derived Classes (szélesség, intenzitás) • AHH: Average Hierarchy Height (mélység) 15 Itt nincsenek hányadosok, ezt a két átlagot önmagában kell vizsgálnunk. Itt is érvényes az ökölszabály, hogy a zöld a jobb, de árnyaltabb a kép. • Inheritance (öröklődés) az öröklődést is leírhatjuk két értékkel ◦ ANDC: Average Number of Derived Classes, azaz a származtatott osztályok átlagos száma. Ez az osztályok számának súlyozott átlaga, ahol minden osztály súlya a közvetlen leszármazottainak száma. Ez a szám az örökési rendszerünk szélességét mutatja meg, hogy mennyire vesszük igénybe az öröklést, és annál kisebb, minél több a gyermektelen osztály. ◦ AHH: Average Hierarchy Height, azaz az öröklési hierachia átlagos magassága. Ez a gyökér osztályok számának súlyozott átlaga, ahol minden osztály súlya a belőle kiinduló öröklési fa legnagyobb mélysége. Ez a szám pedig a arról tájékoztat, milyen mennyire mélyek az öröklések, és annál kisebb, minél kevesebb a mély öröklési fa. Az ANDC esetében pl. csúnyán a narancsba kerülünk, ha egy db absztrakt objektumból örököltetünk mindent. De hát, miért ne tennénk, láttunk már ilyet, hogy minden egy Base object leszármazottja, és ennek megvannak a jó oldalai is. Ennek ellenére ez a mérési rendszer azt javasolja, az osztályaink inkább legyenek különállóak, mintsem egy terebélyes hierachia részei, a pmd még figyelmeztetni is tud, ha ilyesmire utaló jeleket talál!
  • 16. PHP Depend - Low, Avg, High! 16 Ez is most nagyon furcsa, hiszen van nagyon jó és szép rendszer, ami intenzíven alkalmazza az öröklést, akkor ez mégis miért rossz? Nem az. Nézzük meg a színkódot: szürke: alacsony zöld: átlagos narancs: magas A piramis öröklés sarkára különsen igaz, de a többire is, hogy a narancs nem “rossz”, hanem “magas”. Ez az ábra pedig nem azt mutatja meg, hogy a kódunk milyen rossz vagy jó, hanem azt, hogy “milyen”. Áttekintést ad arról, hogy a kódunkban milyen intenzitással használunk öröklést, óriási osztályink, vagy csak kicsik, hosszú rövidek-e a metódusaink vagy hosszúak és bonyolultak? Nagyon jó, ha a piramisunk zöld, de nem cél! Ne felejtsük el, hogy az ideák kergetésében nagyon könnyű szemelől téveszteni a célt.
  • 17. Absztrakció és Instabilitás 1. • ac: absztrakt osztályok • cc: konkrét osztályok A = ac / (ac + cc) • Ce: efferens kapcsolatok • Ca: afferens kapcsolatok I = Ce / (Ce + Ca) 17 Ezen a látványos ábrán az egyes csomagokat (névtereket) láthatjuk az absztrakciójuk, instabilitásuk és méretük függvényében. Az absztrakció egyszerű, a csomagban található absztakt osztályok aránya az összeshez. Minél több van belőlük, annál inkább jobbra helyezkedik el a kis golyó az ábrán. A = ac / (ac + cc) Az instabilitás már bonyolultabb. Vannak az Afferens kapcsolatok, azok a csomagok, amik valahogy függenek a vizsgált csomag osztályaitól, illetve az Efferens kapcsolatok, azok a csomagok, amiktől valahogy függenek a vizsgált csomag osztályai. • Ca: Afferent Couplings, amik tőlem függenek • Ce: Efferent Couplings, amiktől én függők Az instabilitást úgy számolhatjuk ki, hogy az osztály saját függőségeinek számát elosztjuk az összes függőséggel, vagyis egy csomag instabil, ha több indetől függ, mint amennyien tőle függenek. I = Ce / (Ce + Ca)
  • 18. Absztrakció és Instabilitás 2. ? 18 Egy csomag akkor van az ideális zónában, ha az instabilitás és az absztrakció összege 1. Teht egy olyam csomag, ami főleg másoktól függ, tipikusan ilyenek a kontrollerek, azokban ne legyen túlsúlyban az absztrakt osztályok száma a konkrétakkal szemben. A másik oldalon viszont, ha egy csomag főként absztrakt csomagokból áll, akkor inkább tőle függjenek más csomagok, azaz legyen minél inkább stabil. Jellemző, hogy olyan absztrakt csomag, amitől semmi nem függ nem vagyon van, hisz ki gyártana ilyen csomagot? Az már gyakrabban fordul elő, hogy egy konkrét csomag nem függ semmitől, sőt talán még tőle függenek. Ezeket célszerű megvizsgálni és valahogy átszervezni.
  • 19. Összefoglalás • Előnyök • sokkal gyorsabb, mint bármi más • aprólékos (pmd) • átfogó kép (pdepend) • Hátrányok • néha szigorú és ellentmondásos 19 A bemutatott két eszköz kiválóan alkalmas arra, hogy viszonylag gyorsan adjon információt a kód állapotával kapcsolatban. Nálunk minden buildnek része, hogy ezek a mérések lefutnak, hogy legalább élesítés előtt mindenképp lássuk, mit is csináltunk. Ha figyeljük a számokat könnyen észrevehetjük, ha rossz irányba haladunk. Előnyök Hátrányok Mindenképp javaslom, hogy futtassátok le ezeket a saját rendszereiteken is, ha még nem tettétek és fontoljátok meg, hogy a talált problémákat kijavítsátok. A személyes tapasztalatom, hogy az elmúlt évben úgy fejlesztettem, hogy ezeket szem előtt tartottam és a köpönyeg ma sokkal jobb állapotban van, mint előtte, és fejleszteni is könnyebb.