P r o g r a m i r a nj e
PC home - osnovna strana
PC #34 - April 1998

Java u zrnima

Ključ programerskog uspeha je u višestrukom korišćenju napisanog koda. Najnaprednija tehnologija te vrste nosi ime softverske komponente, a njen predstavnik je JavaBeans, jedan od glavnih oslonaca Jave u bitci za dominaciju na tržištu razvojnih alata. 

Ivan Ristić


  

 

 

 

 

Klikni za uvecanu sliku

Java nije odmah dobila okruženje pogodno za korišćenje softverskih komponenti. Tek Jave 1.1 specifikacijom se precizno definiše način pisanja klasa, kojim one postaju "zrna" (Beans).

BeanBox

JavaSoft-ov Bean Development Kit, sa desetak gotovih primera, pretvara čitavu ovu priču u praksu. Koristeći BeanBox možete da ubacuje "zrna" u peščanik, međusobno ih povezujete i izazivate događaje. Zahvaljujući dobro izabranim primerima, proces istraživanja JavaBeans tehnologije je vrlo zabavan. Prva stvar koju sam probao (baš kao i pola miliona drugih ljudi, pretpostavljam) je da na radnu površinu postavim Jugglera i dva tastera. Pritiskom na prvi taster žongler počinje sa žongliranjem, a pritiskom na drugi prestaje. Jednostavnost kreiranja je zadivljujuća.

Zongler

JavaBeans u praksi: jedan od prvih primera je "žongler", koga kontrolišete koristeći dva tastera.

Na slici gore možete videti ovaj primer, kao i radnu površinu posle pola sata igranja ovom aplikacijom. Da biste se i sami poigrali, potrebni su vam sledeći sastojci: Java Development Kit 1.1.4 ili viši, Bean Development Kit (Februar 98) i nešto slobodnog prostora na disku. Kao i uvek, sve relevantne informacije o Javi preuzećete sa www.javasoft.com.

   

Umesto da kuću gradite tako što sve, čak i najmanje delove, pravite sami, zidate koristeći gotove komponente različitih proizvođača, sklapajući od njih celinu. Ovakav proces, tako uobičajen u životu, dugo nije bio moguć u programerskom svetu; prvo popularno razvojno okruženje koje je uspešno primenilo ovakav proces bio je Microsoft Visual Basic, a sledili su ga i mnogi drugi. Osnovni cilj je brzina: tempo kreiranja današnjih softverskih paketa je paklen, a od projektanata se po pravilu očekuje da softver bude završen "juče". A ako se tu uračunaju i izbegnuti troškovi testiranja i ispravljanja grešaka, dobici su mnogo veći.

   

Mr. Bean

Pošto je uspeh Jave iznenadio i same kreatore jezika, ovo okruženje je dugo postojalo bez standarda za "pakovanje" u softverske komponente. Tek je verzija Jave 1.1 (ne dajte se zavarati, razlike između verzija 1.0 i 1.1 su ogromne) donela specifikaciju o kojoj je ovde reč. Specifikacijom se precizno definiše način pisanja klasa, kojim one postaju "zrna" (Beans - moglo bi se prevesti i kao "pasulj"). Razlika između klase i "zrna" je zapravo vrlo mala, pa tako dolazimo do glavne prednosti JavaBeans tehnologije: jednostavnost.
Ako pravite nevidljivo "zrno", dovoljno je da to bude obična klasa, koja implementira interfejs Serializable. Ovaj interfejs omogućava perzistenciju, zamrzavanje trenutnog stanja objekta i njegovo čuvanje do ponovnog oživljavanja u identičnom stanju. Ako pravite "zrno" koje treba da bude vidljivo, potrebno je da nasledite klasu java.awt.Canvas. Osnovni elementi jednog "zrna" su osobine (properties), metodi (methods) i događaji (events). Osobine definišu izgled i ponašanje, pozivanjem metoda "zrno" radi posao kome je namenjeno i pri tome generiše događaje, kojima komunicira sa ostalim elementima aplikacije.
Pre nego što se upustimo u detaljno opisivanje glavnih elemenata, moramo se zapitati kako saznajemo osobine jednog "zrna", kada ga dobijemo? Koristićemo klasu java.beans.Introspector, koja kao rezultat vraća objekat klase BeanInfo, koji "zna" sve o dotičnom "zrnu". Interesantna stvar je što mi, kao kreatori "zrna", uopšte ne moramo da unosimo podatke - ako sledimo jednostavna pravila za davanje imena metodima klase, Introspector će sam shvatiti o čemu se radi! Osobinama "zrna" se ne pristupa direktno, već preko get i set metoda. Ako definišete metode:

