Half Object Plus Protocol (HOPP)
Proprietati
Tip: Structural
Nivel: Componenta
Scop
Ofera o singura entitate care traieste īn doua sau mai multe spatii de adrese.
Introducere
O aplicatie distribuita Java foloseste obiecte peste spatii de adrese diferite - mai multe masini virtuale Java (JVM). Pentru tehnologii precum RMI, obiectele la distanta pot apela metode pe 23323y247x obiecte care sunt instantiate īn alte JVM, permitānd distribuirea starii si comportamentului. Pentru ca aplicatia distribuita sa functioneze, indiferent ce tehnologie se foloseste, obiectele din JVM diferite trebuie sa comunice unul cu altul.
Sa presupunem ca avem doua masini, A si B, si ca īn fiecare este īn executie o JVM. Presupunem, de asemenea, ca un obiect din JVM (masina A) are nevoie de un stub pentru a apela metodele unui obiect din JVM (masina B). Odata ce obiectul din masina A are acces la stub, A poate apela metodele pe acel stub, care vor fi redirectionate spre obiectul din masina B.
Dezavantajul este ca toate apelurile de metode pe stub vor fi redirectionate prin retea, ceea ce nu este de dorit īn toate cazurile. Cāteodata se doreste ca stub-ul sa execute local unele dintre metodele apelate, fara a le trimite la obiectul aflat la distanta.
Acesta este un exemplu de obiect care exista īn doua sau mai multe spatii de adrese. Proxy-ul (reprezentarea locala a obiectului aflat la distanta) este considerat ca parte a obiectului aflat la distanta. Prin executarea metodelor local si īn JVM la distanta, un obiect executa comportamentul sau īn mai multe spatii de adrese. Asa se manifesta sablonul HOPP.
Aplicabilitate
sablonul HOPP se foloseste cānd:
Un obiect trebuie sa existe īn doua spatii de adrese diferite si nu poate fi divizat.
O parte a functionalitatii trebuie sa se execute la distanta, iar o alta parte a metodelor trebuie sa se execute local.
Optimizarile, precum caching-ul, sau combinarea mai multor cereri īntr-o singura tranzactie pe retea, trebuie aplicate īntr-o maniera transparenta pentru apelator.
Descriere
Aplicatiile distribuite sunt dificil de scris. Una dintre problemele īntālnite este aceea ca o singura entitate (obiect) trebuie sa existe īn mai multe spatii de adrese. Aceasta deoarece obiectul are nevoie sa acceseze multiple dispozitive fizice pe masini diferite sau deoarece obiectul nu poate fi divizat īntr-o maniera logica.
Divizarea unui obiect īn doua, si apoi facerea celor doua jumatati sa comunice la distanta se realizeaza prin executarea rmic cu optiunile keep sau -keepgenerated. Prin aceasta, se economiseste codul sursa pentru stub. Pe urma, codul sursa se editeaza astfel ca anumite metode sunt gestionate de stub si nu sunt redirectionate spre obiectul de la distanta. Cānd se compileaza codul sursa astfel modificat, se va produce o versiune personalizata a stub-ului.
Din pacate, aceasta limiteaza folosirea ulterioara a rmic deoarece ori de cāte ori se foloseste rmic pe obiectul la distanta, este nevoie ca sa se editeze manual codul sursa produs.
Solutia este sa se divida obiectul īn doua si sa se ofere celor doua jumatati posibilitatea de a comunica. Fiecare jumatate se implementeaza astfel ca sa poata interactiona cu obiectele din spatiul sau de adrese. Protocolul este responsabil de sincronizarea celor doua jumatati si cu transmiterea informatiei īntre ele.
Acesta este modul de functionare a sablonului HOPP - se creeaza un obiect care implementeaza interfetele la distanta cerute si care contine o referinta la stub-ul original al obiectului de la distanta. Metodele care trebuie sa se comporte normal (adica trebuie redirectionate spre obiectul la distanta) sunt redirectionate spre stub. Metodele care trebuie sa se execute local sunt gestionate de noua clasa.
Numele HOPP provine de la faptul ca clientul obiectului divizat primeste o jumatate de obiect. Acea jumatate contine si protocolul care-i permite sa comunice cu cealalta jumatate, deci per total jumatate de obiect plus protocol (Half-Object Plus Protocol).
Implementare
Diagrama de clase a sablonului HOPP este
prezentata īn Figura 1
Figura 1. Diagrama de clase a sablonului HOPP
Pentru implementarea sablonului HOPP este nevoie de urmatoarele:
HOPP - Interfata care defineste metodele disponibile pentru clientul sablonului HOPP. Ambele jumatati ale obiectului HOPP implementeaza aceasta interfata.
LocalHOPP - Clasa care implementeaza interfata HOPP. Unele dintre metode se executa local; celelalte sunt redirectionate spre RemoteObjectProxy
RemoteObjectProxy Clasa care corespunde unui proxy la distanta si redirectioneaza toate cererile spre cealalta jumatate a obiectului, aflat īn alt spatiu de adrese. Acest proxy īncapsuleaza protocolul care leaga cele doua jumatati de obiect.
RemoteObject Aceasta jumatate a HOPP contine toate metodele care se executa la distanta.
Client - Apeleaza metodele din interfata HOPP. Aceste apeluri de metode sunt transparente pentru client, indiferent daca acesta foloseste un Remote Proxy, un HOPP, sau un obiect local.
Avantaje si dezavantaje
Avantaje:
Avantajul acestui sablon este ca se dispune de un obiect īn doua spatii de adrese, fara prea multa īncarcatura suplimentara. Pentru clientul care foloseste o parte a HOPP, aceasta este transparent. Clientii nu sunt afectati de faptul ca obiectul exista īntr-unul sau mai multe spatii de adrese.
Este chiar posibila ascunderea completa a diferentelor, asa īncāt clientul crede ca foloseste un obiect local, desi parti din el nu sunt locale. si reversul este posibil - se poate face astfel implementarea, īncāt clientul crede ca foloseste un Remote Proxy, cānd de fapt foloseste un HOPP care contine un Remote Proxy. Aceasta prezinta avantajul ca unele dintre metodele care erau prevazute sa se execute la distanta se executa acum local.
Un avantaj foarte puternic este acela ca sablonul permite optimizari dedicate. Fiecare jumatate a HOPP poate determina cānd si cum doreste sa comunice cu cealalta jumatate. Aceste strategii de comunicare pot īmbunatati performanta prin scaderea numarului de apeluri prin retea fara ca sa fie afectat codul client de la oricare dintre capete.
Dezavantaje:
Dezavantajul este ca o parte a functionalitatii trebuie duplicata. Este necesar acest lucru deoarece fiecare jumatate trebuie sa posede suficienta functionalitate pentru a gestiona obiectele locale.
Variatiuni la acest sablon
Fiecare dintre jumatati pastreaza o referinta la cealalta jumatate si īsi trimit mesaje una alteia. Īn varianta clasica, numai HOPP de la client are o referinta la cealalta jumatate. Prin urmare, numai HOPP de la client poate initia comunicatia cu jumatatea de la distanta prin apelarea unei metode. Jumatatea de la distanta raspunde numai la fiecare apel prin valoarea returnata. Daca este necesar ca ambele jumatati sa initieze comunicatia, fiecare dintre ele trebuie saa aiba o referinta la cealalta jumatate.
Smart HOPP (SHOPP, HOPP destept). Īn aceasta implementare, partea locala a HOPP īsi poate alege companionul din mai multe strategii de conectare. Aceasta varianta este utila, de exemplu, cānd aplicatia este distribuita īntr-o reteaa flexibila, īn care intra si ies masini.
Asymmetric HOPP HOPP asimetric. Īn aceasta versiune a sablonului HOPP, nu este necesar ca ambele jumatati sa implementeze exact aceeasi interfata. Partea aflata la distanta a lui HOPP poate furniza un proxy nou care sa fie folosit de cealalta parte. Acest proxy nou poate contine anumite optimizari, sau chiar poate fi un proxy pentru un alt obiect aflat la distanta.
sabloane īnrudite
Mediator - Obiectele care au nevoie de mediere sunt distribuite īn spatii de adrese diferite. sablonul Mediator poate folosi sablonul HOPP pentru a simplifica comunicarea.
Proxy, mai exact Remote Proxy - sablonul HOPP foloseste sablonul Proxy pentru comunicarea transparenta dintre cele doua jumatati ale sale.
Exemplu
PIM trebuie sa fie disponibil īn multe locuri, īnsa datele pe care le pastreaza trebuie memorate īntr-un singur loc. Exemplul de fata foloseste RMI si sablonul HOPP pentru a pastra un calendar personal pe un server, facānd disponibila informatia din el la clienti aflati la distanta.
Interfata Calendar defineste toate metodele care vor fi disponibile la distanta. Aceasta interfata extinde interfata java.rmi.Remote si toate metodele sale declanseaza exceptia java.rmi.RemoteException. Īn cazul de fata, Calendar defineste trei methode: getHost getAppointments si addAppointment
Exemplul 1 Calendar.java
1. import java.rmi.Remote;
2. import java.rmi.RemoteException;
3. import java.util.Date;
4. import java.util.ArrayList;
5. public interface Calendar extends Remote
Interfata Calendar este implementata de doua clase - obiectul RMI la distanta si stub-ul (proxy-ul) sau. Clasa obiectului aflat la distanta, CalendarImpl, furnizeaza implementarile metodelor, pe cānd stub-ul gestioneaza comunicatia cu obiectul aflat la distanta. Compilatorul Java RMI (rmic) trebuie executat (rulat) pe CalendarImpl pentru a genera cāte o clasa stub si skeleton. Clasa skeleton este furnizata pentru compatibilitate cu versiunile anterioare, nefiind necesara īncepānd cu Java 1.2.
Exemplul 2 CalendarImpl.java
1. import java.rmi.Naming;
2. import java.rmi.server.UnicastRemoteObject;
3. import java.io.File;
4. import java.util.Date;
5. import java.util.ArrayList;
6. import java.util.HashMap;
7. public class CalendarImpl implements Calendar
public CalendarImpl(String filename)
try
catch (Exception exc)
}
public String getHost()
public ArrayList getAppointments(Date date)
return returnValue;
}
public void addAppointment(Appointment appointment, Date date)
else
}
Obiectul CalendarImpl trebuie sa foloseasca clasa de sprijin RMI UnicastRemoteObject pentru ca sa poata gestiona cererile de comunicare adresate ei. Īn acest caz, constructorul clasei CalendarImpl se exporta folosind metoda statica UnicastRemoteObject.exportObject. Obiectul CalendarImpl are nevoie si de o modalitate de publicare a sa pentru lumea exterioara. Īn RMI, serviciul de nume apeleaza rmiregistry. Acesta trebuie sa fie īn executie īnainte de crearea obiectului CalendarImpl. Serviciul rmiregistry este ca o carte de telefon, oferind legatura dintre un nume si un obiect. Cānd obiectul CalendarImpl se īnregistreaza īn rmiregistry prin metoda rebind, el leaga numele "calendarimp" de stub-ul obiectului de la distanta.
Pentru ca un client sa foloseasca obiectul de la distanta, el trebuie sa consulte īn rmiregistry al masinii gazda si sa primeasca stub-ul obiectului la distanta. Stub-ul se poate compoara cu un numar de telefon. Numarul se poate folosi de oriunde, pe orice telefon, si se obtine o conexiune cu cineva care raspunde la numarul de telefon format. Īn exemplul de fata, clasa CalendarHOPP este pe post de client pentru obiectul CalendarImpl
Exemplul 3 CalendarHOPP.java
1. import java.rmi.Naming;
2. import java.rmi.RemoteException;
3. import java.util.Date;
4. import java.util.ArrayList;
5. public class CalendarHOPP implements Calendar, java.io.Serializable
public CalendarHOPP(String host)
catch (Exception exc)
}
public String getHost()
public ArrayList getAppointments(Date date) throws RemoteException
public void addAppointment(Appointment appointment, Date date)
throws RemoteException
Clasa CalendarHOPP ofera un beneficiu esential īn raport cu un client conventional RMI - ea poate executa local ceea ce īn mod normal īnseamna apeluri de metode la distanta. Aceasta poate aduce un beneficiu substantial din punctul de vedere al īncarcarii datorate comunicatiei. sablonul HOPP implementeaza aceeasi interfata la distanta, dar nu se exporta. El pastreaza o referinta la stub si redirectioneaza toate apelurile de metode pe care nu le poate gestiona la stub. El poate implementa acum metodele ce se doreste a fi executate local - īn exemplul de fata, metoda getHost. sablonul HOPP se poate īnregistra īn rmiregistry ca orice stub normal, īnsa acum el are abilitatea de a executa local unele metode.
|