42
Objektno orjentirano programiranje Predavanje 5 Klase – nastavak Dizajn s objektima

Objektno orjentirano programiranje. semestar/Objektno orijentirano... · Dizajn s objektima •Dobar OO dizajn proces uključuje sljedeće: 1. Kvalitetna analiza i istraživanje 2

  • Upload
    others

  • View
    23

  • Download
    2

Embed Size (px)

Citation preview

Objektno orjentirano programiranje

Predavanje 5

Klase – nastavak

Dizajn s objektima

Detalji klase

• Pri izboru što će biti sučelje a što implementacija treba imati na umu koliko će klasa biti korisna

• Klasa nije izolirana cjelina – otok za sebe

• Nakon instanciranja objekti međusobno obavljaju interakciju

• Jedan objekt može biti dio drugog objekta ili dio hijerarhije

• Izbor imena klase je vrlo važan i ime treba biti deskriptivno

• Ime nam pruža informacije o tome što klasa radi i u kakvoj je interakciji s ostatkom sustava

/* Ova klasa definira avion kojeg nadzire

sustav kontrole leta*/

class Avion

{

private:

int sifraAviona; //serijski broj aviona

string modelAviona;

string imePiota;

int trenutnaVisina;

int trenutnaBrzina;

static inttrenutniBrojAvionaIznadAerodroma;

public:

Avion()

{

sifraAviona = null;

modelAviona = null;

trenutnaVisina = 0;

...

}

Avion(int sifAviona, string modAviona)

{

sifraAviona = sifAviona;

modelAviona = modAviona;

}

void ZapocniSlijetanje();

void ZapocniPolijetanje();

int DohvatiVisinu();

int DohvatiBrzinu; }

Komentari

• Važno je kvalitetno dokumentirati klasu i kroz korištenje komentara

• Ponekad je potrebno detaljnije opisati funkcionalnost pojedinih metoda ako iz imena nije lako zaključiti kako se ona koristi

• Većina OO jezika ima dvije standardne vrste komentara/* komentar u više

linija (moramo paziti da zatvorimo komentar */

//komentar u jednoj liniji (nije potrebno zatvarati)

Atributi

• Public ili private?

• Potrebno je skriti što je više moguće podataka i korisniku dati samo ono što mu je potrebno

• static int trenutniBrojAvionaIznadAerodroma;

Konstruktori

• Ako ne definiramo svoj konstruktor klasi se dodjeljuje defaultnikonstruktor

Avion(){

sifraAviona=null;

modelAviona=null;

trenutnaVisina=0;

...

}

• Konstruktor može i primati parametre

null

• Null predstavlja vrijednost „ništa”

• Može biti korisno u programiranju

• Provjera da li je neka varijabla ili objekt null govori nam da li je postavljena vrijednost

• Varijable/objekta možemo postaviti na null prije nego imamo neku smislenu vrijednost (npr. Prije nego korisnik upiše neki traženi unos)

• Null je validno stanje objekta

Atributi i metode

• Osim atributa i metode mogu biti definirane kao static

• Svi objekti iz iste klase imaju zajedničke statičke metode

• Statična metoda može se koristiti npr. za manipulaciju static atributima

• Public metode – dio sučelja

• Private metode – dio implementacije

Dizajn klasa

• Osnovni cilj OO programiranja je modeliranje stvarnog svijeta na način kako ljudi prirodno razmišljaju – u okvirima objekata

• Kada dizajniramo klasu potrebno je ponašanje predstaviti na način kako se stvarno u svijetu i odvija

• Jedna od najčešćih pogrešaka je dizajn klasa koje imaju ponašanje ali nemaju podatke

• Dizajn interfejsa• Minimalni mogući interfejs čini klasu konciznom i „čistom”

• Uključiti korisnika u definiranje dizajna od samog početka

Dizajn klasa

• Robusni konstruktori i destruktori• Destruktor prilikom završetka života objekta treba osloboditi memoriju koju je

objekt alocirao

• U protivnom dolazi do memory leak-a

• Uključiti error-handling u samu klasu

• Dokumentiranje klase i korištenje komentara• Dobra praksa

• Potrebno je uložiti vrijeme

• Izrazito bitno kod većih projekata i za rad u timovima

• Stvaranje objekata imajući na umu njihovu suradnju

Dizajn klasa• Dizajn s naglaskom na ponovno

korištenje