public void setXXX(XXXType vrednost);
public XXXType getXXX();
klasa Introspector će "znati" da "zrno" poseduje osobinu naziva XXX i tipa XXXType, koja se može čitati i pisati. Izostavljanjem jednog od metoda dobija se read-only, odnostno write-only osobina. Ako pretpostavimo da naše "zrno" poseduje objekat klase String, metodi za rad sa tim objektom bi izgledali ovako (ako imamo logičku promeljivu, možemo koristiti i oblik isXXX().:

public void setStatus(String status);
public String getStatus();

   

Metodi i događaji

Događaji su jedini vid komunikacije "zrna" sa spoljnim svetom. Događaj je predstavljen objektom klase java.util.EventObject (ili iz nje izvedene klase). Dužnost "zrna" je da vredno radi i kreira definisane događaje kad god je to potrebno. Osim toga, dužnost "zrna" je i da obezbedi metode kojima će se drugi zainteresovani objekti prijavljivati za primanje određenih događaja. Za svaki događaj je potreban po jedan par metoda. Uzmimo za primer imaginarno "zrno" LazyBean, koje obavlja neki posao koji dugo traje. Lepo bi nam došao događaj StatusChangeEvent, ekstenzija standardnog događaja koja sve "zainteresovane stranke" obaveštava o trenutnom stanju zadatka koji se izvršava (slika 1). Uz svaki događaj (ili grupu događaja koji su logički povezani) ide bar jedan interfejs koji predstavlja "uputstvo" ostalim objektima za primanje događaja. Poslednja karika u ovom lancu je par metoda potrebnih za prijavljivanje i odjavljivanje primanja određenih događaja. U našem slučaju, oni bi izgledali kao na slici 2 (listener je objekat klase java.util.Vector).
Metodi za dodavanje adresa objektu listener su sinhronizovani, jer se pretpostavlja da se jednom "zrnu" može pristupiti iz više aktivnih niti. Iz sličnog razloga se ne preporučuje sinhronizovanje samog metoda za slanje događaja. Umesto toga, preporučuje se sinhronizacija objekta samo prilikom pribavljanja spiska adresa na koje treba poslati događaj, što se vidi i iz priloženog koda.
Napomenimo i da "zrno" može imati događaj koji će poslati samo jednom primaocu. U tom slučaju bi se metod za prijavljivanje definisao ovako:

public synchronized addStatusChangeListener(StatusChangeListener scl)
	throws java.util.TooManyListenersException;
pri čemu "zrno" baca izuzetak java.util.TooManyListenersException, ako je mesto primaoca već popunjeno. U JavaBeans terminologiji ovakvi događaji nazivaju se unicast, za razliku od uobičajenih, multicast događaja.
Usko vezani za događaje su specijalne klase-adapteri, koje ćemo ovde samo kratko pomenuti. Oni mogu poslužiti u razne svrhe uz najčešću upotrebu za povezivanje dva nesrodna "zrna" i demultipleksiranje događaja. Recimo da imate "zrno" koje može kao događaj primiti pritisak tastera. Kako vi želite da na to "zrno" zakačite dva tastera, recimo ok i cancel, morate da napravite malu akrobaciju, kreirajući dve nove klase koje će primati pritisak jednog tastera i prosleđivati ga na odgovarajući metod "zrna".

   

Korišćenje JavaBeans-a

"Zrno" koristite kao i svaku drugu klasu: novi objekat kreiraćemo new pozivom, ako smo zainteresovani prijavićemo se za primanje događaja koje "zrno" šalje i to je sve. Ako želimo da kreiramo "zrno" čije ime ne znamo u toku pisanja programa, poslužićemo se klasom java.beans.Bean, koja poseduje metod instantiate(), kojim se kreira "zrno" samo na osnovu zadatog naziva.
Kod ozbiljnijeg rada zatrebaće vam i dodatne opcije, kao što je klasa BeanInfo. Klasa Introspector je dovoljno "pametna" da, koristeći Reflection API (niz metoda za analizu nepoznate klase), na osnovu naziva polja, otkrije osobine "zrna". Ovo znatno olakšava posao piscima softverskih komponenti koji ne moraju "ručno" da kreiraju opis. Zgodno je to što Introspector vraća objekat klase BeanInfo, koji sadrži sve otkrivene informacije.
Ako želimo nešto da dodamo opisu, možemo kreirati sopstveni objekat ove klase, a Introspector će ga proslediti, umesto da sam vrši analizu. Ovim postupkom se ne može efikasno sprečiti korišćenje javnih metoda "zrna", jer će svako ko direktno koristi Reflection API moći da dođe do kompletnih podataka. Mogućnosti klase BeanInfo su velike, tako da je moguće pružiti detaljne informacije o "zrnu", počevši od naziva i podataka o proizvođaču preko naziva metoda pa sve do ikona koje će se koristiti za predstavljanje "zrna" u razvojnim alatima.
Interesantno je da BeanInfo podržava internacionalizaciju - isti metodi mogu imati različite nazive, zavisno od područja na kome se koriste. Na sreću, radi se samo o nazivima koji se koriste u razvojnim alatima - u samom kodu se i dalje moraju koristiti originalni nazivi. Niz zanimljivih mogućnosti postoji kada su u pitanju osobine "zrna". Najinteresantnije su mogućnosti postojanja vezanih (bound) i uslovljenih (constrained) osobina. Vezane osobine su kombinacija običnih osobina i događaja. Svaki put kada se neka od vezanih osobina "zrna" promeni, nastaje događaj, koji obaveštava ostale objekte o promeni.
Uslovljene osobine su vrlo slične, ali se događaj emituje pre promene vrednosti, a od primalaca se očekuje da promenu odobre (ne reagujući) ili odbace, emitujući izuzetak PropertyVetoException. Metod za postavljanje nove vrednosti uslovljene promenljive bi glasio public void setStatus(String status) throws PropertyVetoException, uz normalne metode za prijavljivanje i odjavljivanje. JavaBeans specifikacija uključuje i specijalne klase za promenu i podešavanje (customization) osobina "zrna". Ako napravite iole komplikovanije "zrno", možete uz njega isporučiti i Wizard za lakše korišćenje, što će korisnici verovatno s radošću prihvatiti.

   

Šta će biti sutra?

Pretpostavljajući da će JavaBeans tehnologija uspeti, u JavaSoft-u ubrzano rade na ispravljanju nedostataka postojeće specifikacije. Sledeća verzija nosi ime Glasgow i trebalo bi da donese bar tri nove osobine: Drag & Drop funkcionalnost (što je zapravo deo JFC-a ali blisko povezano sa JavaBeans-om), specifikaciju za interakciju "zrna" sa okolinom (slično AppletContext-u, ali komplikovanije) i JavaBeans Activation Framework, tehnologiju koja omogućava pridruživanje tipa grupi podataka i čuvanje svih informacija o tom tipu kao i o "zrnima" potrebnim da njime barataju. Očigledno, broj API-ja koji postoji raste ogromnom brzinom, a da li je to dobro, ostaje da se vidi.
Nezavisno od sistema koji koristite, softverske komponente predstavljaju veliki korak napred. One efektivno dele programerski svet na dve grupe, jednu čiji je posao pisanje komponenti i rad na niskom nivou, sa puno programskog koda, i drugu u koju spadaju programeri koji rade sa razvojnim alatima visokog nivoa, spajajući gotove komponente. JavaBeans je dobro balansirana tehnologija, koja se prirodno nadovezuje na Javu i dozvoljava da brzo krenete sa radom, držeći sve konce u svojim rukama. Uspeh JavaBeans tehnologije u potpunosti zavisi od uspeha samog Java okruženja.
Slika 1

public class StatusChangeEvent extends java.util.EventObject {
   protected String status;
   public StatusChangeEvent(LazyBean source, String status) {
      super(source);
      this.status = status; }
   public String getStatus() {
      return new String(status); }
}
interface StatusChangeListener extends java.util.EventListener {
   void statusChanged(StatusChangeEvent sce);
}
Slika 2

public synchronized void addStatusChangeListener(StatusChangeListener scl) {
   listeners.addElement(scl); }
public synchronized void removeStatusChangeListener(StatusChangeListener scl) {
   listeners.removeElement(scl); }
Konačno, obaveštavanje zainteresovanih klijenata bi izgledalo ovako:

protected void fireEvent(String status) {
   Vector v;
   StatusChangeEvent sce = new StatusChangeEvent(this, status);
   synchronized(this) { v = (Vector)listeners.clone(); }
   for(int i=0; i < v.size; i++)
      ((StatusChangeListener)v.elementAt(i)).statusChanged(sce); }


PC home - osnovna strana Novi broj|Arhiva|Pretrazivanje svih brojeva|O nama
Pretplatite se na PC|Postanite saradnik casopisa PC|Pitanja i komentari u vezi casopisa