Objektno orjentirano programiranje Predavanje 11 Objekti i klijent server aplikacije, templates, klasifikacija
Objektno orjentirano programiranje
Predavanje 11
Objekti i klijent server aplikacije, templates, klasifikacija
Klijent - server
• Kao i u prethodnom predavanju – radi se o slanju objekta kroz mrežu
• Kod distribuiranog objektnog modela mogu se koristiti vlasnički (eng. proprietary) pristup ili nevlasnički pristup korištenjem SOAP/XML
• Isto vrijedi i za klijent – server model
• Pristup koji ćemo koristiti ovisi o samom problemu i postavljenim zahtjevima
• Vlasnički pristup je jednostavniji i uzima manje vremena ali nas ograničava na jednu tehnologiju
• Nevlasnički pristup omogućava komunikaciju neovisnu o platformi i programskom jeziku
• U ovom primjeru koristi se Java programski jezik
• Klijent stvara objekt i šalje ga na server
• Server stvara referencu objekta da bi mu pristupio
• Server može mijenjati atribute objekta i vratiti ga natrag klijentu
Vlasnički pristup
Klijent Server
Objekt
Primjer
• Stvorimo klasu TekstualnaPorukasa atributima ime i poruka
import java.io.*;import java.util.*;public class TekstualnaPoruka implements Serializable {
public String ime;public String poruka;//KonstruktorTekstualnaPoruka(String i) {
poruka = “ “;ime= i;
}// Pristupnikpublic String dohvatiIme() {
return ime;}// Pristupnikpublic String dohvatiPoruku() {
return poruka;}//Mutatorpublic void postaviPoruku(String p) {
poruka = p;}
}
Klijentski kod
• Klijent koristi klasu tekstualnaPoruka da bi stvorio objekt i poslao ga na server
Klijent treba obaviti sljedeće zadatke:
• Dohvatiti informacije od korisnika
• Stvoriti objekt
• Postaviti vrijednosti atributa
• Stvoriti socket konekciju
• Stvoriti izlazni tok (eng. stream)
• Zapisati objekt
• Zatvoriti tok
public class Klijent{
public static void main(String[] arg) {
try {
String poruka= “ “;
String ime= “ “;
System.out.print(“Unesite ime poruke:“);
ime = getString();
// Stvori objekt
TesktualanPoruka mojaPoruka= new TekstualnaPoruka(ime);
System.out.print(“Unesite sadrzaj poruke: “);
poruka= getString();
// koristi mutator
mojaPoruka.postaviPoruku(poruka);
// Stvori konekciju na socketSocket socketNaServer = new Socket(“127.0.0.1”, 88888);// Stvori ObjectOutputStreamObjectOutputStream mojIzlazniStream =new ObjectOutputStream(socketNaServer .getOutputStream());// Zapiši objekt u OutputStreammojIzlazniStream.writeObject(mojaPoruka);
// Zatvori streammojIzlazniStream.close();
} catch (Exception e) {System.out.println(e);}}
Serverski kod
Server obavlja sljedeće funkcionalnosti:
• Stvara referencu na objekt
• Sluša na portu 88888
• Čeka konekciju klijenta
• Stvara input i output stream
• Čita objekt TekstualnaPoruka
• Ispisuje poruku
public class Server {
public static void main(String[] arg) {
// Stvori referencu objekta kojeg očekuje
TekstualnaPoruka mojaPoruka = null;
try {
// Slušaj na portu 88888
ServerSocket mojServerSocket = new ServerSocket(88888);
System.out.println(“Spremno\n”);
// Čekaj dok se klijent ne spoji
Socket dolazni = mojServerSocket.accept();
// Stvori input stream
ObjectInputStream mojInputStream
= new ObjectInputStream(dolazni.getInputStream());
// Pročitaj objekt sa streama
mojaPoruka = (TekstualnaPoruka)mojInputStream.readObject();
System.out.println(mojaPoruka.dohvatiIme() + “ : “
+ mojaPoruka.dohvatiPoruku()+ “\n”);
// Zatvori streammojInputStream.close();} catch(Exception e) {
System.out.println(e);}
Nevlasnički pristup
• U nevlasničkom (eng. nonproprietary) pristupu obično se koristi XML kao što je to bio slučaj sa postojanim podacima i dstribuiranim sustavima
• Korištenjem XML-a možemo slati objekte između aplikacija napisanih u različitim programskim jezicima i među različitim platformama
• Iako su vlasnički i nevlasnički koncepti slični najveća razlika je u tome što objekti nisu rastavljeni u binarni zapis u vlasničkom formatu već se koristi tekstualni XML dokument
• XML pristup klijent – server arhitekturi
Nevlasnički pristup
Klijent Server
Objekt
XML
Primjer
• Primjer klijent-server komunikacije realiziran u C#
• Nevlasnički pristup temeljen na XML-u
• XML definicija objekta je specificirana direktno u klasi
• Klasa se stvara oko XML definicija
namespace Server
{
[XmlRoot(“racun”)]
public class BankovniRacun
{
private String strIme;
private int intBrojRacuna;
[XmlElement(“ime”)]
public String Ime
{
get { return strIme; }
set { strIme = value; }
}
[XmlElement(“br_racuna”)]
public int BrojRacuna
{
get { return intBrojRacuna; }
set { intBrojRacuna = value; }
}
public BankovniRacun()
{
this.Ime= “Ivo Ivic”;
this.BrojRacuna= 76245;
Console.WriteLine(“Stvaranje računa!”);
}
}
}
Klijentski kod
Klijent izvodi sljedeće zadatke:
• Stvara objekt BankovniRacun
• Stvara socket
• Priprema za formatiranje objekta u XML
• Stvara stream
• Serijalizira objekt u stream u XML formatu
• Zatvara resurse i stream
namespace Klijent
{
class Klijent
{
public static void Zapocni()
{
BankovniRacun mojRacun= new BankovniRacun();
try
{
//Otvori TCP socket
TcpClient tcpKlijent= new TcpClient(“127.0.0.1”, 88888);
//Priprema za serijalizaciju objekta u XML
XmlSerializer myXmlFactory =
new XmlSerializer(typeof(BankovniRacun));
//Stvori stream
NetworkStream stream = tcpKlijent.GetStream();
// Serijaliziraj objekt u TCP Stream
myXmlFactory.Serialize(stream, mojRacun);
// Zatvori stream
stream.Close();
tcpKlijent.Close();
}
catch (Exception ex)
{
Console.WriteLine(“Exception: {0}”, ex);
}
}
}
}
Serverski kod
• Stvori reference za objekt BankovniRacun
• Spoji se na socket i slušaj
• Postavi input stream
• Čitaj bajtove sa stream-a
• Deserijaliziraj objekt iz stream-a
• Zatvori sve resurse
public Server()
{
TcpListener server = null;
TcpClient klijent= null;
try
{
//Stvori Socket Listener i pokreni ga
server = new TcpListener(IPAddress.Parse(“127.0.0.1”), 88888);
server.Start();
//Postavi input buffer
Byte[] bajtovi = new Byte[256];
//Otvori petlju za spajanje više klijenata
while (true)
{
//Započni primanje konekcija
klijent= server.AcceptTcpClient();
Console.WriteLine(“Spojen!”);
//Otvori stream
NetworkStream stream = klijent.GetStream();
int i;
while ((i = stream.Read(bajtovi, 0, bajtovi.Length)) != 0)
{
//Pripremi memory stream za serijalizaciju
MemoryStream ms = new MemoryStream(bajtovi);
//Pripremi alat za serijalizaciju
XmlSerializer myXmlFactory =
new XmlSerializer(typeof(CheckingAccount));
//Stvori objekt BankovniRacun iz stream-a
BankovniRacun mojRacun =
(BankovniRacun)myXmlFactory.Deserialize(ms);
//Ispiši objekt
Console.WriteLine(“Ime: {0}, Broj računa: {1}.”,
mojRacun.Ime, mojRacun.BrojRacuna);
Generički tipovi (eng. generic types)
• U C++ koriste se templates
• Omogućava funkciji ili klasi da radi sa različitim tipovima
• Funkciju/klasu ne moramo pisati više puta za različite tipove
template<class TYPE>
void IspisiUdvostruceno(TYPE podaci)
{
cout<<„Udvostruceno: " << podaci * 2 << endl;
}
Generički tipovi (eng. generic types)
• Prilikom poziva funkcije utvrđuje se o kojem se tipu radi
• npr. poziv: IspisiUdvostruceno() podrazumijeva int, a
• IspisiUdvostruceno(5.1) podrazumijeva double
• Možemo i eksplicitno navesti koji tip želimo prilikom poziva funkcije
• IspisiUdvostruceno <<double>>(5);
Primjer
template<class T>
T Zbroji(T n1, T n2)
{
T rezultat;
rezultat = n1 + n2;
return rezultat;
}
Primjer 2template<class T>
double IzracunajProsjek(T tNiz[], int brElemenata)
{
T tSuma = T(); // tSuma = 0
for (int i = 0; i < brElemenata; ++i)
{
tSuma += niz[i];
}
// O kojem god tipu T da se radi pretvori ga u double
return double(tSum) / brElemenata;
}
int main()
{
int IntNiz[5] = {100, 200, 400, 500, 600};
float FloatNiz[3] = { 1.22f, 2.33f, 14.54f};
cout << IzracunajProsjek(IntNiz, 5);
cout << IzracunajProsjek(IntNiz, 3);
}
Class templates - primjerclass MojaKlasa
{
int podaci;
public:
MojaKlasa() : podaci(0)
{}
void PostaviPodatke(int vrijednost)
{
podaci = vrijednost;
}
int DohvatiPodatke() const
{
return podaci;
}
void IspisiPodatke()
{
cout << podaci;
}
};
template<class T>
class MojaKlasa
{
T podaci;
public:
MojaKlasa() : podaci( T() )
{}
void PostaviPodatke(T vrijednost)
{
podaci= vrijednost;
}
T DohvatiPodatke() const
{
return podaci;
}
void IspisiPodatke()
{
cout << podaci;
}
};
//main
//Prvi objekt
MojaKlasa<int> obj1;
obj1.PostaviPodatke(75);
obj1.IspisiPodatke();
//Drugi objekt
MojaKlasa<float> obj2;
float n = obj2.DohvatiPodatke();
//Napomena
obj1 = obj2; // ERROR : MojaKlasa<float> to
// MojaKlasa<int>
Višestruki tipovi - class templates
template<class Tip1, class Tip2>
struct Par
{
Tip1 prvi;
Tip2 drugi;
};
Par<int,int> tocka1;
tocka1.prvi = 5;
tocka1.drugi = 40;
Par<int, double> tocka2;
tocka2.prvi = 7;
tocka2.drugi = 3.5412;
Dio 2. Klasifikacija
• Klasifikacija je način organiziranja znanja
• U objektno orijentiranom programiranju svodi se na prepoznavanje jednakih značajki među stvarima i stvaranje ključnih apstrakcija
• Ovakav pristup vodi manjim aplikacijama i jednostavnijim arhitekturama
• Ne postoji univerzalan proces klasifikacije
• Ne postoji „savršena” struktura klasa i skup objekata
Važnost ispravne klasifikacije
• Identifikacija klasa i objekata je važan dio objektno orijentiranog dizajna
• Ovaj proces identifikacije uključuju i otkrivanje i osmišljavanje
• Otkrivanje predstavlja prepoznavanje ključnih apstrakcija iz vokabulara ili domene
• Osmišljavanje predstavlja generaliziranje apstrakcija i uvođenje novih mehanizama koji predstavljaju kako objekti surađuju
• Klasifikacija je u suštini problem pronalaženja zajedničkog (svojstava ili ponašanja)
Problematika klasifikacije
• Objekt se često definira kao zatvorena cjelina sa jasno definiranim granicama
• Međutim, granice koje razdvajaju jednu vrstu objekta od druge su u stvarnosti često nejasne
Neki primjeri: ako želimo klasificirati dijelove noge, gdje točno počinje, a gdje završava koljeno
Pri prepoznavanju govora, kako odrediti da neki glas pripada jednoj riječi ili je riječ za sebe
Ako radimo alat za obradu teksta, da li klasama predstaviti slova, riječi ili paragrafe
Klasifikacija živih bića u biologiji
Problematika klasifikacije
• Najbolji dizajn u softveru izgleda jednostavno, ali potrebno se potruditi da bi smo dizajnirali jednostavnu arhitekturu
• Klasifikacija je inkrementalan i iterativan proces
• U prvoj iteraciji se napravi struktura klasa koja u tom trenutku izgleda kao najbolje rješenje
• U kasnijim fazama dizajna, korištenjem takvih klasa otkrivaju se njihove prednosti nedostaci
• Možemo klase doraditi na način da stvorimo nove klase iz postojećih, razbijemo ih u manje cjeline ili možda spojimo više klasa u jednu veću cjelinu
Problematika klasifikacije
• Zašto je klasifikacija teška?
• Ne postoji savršena klasifikacija, iako neke klasifikacije možemo proglasiti „boljima” od drugih
• “There are potentially at least as many ways of dividing up the world into object systems as there are scientists to undertake the task”Coombs, Raiffa, and Thrall
• Bilo koja klasifikacija ovisi o perspektivi promatrača koji obavlja proces klasifikacije
Pristupi klasifikaciji
Povijesno su postojala tri generalna pristupa klasifikaciji:
• Klasična kategorizacija
• Konceptualno grupiranje (eng. conceptual clustering)
• Teorija prototipa
Klasična kategorizacija
• U klasičnoj kategorizaciji svi entiteti koji imaju zadano svojstvo ili skup svojstava pripadaju određenoj kategoriji
• Takva svojstva su nužna i dovoljna da bi se definirala kategorija
• Npr. oženjeni ljudi tvore jednu kategoriji – ovisno o tome svojstvu kategoriziramo entitete
• Visoki ljudi ne tvore kategoriju osim ako ne definiramo neki apsolutni kriterij pomoću kojeg razlikujemo svojstva visok i nizak
• Dijelimo objekte u odvojene skupove ovisno o prisutnosti ili odsutnosti određenog svojstva
• Najkorisniji su oni skupovi svojstava čiji članovi nisu međusobno zavisni, npr. često se koriste skupovi svojstava – boja, veličina, oblik
Klasična kategorizacija
• U generalnom smislu svojstva mogu označavati više od mjerljivih karakteristika, mogu označavati ponašanja, npr. činjenica da ptica leti, a riba ne leti je svojstvo koje razlikuje orla od tune
• Svojstva koja bi se trebala razmatrati u određenoj situaciji su vezana za konkretnu domenu
• Npr. boja automobila je bitna za računalni sustav u tvornicama, ali nije bitna za računalni sustav koji upravlja semaforima
• Klasifikacije je ljudski koncept i ne odražava pravo stanje prirode
• Klasični pristup kategorizaciji ima određene nedostatke: mnoge ptice lete, ali ne sve
• Stolice mogu biti od drva, plastike ili imati proizvoljan broj nogu – koja svojstva odabrati za napraviti klasifikaciju?
Konceptualno grupiranje
• Pri ovom pristupu klase se generiraju formuliranjem konceptualnih opisa ovih klasa i klasificiranje entiteta se obavlja prema tim opisima
• Npr. možemo navesti koncept „ljubavna pjesma”
• Ovdje se radi o konceptu a ne o svojstvu jer se ne može empirijski mjeriti
• Ovaj oblik grupiranja predstavlja probabilistički pristup
• Vezana je uz fuzzy teoriju gdje objekti mogu pripasti u jednu ili više grupa različitim stupnjevima pripadnosti
Teorija prototipa
• Postoje neke apstrakcije koje nemaju ni jasno ograničena svojstva ni koncepte
• Npr. za kategoriju igra nema skupa svojstava koje sve igre posjeduju. Također nema ni fiksne granice za kategoriju igra, kategorija se može proširiti novim vrstama igara, ako na prikladan način nalikuju na postojeće igre
• Ovaj pristup se naziva teorija prototipa jer je klasa objekata predstavljena prototipnim objektom, i neki objekt se smatra članom te klase ako i samo ako nalikuje prototipu na značajan način
• U konceptualnom grupiranju grupiramo stvari prema određenim konceptima, u teoriji prototipa grupiramo po stupnju sličnosti konkretnom prototipu
Primjena metoda klasifikacije
• Na koji način ove teoretske pristupe primijeniti u praksi
• 1. korak – identifikacija klasa i objekata prema svojstvima vezanim uz određenu domenu. Identifikacija struktura i ponašanja koji su dio vokabulara problemske domene. Ako ovo nije dovoljno
• 2. korak – razmatranje grupiranja objekata po konceptima. Fokusiramo se na kolaboraciju objekata . Ako ovo nije dovoljno
• 3. korak – razmatramo klasifikaciju po asocijaciji, odnosno, koliki neka grupa objekta nalikuje nekom objektu kojeg smo izabrali da bude prototip
Klasični pristup
• Shlaer i Mellor navode da kandidati za klase i objekte obično dolaze iz jednog od ovih izvora:
• Opipljive stvari: npr. automobili, podaci sa senzora itd.
• Uloge: npr: majka, učitelj, vozač
• Događaji: npr. zahtjev, slijetanje
• Interakcije: npr: sastanak, posudba, itd.
Analiza ponašanja
• Osim „opipljivih” stvari u problemskoj domeni drugi pristup je analiza ponašanja
• Ključni koncept je identificiranje što se događa u sustavu – odnosno koja su ponašanja prisutna
• Tko inicira i tko sudjeluje u ponašanjima
• Inicijatori i sudionici ponašanja koji igraju važnu ulogu predstavljaju objekte
Use case analiza
• Use case – sekvenca ponašanja između aktera i sustava koja akteru pruža neku mjerljivu vrijednost
• Definiranjem više use case scenarija možemo uočiti važne objekte i njihove karakteristike i ponašanja
• U osnovi analiziramo konkretne zadatke sustava iz perspektive korisnika
• Na taj način se mogu izvući osnovne apstrakcije
• I ovaj proces je iterativan i može zahtijevati mijenjanje inicijalnih apstrakcija
CRC kartice
• Jednostavan i efektivan način analize scenarija
• CRC – Class/Responsability/Collaborators
• Služi za brainstorming i jednostavniju suradnju među developerima
• Na karticu se napiše ime klase, njene odgovornosti i suradnici
• Po jedna kartica se napravi za svaku klasu
• Prolaskom kroz različite scenarije klasama se mogu dodavati nove odgovornosti i suradnici, mogu se mijenjati, stvarati nove klase ili razdvojiti klasu na više manjih sa specifičnim odgovornostima