• Dizajn s naglaskom na proširivost

• Deskriptivna imena• Ako koristimo neku konvenciju ili standard

imenovanja bitno je da ga slijedimo do kraja

• Kada netko pročita ime trebao bi znati što taj objekt predstavlja

• Apstrahiranje ne-portabilnog koda (kod koji na nekoj specifičnoj hardverskoj platformi)

Dizajn klasa

• Pružanje načina za kopiranje i usporedbu objekata

• Dizajnirati kod s malim dosegom• Lokaliziranje atributa i ponašanja

• Pojednostavljuje održavanje, testiranje i proširivanje klasa

• Primjer nepotrebnog povećanja dosega

class Matematika{int temp;public int zamijeni(int a, int b){

temp = a;a = b;b = temp;return temp;

}};

Dizajn klasa

• Klasa bi trebala biti odgovorna za svoje funkcionalnosti

• Primjer ne-OO pristupaIspisiKrug(krug);IspisiPravokutnik(pravokutnik);

switch (oblik){case 1: IspisiKrug(krug); break;case 2: IspisiPravokutnik(pravokutnik); break;case 3: IspisiTrokut(trokut); break;default: System.out.println("Nedefinirani oblik"); break;}

Dizajn klasa

Dizajn klasa

• Primjer OO pristupa - polimorfizam

Dizajn s naglaskom na lako održavanje

• Dizajn konciznih i korisnih klasa olakšava održavanje

• Organiziramo kod u više manjih zasebnih jedinica koje je lakše održavati

• Potrebno je reducirati međuzavisni kod – promjena u jednom dijelu koda ne bi trebala imati utjecaj na ostatak koda

• Ako su klase ispravno dizajnirane promjene u sustavu bi se trebale odnositi samo na implementaciju

• Promjene na javnom interfejsu bi se trebale izbjegavati – takve promjene uzrokuju velike promjene u ostatku koda

Povezane klase

• Situacija kada dvije (ili više) klase u velikoj mjeri ovise jedna o drugoj naziva se jako povezane klase

• Promjena na jednoj klasi vrlo vjerojatno znači da će biti potrebno mijenjati i drugu klasu

• Ponekad na priroda problema iz domene nameće jaku povezanost klasa

Iterativan razvojni proces

• Ne treba cijeli kod napisati odjednom

• Kod se radi u manjim koracima, i iza svakog koraka obavlja se potrebno testiranje

• Dobar plan testiranja otkriva greške u ranom stupnju razvoja gdje je ispravljanje jednostavnije

• Ako se greška uoči u zadnjem stadiju developmenta puno skuplje je popraviti

Testiranje interfejsa

• Testiranje počinje sa minimalnim implementacijama interfejsa (eng. stubs)

• Na taj način možemo testirati interfejs bez pisanja stvarnog koda

• Služi samo da testiramo da interfejsi dobro rade

• Nakon runde testiranja stub možemo ostaviti sakriven od korisnika u slučaju da nam opet zatreba

Testiranje interfejsa

Testiranje interfejsaclass CitacBazePodataka{

private string baza[] = { "Zapis1","Zapis2", "Zapis3","Zapis4", "Zapis5" };private bool bazaOtvorena = false;private int pozicija;public void Otvori(string ime){

bazaOtvorena = true;}public void Zatvori(){

bazaOtvorena = false;}public void IdiNaPrviZapis(){pozicija = 0;}

public void IdiNaZadnjiZapis(){pozicija = 4;

}public int KolikoImaZapisa(){

int brojZapisa = 5;return brojZapisa;

}public string DohvatiZapis(int redniBroj){

/* implementacija specifična za konkretnu bazu*/return baza[redniBroj];

}public string DohvatiSljedećcZapis(){

/* implementacija specifična za konkretnu bazu*/pozicija++;return baza[pozicija];

}};

Postojanost objekata (eng. object persistence)

• Postojanost (eng. persistence) je koncept čuvanja stanja objekta

• Kada se pokrene program, ako ne sačuvamo stanje objekta on nakon nekog vremena nestaje (tokom ili na kraju programa) i podaci se ne mogu vratiti

• U nekim situacijama nam nije bitno da sačuvamo stanje objekta, ali u određenim situacijama to trebamo uzeti u obzir

• Najjednostavniji način osiguravanja postojanosti objekta je serijalizacija u obični file (obično se radi o xml formatu)

Postojanost objekata

