Udržovateľný kód
Trinásta prednáška
Stiahnuť PDF · 2,4 MBPreber si túto poznámku so svojou AI
Skopíruj pripravený podklad a vlož ho do ChatGPT, Claude alebo inej AI — bude ťa učiť alebo skúšať len z tejto poznámky.
Náhľad poznámky
Udržovateľný kód
Informatika 2
Pojmy zavedené v 1. prednáške(1)
• typy chýb
– syntaktické
– behové
– logické
• techniky boja s chybami
– testovanie
– ladenie
– písanie udržovateľného kódu
Informatika 2
1
Pojmy zavedené v 1. prednáške(2)
• testovanie – rôzne pohľady
– aplikačné testovanie a testovanie jednotiek
– biela a čierna skrinka
– pozitívne a negatívne
– manuálne a automatické
• manuálne testovanie jednotiek
– prechádzanie zdrojového kódu
– priama komunikácia s objektom
• BlueJ – využitie funkcie object inspector
Informatika 2
2
Pojmy zavedené v 1. prednáške(3)
• automatické testovanie
– testy regresie
– test driven development
– testovacie triedy – JUnit
• správa assertEquals
• prípravky – fixtures
Informatika 2
3
Pojmy zavedené v 1. prednáške(4)
• ladenie
– manuálne prechádzanie kódu
– ladiace výpisy
– debugger
Informatika 2
4
Cieľ prednášky
• charakteristiky dobrého návrhu tried
– nízka implementačná závislosť
– vysoká súdržnosť
– duplicita kódu – zlá vlastnosť kódu
• návrh tried určený zodpovednosťou
• refaktoring – zlepšenie kódu
• príklad: Hra „World of FRI“
Informatika 2
5
World of FRI
Informatika 2
6
Implementačná závislosť(1)
• coupling
• úroveň vzájomného prepojenia tried
• zmeny v implementácii jednej triedy si vynútia
zmeny v implementácii druhej, závislej triedy
• snažíme sa minimalizovať
Informatika 2
7
Implementačná závislosť(2)
• vonkajší pohľad – rozhranie = „čo objekt robí“
• vnútorný pohľad – implementácia = „ako to robí“
• minimálna závislosť – používa iba dobre
navrhnuté rozhranie
• implementačná závislosť – požíva „ako to robí“
Informatika 2
8
Znaky minimálnej závislosti
• pochopenie triedy bez nutnosti skúmať triedy, na
ktorých je závislá
• zmena implementácie jednej triedy nevyžaduje
zmeny iných tried
Informatika 2
9
Súdržnosť kódu
• cohesion
• počet a rôznosť úloh jednej jednotky kódu
• vysoká súdržnosť – jednotka má jedinú logickú
úlohu
• metóda – práve jedna presne definovaná úloha –
operácia.
• trieda – jedna presne definovaná logická entita
• cieľ – maximalizácia súdržnosti
Informatika 2
10
Vysoká súdržnosť uľahčuje
• pochopenie úloh triedy a metód
• opakované použitie (reuse) triedy alebo metód v
iných častiach kódu, v inom softvéri
Informatika 2
11
Zodpovednosťou riadený návrh(1)
• responsibility-driven design
• objekt má len jednu úlohu
• objekt zodpovedá za svoj stav – dáta
• objekt zodpovedá za zmeny stavu – operácie s
dátami
• informácie o svojom stave poskytuje objekt
• atribúty tvoria logický celok
• metódy implementujú jednu operáciu
Informatika 2
12
Zodpovednosťou riadený návrh(2)
• do ktorej triedy pridať novú metódu?
• čie dáta bude metóda spracovávať?
• každá trieda je zodpovedná za operácie so svojimi
vlastnými dátami
Informatika 2
13
Aká veľká má byť
• trieda?
• metóda?
• metóda je príliš dlhá, ak vykonáva viac ako jednu
úlohu – operáciu
• trieda je príliš zložitá, ak spája viac ako jednu
logickú entitu
• rešpektovanie týchto pravidiel necháva ešte stále
dostatočný priestor programátorovi
Informatika 2
14
Hra World of FRI
Informatika 2
15
WoF
– existujúci kód
• hra – textová adventúra
• miestnosti: terasa, aula, bufet, labak,
kancelaria
• príkazy: chod, pomoc, ukonci
• smery: sever, vychod, juh, zapad
Informatika 2
16
Wof
– diagram tried
Informatika 2
17
Trieda NazvyPrikazov
• definícia všetkých platných príkazov
• názvy príkazov – pole reťazcov
• overuje platnosť príkazu
Informatika 2
18
Trieda Parser
• číta vstup hráča z terminálu
• rozpoznáva vo vstupe slová príkazov
• príkazy kontroluje prostredníctvom inštancie
triedy NazvyPríkazov
• vytvára inštancie triedy Prikaz
Informatika 2
19
Trieda Prikaz
• inštancie sú nemeniteľné objekty
• reprezentuje zadaný príkaz
• príkaz má 2 časti: názov a parameter
• overuje platnosť príkazu (nazov != null)
Informatika 2
20
Trieda Miestnost
• reprezentuje určitý priestor v hre
• má východy do iných miestností
• východy označené smerom
• neexistujúci východ = null
Informatika 2
21
Trieda Hra
• hlavná trieda
• nastavuje hru
• vytvorí miestnosti
• nastaví miestnostiam východy
• vykonáva príkazy hráča
Informatika 2
22
Návrh testov – regresné testovanie
• testy pred zmenami
• príprava kontroly korektnosti zmien
• úpravy existujúceho kódu po krokoch
• overenie správnosti každého kroku
Informatika 2
23
Diagram tried s testovacími triedami
Informatika 2
24
NazvyPrikazovTest
• testJePrikaz
• pozitívne testy na všetky platne príkazy
• negatívne testy na neplatné príkazy
Informatika 2
25
PrikazTest
• testDajNazov
• testDajParameter
• testJeNeznamy
• testMaParameter
• pozitívne a negatívne testy častí príkazu
Informatika 2
26
MiestnostTest
• testNemaVychody
• testSever
• testJuh
• testy nastavenia východov – priamy prístup k
atribútom
Informatika 2
27
Parser, Hra
• nemajú testy
• komunikujú priamo s užívateľom cez terminál
• => nedajú sa automaticky testovať
Informatika 2
28
Výsledky testov pred úpravami
Informatika 2
29
Duplicita v existujúcom kóde(1)
Informatika 2
30
Duplicita v existujúcom kóde(2)
• prehliadka kódu – duplicita v triede Hra
• metóda vypisPrivitanie – vypíše
– privítanie
– info o aktuálnej miestnosti a jej východoch
• metóda chodDoMiestnosti –
– vyhľadá miestnosť v zadanom smere z aktuálnej
– prejde do nej
– vypíše info o aktuálnej miestnosti a jej východoch
Informatika 2
31
Info o aktuálnej miestnosti(1)
System.out.println("Teraz si v miestnosti „
+ aAktualna.dajPopis());
System.out.print("Vychody: ");
if (aAktualna.aSevernyVychod != null) {
System.out.print("sever ");
}
if (aAktualna.aVychodnyVychod != null) {
System.out.print("vychod ");
}
...
Informatika 2
32
Info o aktuálnej miestnosti
...
if (aAktualna.aJuznyVychod != null) {
System.out.print("juh ");
}
if (aAktualna.aZapadnyVychod != null) {
System.out.print("zapad ");
}
System.out.println();
Informatika 2
33
Duplicita kódu(1)
• nežiaduci jav
• pri modifikáciách nutnosť úpravy kódu
na viacerých miestach
• zväčšuje pravdepodobnosť vzniku chyby
• znižuje čitateľnosť a zrozumiteľnosť kódu
Informatika 2
34
Duplicita kódu(2)
• indikuje zlý návrh – znižuje súdržnosť
– chodDoMiestnosti
– vypisPrivitanie
• odstraňovanie duplicít – jedna zo zásad
udržovateľnosti kódu
• =>
• refaktoring: samostatná metóda pre duplicitný
kód
• regresné testovanie
Informatika 2
35
Refaktoring
• úprava fungujúceho kódu so zachovaním jeho
funkčnosti
• nemení „čo objekt robí“
• mení „ako to objekt robí“
• zlepšenie udržovateľnosti kódu
Informatika 2
36
Info o aktuálnej miestnosti
• nová metóda definovaná v triede Hra
• v metódach vypisPrivitanie a chodDoMiestnosti
poslanie správy
Informatika 2
37
private void vypisInfoMiestnosti()
{
// pôvodne duplicitný kód
}
vypisInfoMiestnosti();
Regresné testovanie
• ! spustiť znovu všetky testy
Informatika 2
38
Zadanie rozšírenia hry
• možné smery sú sever, východ, juh a západ
• rozšíriť hru o smery dole a hore
Informatika 2
39
Postup práce
• nájsť časti kódu, kde sa smery priamo používajú
• redukcia týchto častí na nutné minimum
• refaktoring
• doplnenie nových smerov
Informatika 2
40
Smery – trieda Miestnost
• atribút pre každý východ
• inicializácia v konštruktore
• metóda nastavVychody –
nastavenie všetkých východov
Informatika 2
41
Smery – trieda Hra
• metóda vytvorMiestnosti – vytvára miestnosti a
nastavuje im východy (v smeroch)
• metóda chodDoMiestnosti – vyhľadá miestnosť v
zadanom smere z aktuálnej a prejde do nej
• metóda vypisInfoMiestnosti – vypíše info o
aktuálnej miestnosti aj s jej východmi
Informatika 2
42
Metoda chodDoMiestnosti
Miestnost novaMiestnost = null;
if (smer.equals("sever")) {
novaMiestnost = aAktualna.aSevernyVychod;
}
if (smer.equals("vychod")) {
novaMiestnost = aAktualna.aVychodnyVychod;
}
if (smer.equals("juh")) {
novaMiestnost = aAktualna.aJuznyVychod;
}
if (smer.equals("zapad")) {
novaMiestnost = aAktualna.aZapadnyVychod;
}
Informatika 2
43
Priamy prístup k atribútom
• priamy prístup hry k východom – atribútom
miestnosti
• porušenie zapuzdrenia – základný princíp
• zvyšuje implementačnú závislosť
Informatika 2
44
Závislosť Hra na Miestnost
• cieľ: odstrániť
• riešenie – posielanie správ miestnosti
Informatika 2
45
Úpravy triedy Miestnost
• atribúty budú neverejné
• pridanie prístupovej metódy
Informatika 2
46
public Miestnost dajVychod(String paSmer)
Telo metódy dajVychod(paSmer)
if (paSmer.equals("sever")) {
return aSevernyVychod;
}
if (paSmer.equals("vychod")) {
return aVychodnyVychod;
}
if (paSmer.equals("juh")) {
return aJuznyVychod;
}
if (paSmer.equals("zapad")) {
return aZapadnyVychod;
}
return null;
Informatika 2
47
Výsledok refaktoringu
• ! nezabudnúť pustiť testy
• znížila sa implementačná závislosť triedy Hra na
triede Miestnost
• pre zvýšenie počtu smerov, treba stále rozširovať
triedy Hra a Miestnost
Informatika 2
48
Trieda Miestnost – problémy
• východy sú definované ako atribúty
• => každá metóda v triede Miestnost musí vedieť
zoznam smerov
• riešenie: uloženie smerov do zoznamu
• poznámka: s pôvodnými verejnými atribútmi by
to bolo zložitejšie
Informatika 2
49
Zoznam smerov
• kontajner
• treba vyhľadávať
– ArrayList, pole – komplikované; nutnosť vyhľadávania
v cykle
• riešenie kontajner HashMap
Informatika 2
50
Kontajner HashMap(1)
• neusporiadaná množina dvojíc
• dvojica = (kľúč; hodnota)
• možnosť vyhľadávania podľa kľúča
• hodnota kľúča musí byť unikátna
• generická trieda
– možnosť meniť typ kľúča
– možnosť meniť typ hodnoty
Informatika 2
51
Kontajner HashMap(2)
Informatika 2
52
Správa keySet objektom HashMap
• keySet vytvára množinu všetkých kľúčov
• zoznam je neusporiadaný
• množina – nedá sa pristupovať pomocou indexu
• dá sa prechádzať pomocou cyklu foreach
Informatika 2
53
Trieda Miestnost
• zmena implementácie
• rozhranie bezo zmien
– trieda Hra – žiadne zmeny
Informatika 2
54
55
Informatika 2
Atribúty v triede Miestnost
private Miestnost aSevernyVychod;
private Miestnost aJuznyVychod;
private Miestnost aVychodnyVychod;
private Miestnost aZapadnyVychod;
private HashMap<String, Miestnost> aVychody;
názov smeru
miestnosť v smere
56
Informatika 2
Konštruktor v triede Miestnost
this.aSevernyVychod = null;
this.aJuznyVychod = null;
this.aVychodnyVychod = null;
this.aZapadnyVychod = null;
aVychody = new HashMap<String, Miestnost>();
57
Informatika 2
Metóda dajVychod(paSmer)
if (paSmer.equals("sever")) {
return aSevernyVychod;
}
...
return null;
return aVychody.get(paSmer);
Smery – priame použitie
• trieda Hra
– vytvorMiestnosti – vytvára miestnosti a nastavuje im
východy
– vypisInfoMiestnosti – vypíše info o aktuálnej
miestnosti aj s jej východmi
• trieda Miestnost
– nastavVychody – nastavenie jednotlivých východov
– rapídne sa zmenšil počet výskytov priameho použitia
smerov = 1
Informatika 2
58
Ďalšie zmeny
• metóda nastavVychody v triede Miestnost
– parametre = zoznam všetkých východov
– nastavovanie každého východu osobitne
• komplikácia pri pridávaní nového smeru
• zmena na metódu nastavVychod(paSmer,
paMiestnost)
• zmena rozhrania
Informatika 2
59
nastavVychod v triede Miestnost
public void nastavVychod(String paSmer,
Miestnost paMiestnost)
{
aVychody.put(paSmer, paMiestnost);
}
Informatika 2
60
Dôsledky pre triedu Hra
• dôsledok zmeny rozhrania triedy Miestnost
• metóda vytvorMiestnosti
– vytvára jednotlivé miestnosti
– nastavuje východy
• náhrada správy nastavVychody miestnosti na
postupnosťou správ nastavVychod miestnosti
Informatika 2
61
62
Informatika 2
Metóda dajVychod(paSmer)
terasa.nastavVychody(null, aula, labak, bufet);
terasa.nastavVychod("vychod", aula);
terasa.nastavVychod("juh", labak);
terasa.nastavVychod("sever", bufet);
Čo zostáva
• smery sú priamo využité na dvoch miestach
– metóda vytvorMiestnosti
• musí obsahovať smery
– metóda vypisInfoMiestnosti
• odstrániť z vypisInfoMiestnosti
• presun vytvárania popisu východov do triedy
Miestnost
– zmena rozhrania
Informatika 2
63
Návrh tried určený zodpovednosťou
• atribút pre východy – miestnosť
• výpis informácie o miestnosti – hra
• porušenie RDD
• informácie o sebe poskytuje miestnosť
Informatika 2
64
Trieda Miestnost – dajPopisVychodov
public String dajPopisVychodov()
{
String vychody = "Vychody:";
for (String smer : aVychody.keySet()) {
vychody = vychody + " " + smer;
}
return vychody;
}
Informatika 2
65
Dôsledok pre triedu Hra
private void vypisInfoMiestnosti()
{
System.out.println("Teraz si v miestnosti " +
aAktualna.dajPopis());
System.out.println(aAktualna.dajPopisVychodov());
System.out.println();
}
Informatika 2
66
Nová verejná metóda = nový test
• testDajPopisVychodov do testovacej triedy
MiestnostTest
Informatika 2
67
Smery – priame použitie
• trieda Hra
– vytvorMiestnosti – vytvára miestnosti a nastavuje im
východy
• smery priamo použité už len na jednom mieste
Informatika 2
68
Pridanie nových smerov
...
aula.nastavVychod("dole", jedalen);
jedalen.nastavVychod("hore", aula);
...
Informatika 2
69
Zhodnotenie riešenia
• smery hore, dole boli pridané
• jednoduchá možnosť pridať iné nové smery
(napr. teleport)
• jediné miesto – metóda vytvorMiestnosti
Informatika 2
70
Zmeny softvéru
• Softvér nie je román
– román sa napíše len raz
– Krstný otec, tretie aktualizované vydanie
• úspešný softvér sa stále opravuje, rozširuje.
• neudržovaný softvér „umiera“.
Informatika 2
71
Kvalita kódu
• implementačná závislosť
• súdržnosť
• jasne definovaná zodpovednosť
• kvalitný kód
– neobsahuje duplicitu
– dodržiava zapuzdrenie
Informatika 2
72
Vývoj kódu
• vývoj – dopĺňanie nových funkcií
• niekedy odstraňovanie chýb
• mení „čo aplikácia robí“
• rieši „ako to aplikácia robí“
• možnosť zväčšovania metód a triedy
– možnosť znižovania kvality kódu
Informatika 2
73
Tvorba softvéru
• oprava chyby, nová funkcia – zmena funkcie
• nové testy + staré (regresné) testy
• refaktoring – zmena (zvýšenie) kvality
• regresné testy (nové + staré)
Informatika 2
74
Vďaka za pozornosť
Informatika 2
76
text
Automaticky vygenerovaný textový náhľad. Pre plné formátovanie si stiahnite súbor.
nechodím na prednášky