objektno orjentirano programiranje - računarstvo 550. semestar/objektno orijentirano... ·...
TRANSCRIPT
Objektno orjentirano programiranje
Predavanje 9
Postojani objekti, serijalizacija, marshaling, relacijske baze podataka
Postojani objekti - osnove
• eng. persistent objects
• Bez obzira na veličinu poslovne aplikacije, ona će gotovo uvijek koristiti baze podataka
• Podaci su temelj programa
• Kada se objekt instancira u aplikaciji on živi maksimalno koliko i aplikacija
• Da bi objekt nastavio „živjeti” i nakon što aplikacija završi mora biti zapisan u neku vrstu sustava pohrane
• Stanje objekta je definirano vrijednošću njegovih atrbuta
Postojani objekti - osnove
• Koncept spremanja stanja objekta na način da se može kasnije ponovno koristiti zove se postojanost (eng. persistence)
• Pojam postojani objekt (eng. persitstent object) označava objekt čije se stanje može povratiti i koristiti neovisno o samo jednoj aplikaciji
Aplikacija 1
Aplikacija 2
Sustav pohrane
Zapiši objekt
Učitaj objekt
Postojani objekti - osnove
• Postoje različiti načini spremanja stanja objekta, neki od njih su:
• Spremanje u file
• Spremanje u relacijsku bazu podataka
• Spremanje u objektnu bazu podataka
• Najjednostavniji način je spremanje u datoteku, što nije standard kod poslovnih aplikacija
Spremanje objekta u datoteku
• Zapisivanje objekta u datoteku je različito od zapisivanja vrijednosti neke varijable u datoteku
• Spremanje varijabli u npr. tekstualnu datoteku (vrijednosti odvojene delimiterom)
• Objekt nije samo kolekcija primitivnih tipova, može sadržavati i druge objekte
• Da bi smo spremili objekt moramo ga razbiti u manje dijelove koje onda možemo zapisati u datoteku
• Moramo znati na koji način objekt ponovno vratiti u izvorni oblik
Serijalizacija
• Da bi objekt slali kroz kanal (npr. putem interneta) potrebno ga je dekonstruirati (razbiti u elementarne podatke, npr. byte stream), poslati i onda ga ponovno složiti na drugom kraju kanala – ovaj proces naziva se serijalizacija (eng. serialization)
• Proces samog slanja kroz mrežu zove se „marshaling”
• Serijalizirani objekt se može zapisati u file i poslije opet vratiti u originalno stanje
• Serijaliziacija i deserijalizacjia trebaju koristiti iste specifikacije (metodu dekompozicije i kasnije vraćanja u stanje objekta) – slično kao enkripcijski algoritam
• Java pruža interfejs – Serializable
• .NET jezici pružaju interfejs ISerializable
Spremanje objekta u datoteku
• Moderni jezici imaju ugrađene mehanizme za postojanost objekata
• Kao i većina jezika Java koristi koncept toka za I/O
• Da bi spremili objekt u datoteku Java koristi Stream
• Da bi pisali u Stream objekt mora implementirati interfejs Serializableili Externaizable
• Ograničenje ovakvog pristupa je da se za povraćanje objekta treba koristiti isti mehanizam/tehnolgija (Java)
• Java mora biti na obje strane ovog procesa
Serijalizacija u Javi
package Serialization;
import java.util.*;
import java.io.*;
class Osoba implements Serializable{
private String ime;
public Osoba(){
}
public Osoba(String i){
System.out.println(“Konstruktor”);
ime = i;
}
String dohvatiIme() {
return ime;
}
}
public class SpremiOsobu implements Serializable{
public SpremiOsobu(){
Osoba osoba = new Osoba(“Ivo Ivić”);
try{
FileOutputStream fos = new FileOutputStream(“Dat.txt”);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(osoba);
oos.flush();
oos.close();
} catch(Exception e){
e.printStackTrace();
}
}}
Serijalizacija u Javi
• U ovom primjeru:
• Instancira se objekt Osoba
• Objekt se serijalizira
• Objekt se sprema u datoteku Dat.txt
• Objekt se jednostavno serijalizira sa:
• oos.writeObject(osoba);
Serijalizacija putem interfejsa
• Primjer razlike između interfejsa i implementacije (znamo kako koristiti serijalizaciju ali ne znamo detalje implementacije)
• Primjer vraćanja objekta iz datoteke
package Serialization;import java.io.*;import java.util.*;public class UcitajOsobu{
public UcitajOsobu(){try{
FileInputStream fis = new FileInputStream(“Dat.txt”);ObjectInputStream ois = new ObjectInputStream(fis);Osoba osoba = (Osoba )ois.readObject();System.out.print(“Učitano ime osobe: “);System.out.println(osoba.dohvatiIme());ois.close();
} catch(Exception e){e.printStackTrace();
}}
}
Što se događa s metodama pri serijalizaciji?
• Objekti se po definiciji sastoje od atributa i metoda
• Atributi se serijaliziraju, ali što je s metodama?
• U primjeru Jave metode se ne serijaliziraju
• Pri ovakvoj serijalizaciji Java treba biti na obje strane procesa (serijalizacija i deserijalizacija)
• Ako jedna aplikacija serijalizira, druga aplikacija koja radi deserijalizaciju treba imati istu definiciju klase
• Ipak, što se tiče programera nema konceptualne razlike (iako fizička implementacija ne odgovara točno konceptualnom modelu)
Korištenje XML-a u procesu serijalizacije
• Vidjeli smo primjer serijalizacije na jednoj platformi
• XML nam omogućuju serijalizaciju/deserijalizaciju kroz različite platforme
• Generira se XML file koji predstavlja atribute klase Osoba
• Da bi u C# omogućili ovu funkcionalnost potrebne su dodatne definicije u klasi
[XmlRoot(“osoba”)]public class Osoba...[XmlAttribute(“ime”)]public String Ime...[XmlElement(“god_starosti”)]public int God_starosti
Korištenje XML-a u procesu serijalizacije
• Getteri i setteri su standardizirani
• Korisno jer ne mora svaki programer smišljati svoja imena za ove metode
[XmlAttribute(“ime”)]public String Ime{
get{
return this.strIme;}set{
if (value == null) return;this.strIme = value;
}}
Korištenje XML-a u procesu serijalizacije
• Prilikom postavljanja vrijednosti atributa ne trebamo eksplicitno pozivati setter već možemo koristiti jednostavno pridruživanje vrijednosti
• this.Ime = ime;
• Kada se ova naredba izvrši automatski se poziva setter
• Slično kao preopterećenje operatora u C++
Korištenje XML-a u procesu serijalizacije
public void Serialize()
{
Osoba[] ljudi = new Osoba[3];
ljudi[0] = new Osoba (“Ivo Ivić”, 32, 95);
ljudi[1] = new Osoba (“Mate Matić”, 35, 67);
ljudi[2] = new Osoba (“Jure Jurić”, 65, 77);
XmlSerializer serializator= new XmlSerializer(typeof(Osoba[]));
TextWriter writer= new StreamWriter(“osoba.xml”);
serializator.Serialize(writer, ljudi);
writer.Close();
}
<?xml version=”1.0” encoding=”utf-8”?>
<ArrayOfOsoba xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<Osoba ime=”Ivo Ivić”>
<god_starosti>32</god_starosti>
</Osoba>
<Osoba ime=”Mate Matić”>
<god_starosti>35</god_starosti>
</Osoba>
<Osoba ime=”Jure Jurić”>
<god_starosti>65</god_starosti>
</Osoba>
</ArrayOfOsoba>
public void DeSerialize()
{
Osoba[] ucitaniLjudi;
XmlSerializer serializator = new XmlSerializer(typeof(Osoba[]));
TextReader reader = new StreamReader(“osoba.xml”);
ucitaniLjudi = (Osoba[])serializator.Deserialize(reader);
Console.WriteLine(“Ucitani ljudi su:”);
foreach (Osoba osoba in ucitaniLjudi)
{
Console WriteLine(osoba.Ime+ “ ima “ +
osoba.God_Starosti + “ godina.”);
}
}
Pisanje u relacijsku bazu podataka
• Relacijske baze podataka su jedan od najuspješnijih alata u IT industriji
• Relacijske baze i danas igraju važnu ulogu iako možda postoje i bolje tehnologije
• Velika većina poslovnih aplikacija koristi relacijske baze podataka (Oracle, SQLServer, MSAccess…)
• Iako se radi o korisnom alatu, može doći do problema kada se radi interakcija s objektima
• Objekt koji se potencijalno sastoji od drugih objekata želimo zapisati u relacijski model koji nije dizajniran na OO način
Pisanje u relacijsku bazu podataka
• Objektno orijentirani model se ne temelji na tablicama
• Budući da se objekti ne mapiraju jednostavno u tablice razvijene su objektno orijentirane baze podataka (90ih)
• Iako su ovakve baze bolje predstavljale OO model postoji jedan veliki problem: legacy data (podaci koji već duže vremena skladišteni u postojećem formatu)
• Većina tvrtki koriste relacijske baze podataka i većina ukupnih svjetskih podataka je spremljena u relacijskom modelu
• Dodatna stavka u korist relacijskih baza je da one provjereno funkcioniraju na različitim nivoima skaliranja
Pisanje u relacijsku bazu podataka
• Iako je objekte lakše zapisivati u objektno orijentirane baze podatka, cijena konverzije postojećih podatka iz relacijskog u objektni model je često previsoka
• OO baze se koriste uglavnom u samo novijim sustavima koji se ne povezuju na legacy podatke
• Želimo riješiti sljedeći problem: želimo pisati OO aplikacij i imati pristup legacy podacima u relacijskim bazama podataka
• Radi se o mapiranju iz objektnog u relacijski model
Pisanje u relacijsku bazu podataka
• Prilikom korištenja baza podataka postoji sljedeća struktura:
1. Klijent baze
2. Server baze
3. Baza podataka
• Korisnička aplikacija obično predstavlja klijenta koji podsredstvomservera obavlja interakciju s bazom podataka
• Klijent komunicira s bazom putem SQL izraza (Structured QueryLanguage)
• Jedan od problema komunikacije sa specifičnom bazom je da su driveri baze vezani za proizvođača i koriste posebne protokole za komunikaciju
Pisanje u relacijsku bazu podataka
korisnik klijent baze server baze Bazapodataka
SQL
driveri
Pisanje u relacijsku bazu podataka
• Microsoft je razvio standard nazvan Open Database Connectivity (ODBC) koji apstrahira komunikaciju sa bazom
• Pisanjem klijenata po ODBC API-ju omogućavamo našim aplikacijama da se spajaju na više različitih servera baza podataka
klijent baze ODCB
MSSQLdriver
driver
driver
Oracle
Access
Dio 2. Kvaliteta softvera
• Karakteristke kvalitete softvera – postoje interne i eksterne karakteristike kvalitet softvera
• Eksterne karakteristike – iz perspektive korisnika softvera:
• Ispravnost (eng. correctness)– koliko je sustav bez pogreški u specifikaciji, dizajnu i implementaciji
• lakoća korištenja (eng. usability)
• Efikasnost (eng. efficiency) – u vidu korištenja memorije i vremena izvršavanja
• Pouzdanost
Karakteristike kvalitete
• Zaštita od neovlaštenog pristupa- dijelovima programa ili podacima
• Prilagodljivost – koliko se sustav može koristiti za namjene za koje nije prethodno dizajniran
• Preciznost – odnosi se na kvantitativni ishod sustava
• Robusnost – do kojeg stupnja sustav nastavlja ispravno raditi uz prisutnost neprihvatljivih unosa i stresnih uvjeta okoline
• Korisnici mare samo za eksterne značajke kvalitete softvera
• Programere zanimaju i interne značajke kvalitete softvera
Interne karakteristike kvalitete softvera
• Lakoća održavanja – koliko lako možemo mijenjati ili dodavati svojstva, poboljšavati performanse ili ispravljati pogreške
• Fleksibilnost- Koliko lako možemo prenamijeniti sustav za namjenu različitu od one s kojom smo započeli
• Portabilnost- koliko lako možemo prilagoditi sustav da radi u drukčijem okruženju od onog za kojeg je inicijalno dizajniran
• Mogućnost ponovnog korištenja – dijelova sustava za neki drugi sustav
• Čitljivost – koliko lako se može čitati i razumjeti izvorni (eng. source) kod
• Mogućnost testiranja- koliko lako se mogu provoditi unit-testovi ili system-testovi
Interne karakteristike kvalitete softvera
• Interne i eksterne karakteristike se donekle preklapaju jer interne karakteristike utječu na eksterne
• Glavni princip kvalitete softvera je da poboljšanjem kvalitete reduciramo troškove razvoja
• Kvaliteta softvera rezultira manjim brojem grešaka
• Troškovi razvoja se povećavaju: promjenom zahtjeva, promjena u dizajnu ili posljedica potrebe za debugiranjem
• Uklanjanje pogrešaka je prema statistikama aktivnost koja uzima najviše vremena u procesu razvoja
Testiranje
• Testiranje je najpopularnija tehnika osiguravanja kvalitete softvera
• Neke vrste testiranja obavljaju developeri, a neke specijalizirane osobe
• Unit testing – testiranje klasa ili malog dijela programa kojeg je napisao jedan developer, i testira se kao zasebna cjelina odvojena od sustava
• Component testing – testiranje klasa, manjeg dijela programa ili programskog elementa kojeg je pisalo više developera, i testira se kao zasebna cjelina odvojena od sustava
Testiranje
• Integration testing – kombinirano izvođenje više klasa, paketa, komponenti ili podsustava koje je razvilo više developera ili programerskih timova. Ovakav tip testiranja počinje čim postoji više klasa za testiranja i traje dok cijeli sustav nije završen
• Regression testing – ponavljanje prethodno izvršenih testova u svrhu pronalaženja naknadno uvedenih bugova
• System testing – izvođenje softvera u konačnoj konfiguraciji, uključujući integraciju s drugim softverskim i hardverskim sustavima
Testiranje
Testovi koje obavlja specijalizirano osoblje:
• beta testiranje
• customer-acceptance tests
• performance tests
• configuration tests
• platform tests
• stress tests
• usability tests
Testiranje
Testiranje se obično dijeli u dvije kategorije:
• black-box testing – tester ne može vidjeti način unutrašnjeg funkcioniranja komponente/modula
• white-box testing – tester ima uvid u unutrašnje funkcioniranje komponente/modula
Razlika između testiranja i debugiranja
Testiranje ne može dokazati da sustav nema pogrešaka, može samo pokazati da ima
U radu na projektima developer testiranje bi u prosjeku trebalo uzeti 8-25% vremena
Testiranje
• Prilikom korištenja klasa najbolje ih je tretirati kao black-box
• Kada želimo testirati klase/module, najbolje ih je tretirati kao white-box, na taj način možemo temeljitije testirati
• Svaka zasebna cjelina se treba posebno testirati prije integracije s ostalim komponentama
• Ako pišemo više funkcionalnosti treba ih prvo svaku zasebno testirati
• Testiranje po zahtjevima (eng. requirements) – najbolje je testove napisati u fazi zahtjeva i prije nego smo napisali kod
• Dizajniranje testnih scenarija u fazi dizajna proizvoda – ovo pomaže da se uoče pogreške u zahtjevima i dizajnu koje skuplje od grešaka pri kodiranju
Testiranje
Developeri se često znaju pitati da li da prvo pišu testove pa kod ili obrnuto:
• Pisanje testova prije koda ne uzima više vremena nego što bi inače trebalo
• Ako testove napišemo prije – ranije možemo pronaći i ispraviti pogreške
• Pisanje testova prije omogućava nam da prvo razmislimo zahtjevima i dizajnu prije pisanja koda što rezultira boljim kodom
• Bolje otkrivamo loše zahtjeve pišući testove
Testiranje podataka
Vrste pogrešaka vezano za podatke:
• Premalo (ili ništa) podataka
• Previše podataka
• Kriva vrsta podataka
• Kriva veličina podataka
• Neinicijalizirani podaci
Testiranje klasa
Napravimo jednu mock klasu koja služi za testiranje druge klase:
• poziva objekt sa zadanim skupom inputa
• koristi višestruke pozive sa različitim inputima
• dohvaća povratne vrijednosti
• loggiranje ponašanja klase
Komercijalni alati: JUnit, CppUnit, NUnit
Testiranje je jednostavnije ako imamo automatizirani input koji se uspoređuje s očekivanim povratnim vrijednostima – pogotovo za regression test
Testiranje
• Random-data generatori testiraju za neobične kombinacije podataka
• Modularni dizaj je lakše testirati – određeni dio koda možemo testirati bez user-iterface-a
• Testiranje bez mjerenja pokrivenosti koda obično koristi samo 50-60% koda
• Coverage monitor je alat koji služi za praćenje udjela koda u testiranju
• Na taj način znamo koji smo dio koda pokrili testovima, a koje nismo
• Re-testiranje nakon bilo kakvih promjena u kodu
Evidencija testiranja
Potrebno je imati evidenciju testiranja da vidimo kako promjene utječu na sustav u pozitivnom ili negativnom smislu
Neke stvari koje možemo evidentirati:
• Administrativni opis pogreške (datum, tko je prijavio, naziv, buildnumber …)
• Opis problema
• Koraci potrebni za reproduciranje problema
• Preporuka o rješavanju problema
• Vezani problemi