• Postoje tri primarne lokacije za čuvanje objekata:

• File system – serijalizacija

• Relacijska baza podataka – potreban je middleware da bi se objekt pretvorio u relacijski model

• OO baza podataka – učinkovitiji način spremanja objekata, ali većina tvrtki ima svoje podatke u starijim sustavima i težak je proces konverzije starih podataka iz relacijskog u OO model

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

Dizajn s objektima

• Pričali smo o načinu kako na dobar način dizajnirati klase

• Sada je fokus na dobrom dizajnu sustava

• Sustav se može definirati kao klase koje međudjeluju jedne s drugima

• Potrebno je dobar dio vremena rada na projektu uložiti u početni dizajn sustava jer su naknadne promjene jako skupe

• Ne postoji samo jedna „dobra” metoda dizajna

• Potrebno je odabrati metodu koja najviše paše našim potrebama i sredstvima/resursima na raspolaganju

Dizajn s objektima

• Dobar OO dizajn proces uključuje sljedeće:1. Kvalitetna analiza i istraživanje

2. Izrada SOW (Statement of work) dokumenta

3. Prikupljanje zahtjeva

4. Izrada prototipa korisničkog sučelja (eng. user interface)

5. Definiranje klasa

6. Određivanje odgovornosti svake klase

7. Određivanje kako različite klase obavljaju interakciju

8. Stvaranje high-level modela koji opisuje sustav koji će se izraditi

Dizajn s objektima

• Za razvoj OO sustava posebno je važan high-level model

• Objektni model se sastoji od class-dijagrama i definiranja interakcija među klasama

• Model bi trebao vjerno predstavljati sustav i trebalo bi ga biti lako razumjeti ili mijenjati

• Za notaciju se koristi UML

• Postoji više metodologija npr. waterfall model, rapid prototyping, Extreme programming, Agile, Scrum …

Waterfall metoda

• Definiranje zahtjeva u ranoj fazi i minimizirati naknadne promjene• Cijena promjene u fazi zahtjeva

i dizajna je mala

• Cijena promjena u fazi implementacije je značajno veća

• Cijena promjena u fazi deploymenta je vrlo velika u odnosu na prvu fazu

Dizajn

Implementacija

Deployment

Vis

oka

cije

na

Korisnik želi mijenjati aplikaciju

Pronaći pogrešaka u ovoj fazi

Otkriti što više potencijalnih problema

Dizajn

Implementacija

Deployment

Vis

oka

cije

na

Korisnik želi mijenjati aplikaciju

Pronaći pogrešaka u ovoj fazi

Otkriti što više potencijalnih problema

Testiranje, testiranje, testiranje

• Neki klijenti su spremni dobiti softver lošije kvalitete za nešto manju cijenu

• Takav pristup nije dugoročno održiv i reputacija proizvođača se degradira

• Neki proizvođači puštaju netestirane beta verzije softvera i tretiraju kupce kao testere

• Greške koje se pronađu na takav način često imaju veću cijenu popravka (sličan primjer je u auto-industriji kada se otkrije greška na nekom modelu koji je već u prodaji)

• Visoka kvaliteta softvera je i dobra podrška mogu biti značajne prednosti za proizvođače softvera

• Testiranje „u hodu” u svakoj fazi razvoja

1. Kvalitetna analiza i istraživanje (faze dizajn procesa)

• Korisnici u svakoj fazi trebaju surađivati sa developerima – zbog (vrlo) mogućih nepredviđenih scenarija

• U fazi analize korisnici i developeri istražuju i analiziraju problematiku projekta za kasniju definiciju SOW i zahtjeva te odluke o izvedivosti projekta (da li se kreće u sam projekt)

• Često se događa da se projekti zbog inercije ili politike provode bez obzira na indikatore koji upućuju da projekt neće biti izvediv

• Ako projekt održiv fokus ove faze je da se prouči potencijalni sustav i utvrde potrebni zahtjevi

2. Izrada Statement of Work (SOW) dokumenta • SOW je dokument koji opisuje sustav

• Iako je utvrđivanje zahtjeva cilj prve faze, u ovom trenutku zahtjevi još nisu u konačnoj formi

• SOW bi trebao sadržavati sve informacije potrebne da bi se sutavrazumio

• Mnogi klijenti izrađuju Request for proposal što je slično SOW-u

• U njemu opisuju kako bi sustav trebao izgledati i šalju različitim proizvođačima

• Na temelju toga proizvođači odlučuju da li da se natječu za projekt i kolika bi bila njihova predložena cijena

3. Prikupljanje zahtjeva

• Dokument zahtjeva opisuje što korisnici žele da sustav radi

• Detalji zahtjeva ne trebaju biti tehničke prirode već trebaju biti specifični u pogledu onoga što korisnici žele od konačnog proizvoda

• Moraju biti dovoljno specifični da bi dizajneri mogli započeti fazu dizajna

• Dokument zahtjeva je obično lista zahtjeva za pojedine specifične funkcionalnosti sustava

• Zahtjevi su konačni prikaz onoga što se treba implementirati

• Svi budući dokumenti u razvojnom procesu se temelje na zahtjevima

4. Razvoj prototipa korisničkog sučelja

• Jedan od najboljih načina da budemo sigurni da korisnici i developeri razumiju i imaju zajedničku viziju sustava je razvoj prototipa

• Većina ljudi prototipom smatra simulirano korisničko sučelje

• Stvaranje stvarnih formi, prozora i interakcije s programom

• Prototip neće sadržavati sve funkcionalnosti konačnog sustava

• Ne moraju biti stvarni prozori i ekrani koje će korisnik vidjeti u konačnom proizvodu, može biti i prezentacija na ploči ili papiru

• Dobar prototip može pomoći pri identifikaciji potrebnih klasa

5. Identifikacija klasa

• Može početi već nakon izrade liste zahtjeva

• Jedan način pristupa je da se sve imenice iz zahtjeva označe (predstavljaju ljude, objekte mjesta, stvari)

• Kroz više iteracija se klase uklanjaju i dodaju dok ne dođemo do željenog dizajna

• Konačni rezultat možda uopće neće nalikovati na prvu fazu

6. Određivanje odgovornosti za svaku klasu

• Podaci koje klasa treba pohranjivati

• Operacije koje treba obavljati

7. Određivanje kako različite klase obavljaju interakciju

• Poruke među klasama – jedna klasa može zatražiti informacije od druge klase ili zatražiti da druga klasa obavi neku operaciju

8. Stvaranje class modela koji opisuje sustav koji će se izraditi

• Nakon što su određene klase, odgovornosti klasa i međudjelovanje izrađuje se class model

• Class model predstavlja sustav koji će se izraditi

• Prikazuje klase i njihove odnose

• Koriste se UML alati za izradu modela

Object wrappers

• OO pristup u sebi ima i strukturnog koda

• Npr. implementacije metoda u sebi sadrže većinom strukturni kod

• Strukturni kod sadrži elemente koji nisu objekti: petlje, uvjetne izraze…

class SredisnjaAplikacija{public static void main(string args[]){

int z = 9;

if (z <= 10){if (z == 3) System.out.println("z iznosi:" + z);z = z+1;

}}

};

Wrapping strukturiranog koda

• Primjer wrapper za operaciju zbrajanje

class TestiranjeKlaseMatematika{public static void main(string args[]){

int z = 0;Matematika m = new Matematika();z = m.zbroji(3, 4);System.out.println("Vrijednost od z je " + z);

}};

class Matematika{public int zbroji(int a, int b){

return a + b;}

};

Wrapping strukturiranog koda

Objekt

Metoda

Strukturirani kod

Wrapping neportabilnog koda

• Jedna od funkcija wrappera je skrivanje neportabilnog (nativnog) koda

• Enkapsulacija funkcionalnosti koja se može izvršavati na jednoj (ili nekoliko) platformi u metodu iza interfejsa kojeg programeri mogu koristiti

• Naredba za beep koja funkcionira u Windows OS-u: cout<<„\007”

class Zvuk{public void napraviBeep(){

cout << "\007";}

};

class TestKlaseZvuk{public:void Test(){

Zvuk mojZvuk;mojZvuk.napraviBeep();

}};

Wrapping postojećih klasa

• Iako nije očit slučaj, ponekad je potrebno napraviti wrapper i za OO kod

• Često se radi o kodu kojeg je netko drugi napisao i na takav način se prilagođava funkcionalnost trenutnim potrebama

• Promjena interfejsa ili implementacija neke klase na način da se napravi wrapper – primjer čitača baze podataka

• Korištenje u design patternima:• Decorator pattern – wrapper implementacije

• Adaptor pattern – promjena interfejsa