APNVZ_7 Builder konstrukční návrhový vzor Broker distribuované systémy 1
Konstrukční návrhové vzory Pro tvorbu nových objektů se obyčejně v Javě používají konstruktory. Konstruktory jsou užitečné pokud klient ví, od které třídy chce vytvořit instanci a má k dispozici všechny hodnoty parametrů vyžadované konstruktorem. Konstrukční návrhové vzory jsou zaměřeny na případy, kdy uvedené základní předpoklady neplatí. 2
Konstrukční návrhové vzory Syntaktická a sémantická pravidla, která řídí chování konstruktorů: využívání implicitního konstruktoru, jméno konstruktoru musí být identické se jménem třídy, konstruktor může vyvolávat jiné konstruktory pomocí pseudoproměnné this() a super(), za podmínky, že je toto volání prvním příkazem v konstruktoru, 3
Konstrukční návrhové vzory výsledkem volání konstruktoru je instance třídy, zatímco výsledkem volání metody je cokoli, k vyvolání konstruktoru využíváme metodu new() nebo metody balíčku java.lang.reflection. 4
Builder Kontext: Vytváření objektů (instancí). Problém: Často se stává, že v době vytváření nového objektu (instance) nemáte k dispozici všechny informace pro jeho vytvoření. Řešení: Je výhodné, dovolit konstrukci objektu postupně po krocích, tak jak jsou dostupné jednotlivé parametry pro nově vytvářený objekt. 5
Builder Záměrem vzoru builder je přesunout logiku konstrukce objektu (instance) mimo třídu, ze které se má objekt vytvořit. 6
Standardní builder Požadovaná data pro vytvářený objekt, jsou začleněna do např. textového řetězce. Z důvodu analýzy řetězce je tento třeba uložit v původním stavu a analyzovat - parse. Zpočátku tedy není dostatek dat pro vytvoření objektu nutná analýza. Řešení, které nabízí vzor builder spočívá v uložení těchto dat do nějakého meziobjektu až do doby, kdy je program připraven požádat objekt v paměti o konstrukci cílového objektu z extrahovaných dat. 7
Standardní builder Předpokládejme, že dostáváme informace formou textového řetězce o pořádání ohňostrojů. Tyto informace obsahují: datum, počet diváků, město, cenu vstupenky informaci, zda je či není určeno vhodné místo konání. 8
Standardní builder Např. (uváděné hodnoty jsou ve stejném pořadí, ale uvedeny anglicky): Date, November 15, Headcount, 330, City, Dublin, DollarsPerHead, 8.45, HasSite, False 9
Standardní builder Úlohou je rozčlenit řetězec na dílčí položky a z nich vytvořit objekt třídy Reservace. Standardní postup: vytvoření prázdného objektu třídy Reservace postupné doplňování datových atributů, jak je budeme schopni získat z analyzátoru textu. Problémem jsou ale neúplné a nepřesné informace. Sémanticky nesprávné informace např. málo diváků. Vytvořené objekty třídy Reservace by měly být vždy platné objekty. 10
Standardní builder Řešením je, že objekt třídy Rezervace nebude vznikat ve třídě Rezervace, ale ve třídě ReservationBuilder, do které jsou dočasně postupně uloženy všechny atributy postupně získané činností analyzátoru. Pro vlastní řešení je výhodné, aby třída ReservationBuilder byla abstraktní s abstraktní metodou build(), která je detailněji specifikovaná v podtřídách UnforgivingBuilder, ForgivingBuilder. 11
Standardní builder Požadavek, co chce zákazník - textově oddělené hodnoty čárkou. Požadavek na minimální hodnoty např. MINHEAD = 25, MINTOTAL = $ 498,95. Parser rozloží text pomocí metody tokenize(), builder výsledky ukládá do paměti a následně vytvoří objekt za předpokladu: má všechna požadovaná data, jsou splněny omezující podmínky (sémantika). 12
Diagram tříd aplikace builderu 13
/* * Copyright (c) 2001, 2005. Steven J. Metsker. * Please use this software as you wish with the sole * restriction that you may not claim that you wrote it. */ Poznámky import java.util.*; import com.oozinoz.utility.dollars; /** * Subclasses of this abstract class validate a reservation's * attributes before constructing a Reservation object. */ public abstract class ReservationBuilder { public static final int MINHEAD = 25; public static final Dollars MINTOTAL = new Dollars(495.95); protected Date date = null; protected String city; protected int headcount; protected Dollars dollarsperhead = new Dollars(0); protected boolean hassite;
/** * Push a date into the future by rolling forward the year. * @param indate a date to push forward * @return a date like the one provided but with a year * that makes the date in the future */ public static Date futurize(date indate) { Calendar now = Calendar.getInstance(); Calendar then = Calendar.getInstance(); then.settime(indate); Poznámky while (then.before(now)) then.add(calendar.year, 1); return then.gettime(); /** * Construct a valid reservation from attributes that have * been presumably been set for this builder. Subclasses may * throw an exception if a valid reservation cannot * be formed. * @return a valid reservation */ public abstract Reservation build() throws BuilderException;
public String getcity() { return city; Poznámky public void setcity(string value) { city = value; /** * The date for a reservation. */ public Date getdate() { return date; public void setdate(date value) { date = value; /** * The dollars/head that a customer will pay for a display. */ public Dollars getdollarsperhead() { return dollarsperhead; public void setdollarsperhead(dollars value) { dollarsperhead = value;
/** * Indicates whether a customer has a site in mind for a * display. */ public boolean hassite() { return hassite; Poznámky public void sethassite(boolean value) { hassite = value; /** * The number of people that a customer will guarantee for * a display. */ public int getheadcount() { return headcount; public void setheadcount(int value) { headcount = value;
/** * Copyright (c) 2001, 2005. Steven J. Metsker. * Please use this software as you wish with the sole * restriction that you may not claim that you wrote it. */ Poznámky import java.text.dateformat; import java.text.parseexception; import java.util.calendar; import java.util.date; import com.oozinoz.utility.dollars; public class ReservationParser { private ReservationBuilder builder; /** * Create a parser that will pass its results to the specified * builder. * @param builder the builder to pass parameters to */ public ReservationParser(ReservationBuilder builder) { this.builder = builder; /** * Parse a reservation request, passing its information to the * builder. * @param s the request */ public void parse(string s) throws ParseException { String[] tokens = s.split(",\\s*"); s*");
for (int i = 0; i < tokens.length; i += 2) { String type = tokens[i]; String val = tokens[i + 1]; if ("date".comparetoignorecase(type) == 0) { Calendar now = Calendar.getInstance(); DateFormat formatter = DateFormat.getDateInstance(); Date d = formatter.parse(val + ", " + now.get(calendar.year)); builder.setdate(reservationbuilder.futurize(d)); else if ("headcount".comparetoignorecase(type) == 0) builder.setheadcount(integer.parseint(val)); else if ("City".compareToIgnoreCase(type) == 0) builder.setcity(val.trim()); else if ("DollarsPerHead".compareToIgnoreCase(type) == 0) builder.setdollarsperhead(new Dollars(Double.parseDouble(val))); else if ("HasSite".compareToIgnoreCase(type) == 0) builder.sethassite(val.equalsignorecase("true")); Poznámky
/* * Copyright (c) 2001, 2005. Steven J. Metsker. */ import java.io.serializable; import java.util.date; Poznámky Třída Reservation import com.oozinoz.utility.dollars; public class Reservation implements Serializable { private Date date; private int headcount; private String city; private Dollars dollarsperhead; private boolean hassite; Reservation(Date date, int headcount, String city, Dollars dollarsperhead, boolean hassite) { this.date = date; this.headcount = headcount; this.city = city; this.dollarsperhead = dollarsperhead; this.hassite = hassite;
public String tostring() { StringBuffer sb = new StringBuffer(); sb.append("date: "); sb.append(date.tostring()); sb.append(", Headcount: "); sb.append(headcount); sb.append(", City: "); sb.append(city); sb.append(", Dollars/Head: "); sb.append(dollarsperhead); sb.append(", Has Site: "); sb.append(hassite); return sb.tostring(); Poznámky Třída Reservation public Date getdate() { return date; public int getheadcount() { return headcount; public String getcity() { return city; public Dollars getdollarsperhead() { return dollarsperhead; public boolean hassite() { return hassite;
/* * Copyright (c) 2001, 2005. Steven J. Metsker. */ /** * Signals a problem while building a reservation from its * attributes. */ public class BuilderException extends Exception { /** * Constructs a BuilderException with no detail * message. */ public BuilderException() { Poznámky BuilderException /** * Constructs a BuilderException with the * specified detail message. * @param s detail message */ public BuilderException(String s) { super(s);
/** * Copyright (c) 2001, 2005. Steven J. Metsker. * * Please use this software as you wish with the sole * restriction that you may not claim that you wrote it. */ Poznámky UnforgivingBuilder public class UnforgivingBuilder extends ReservationBuilder { /** * Create a valid reservation. Throw an exception if any required * attribute of a reservation is missing. * @throws BuilderException */ public Reservation build() throws BuilderException { if (date == null) throw new BuilderException("Valid date not found"); if (city == null) throw new BuilderException("Valid city not found"); if (headcount < MINHEAD) throw new BuilderException("Minimum headcount is " + MINHEAD); if (dollarsperhead.times(headcount).islessthan(mintotal)) throw new BuilderException("Minimum total cost is " + MINTOTAL); return new Reservation(date, headcount, city, dollarsperhead, hassite);
/** * Copyright (c) 2001, 2005. Steven J. Metsker. * Please use this software as you wish with the sole * restriction that you may not claim that you wrote it. */ import com.oozinoz.utility.dollars; /** * This class builds a valid reservation from its attributes, * and fills in values where it can if the attributes are not * set. This builder must receive a city and a date, but it * will set reasonable values for the other reservation values. */ public class ForgivingBuilder extends ReservationBuilder { public Reservation build() throws BuilderException { boolean noheadcount = (headcount == 0); boolean nodollarsperhead = (dollarsperhead.iszero()); Poznámky ForgivingBuilder if (noheadcount && nodollarsperhead) { headcount = MINHEAD; dollarsperhead = sufficientdollars(headcount); else if (noheadcount) { headcount = (int) Math.ceil(MINTOTAL.dividedBy(dollarsPerHead)); headcount = Math.max(headcount, MINHEAD); else if (nodollarsperhead) { dollarsperhead = sufficientdollars(headcount); check(); return new Reservation(date, headcount, city, dollarsperhead, hassite);
private Dollars sufficientdollars(int headcount) { Dollars dollars = MINTOTAL.dividedBy(headcount); if (dollars.times(headcount).islessthan(mintotal)) dollars = dollars.plus(dollars.cent); return dollars; Poznámky protected void check() throws BuilderException { if (date == null) throw new BuilderException("Valid date not found"); if (city == null) throw new BuilderException("Valid city not found"); if (headcount < MINHEAD) throw new BuilderException("Minimum headcount is " + MINHEAD); if (dollarsperhead.times(headcount).islessthan(mintotal)) throw new BuilderException("Minimum total cost is " + MINTOTAL);
/* * Copyright (c) 2001, 2005. Steven J. Metsker. */ import com.oozinoz.reservation.*; Poznámky ShowUnforgiwing public class ShowUnforgiving { public static void main(string[] args) { /* Remove "DollarsPerHead, 9.95" to see exception message when /* that field is omitted. */ String sample = "Date, November 5, Headcount, 250, " + "City, Springfield, DollarsPerHead, 9.95, HasSite, False"; ReservationBuilder builder = new UnforgivingBuilder(); try { new ReservationParser(builder).parse(sample); Reservation res = builder.build(); System.out.println("Unforgiving builder: " + res); catch (Exception e) { System.out.println(e.getMessage()); Výsledek: Unparseable date: "November 5, 2009"
/* * Copyright (c) 2001, 2005. Steven J. Metsker. /* import com.oozinoz.reservation.*; Poznámky ShowForgiving public class ShowForgiving { public static void main(string[] args) { /* Remove "DollarsPerHead, 9.95" to see how that field is /* calculated if omitted. String sample = "Date, November 5, Headcount, 250, " + "City, Springfield, DollarsPerHead, 9.95, HasSite, False"; ReservationBuilder builder = new ForgivingBuilder(); try { new ReservationParser(builder).parse(sample); Reservation res = builder.build(); System.out.println("Forgiving builder: " + res); catch (Exception e) { System.out.println(e.getMessage()); Výsledek: Unparseable date: "November 5, 2009"
Shrnutí - Builder Vzor Builder odděluje konstrukci složitých objektů od jejich prezentace. To má okamžitý efekt v tom, že složitá výsledná třída je jednodušší. Třída builderu se zaměřuje na správnou konstrukci objektu a ponechává na výsledné (cílové) třídě zaměření se na vlastní operace validované instance. To má význam že kontrola platnosti dat se provádí před vlastním vytvořením instance. 28
Distribuované systémy Dva hlavní trendy ve vývoji technologií hardware: Počítačové systémy s multiprocesorovými operačními systémy Počítačová síť spojující stovky heterogenních počítačů Výhody distribuovaných systémů: Ekonomické. Počítačová síť s různými PC a pracovními stanicemi poskytuje lepší poměr cena/výkon než sálové (mainframe) počítače. Výkonnost a rozšiřitelnost. Počítačová síť je počítač, distribuované aplikace jsou schopné využívat zdroje dostupné v počítačové síti. 29
Distribuované systémy Distribuovaná podstata řešených aplikací. Sledují model Klient/Server. Spolehlivost. Multiprocesorový systém může havarovat bez účinku na zbytek systému. (Za předpokladu zálohování důležitých serverů). Nevýhody: Distribuované systémy vyžadují radikálně odlišný software než centralizované systémy. To je důvod proč se vyvinuly tři různé platformy: 30
Distribuované systémy CORBA obecná, trpící nedostatkem kompatibility.net orientovaná pouze na systému platformy Windows Java EE orientovaná pouze na jeden jazyk Javu. Cílem vzoru Broker je zevšeobecnění všech výše uvedených konkrétních řešení. Všechny tři platformy používají tzv. ORB (Object Requert Broker), který se liší. 31
Distribuované systémy Distribuovaný systém bude mít intuitivně komponenty, které jsou distribuované na různých počítačích. Na počítač, který hostí některé komponenty distribuovaného systému se odkazujeme jako na hostitelský (host). Koncept hostitelského počítače pak bude označovat všechny operační komponenty počítače, včetně hardware, síťového operačního systému a software. 32
Distribuované systémy Distribuovaný systém má více než jednu komponentu na více než jednom hostitelském počítači. Tyto komponenty se vzájemně ovlivňují, jsou ve vzájemné interakci. Komponenty potřebují poskytovat vzájemný přístup ke službám a potřebují být schopny si požádat o služby navzájem. 33
Distribuované systémy Teoreticky by komponenty mohly být propojeny navzájem pomocí primitiv síťového operačního systému. Prakticky by to bylo příliš složité pro mnoho aplikací. Middleware mezivrstva, která pomáhá s heterogenitou a distribucí. 34
Hostitelský počítač a distribuovaný systém Komponenta 1... Komponenta N Síťový operační systém Hardware Hostitelský počítač 35
Middleware v distribuovaném systému Komponenta 1... Komponenta N Middleware Síťový operační systém Hardware Hostitelský počítač 36
Úkoly middleware Middleware přemosťuje mezeru mezi síťovým operačním systémem a komponentami. Poskytuje navrhovateli vyšší úrovně abstrakce. Implementuje vyšší úrovně abstrakce založené na základních operacích (primitives), které poskytuje síťový operační systém. Zapouzdřuje složitost před návrhářem. 37
Typy middleware 1. Transakčně orientované middleware Toto middleware podporuje transakce přes různé distribuované databázové systémy. Využívá se v architekturách, kde komponenty jsou databázové aplikace. Používá dvou fázový commit protokol k implementaci distribuovaných transakcí. Open Group adoptovala standard pro Open Distributed Transaction Processing (DTP). 38
2. Middleware orientované na zprávy Message oriented middleware Podporuje komunikaci mezi distribuovanými systémy prostřednictvím výměny zpráv. Komponenty klient používají tyto systémy k posílání zpráv, aby požádaly o vykonání služby na komponentě serveru. Obsah zprávy obsahuje i parametry služby. Jiná zpráva je zaslaná klientovi od serveru, aby dodala výsledky služby. 39
2. Middleware orientované na zprávy Message oriented middleware Síla middleware orientovaného na zasílání zpráv je v podpoře asynchronního doručování zpráv, což je velmi přirozené. 40
3. Vzdálené volání procedur Remote Procedure Calls Vyvinuto počátkem 80. let firmou Sun Microsystem jako část platformy Open Network Computing. RPCs jsou operace, které mohou být vyvolány vzdáleně nad různými platformami hardware a operačních systémů. Systémy remote procedure call jsou základem objektově orientovaného middleware. 41
4. Objektově orientované middleware Toto middleware se vyvinulo více méně z myšlenky RPC (vzdálené volání procedur). Prvním z těchto systémů byl OMG produkt Common Object Request Broker Architecture CORBA. Microsoft přidal distribuované schopnosti svému Component Object Model (COM).NET Sun poskytl mechanismus pro Remote Method Invocation (RMI) v Javě. 42
Návrhový vzor Broker zprostředkovatel, jednatel Návrhový vzor Broker se používá ke strukturování distribuovaných softwarových systémů s oddělenými komponentami, které jsou spolu v interakci prostřednictvím vzdáleného volání služeb. Broker (zprostředkovatel) je zodpovědný za koordinaci komunikace jako např. zasílání požadavků, doručování výsledků a výjimek. 43
Návrhový vzor Broker Kontext: distribuované prostředí s možností heterogenních systémů s nezávisle spolupracujícími komponentami Problém: Vytvoření komplexního softwarového systému jako množiny oddělených, mezi sebou operujících komponent. Výsledkem je velká pružnost, udržovatelnost a zaměnitelnost. 44
Návrhový vzor Broker Rozdělením funkcionality do nezávislých komponent se systém stane potencionálně distribuovatelným a škálovatelným. Problémy návrhu komunikace komponent, závislost a omezení: závislost systému na mechanismu komunikace, klienti musí znát fyzické rozmístění serverů, omezení řešení na jeden programovací jazyk. Jsou třeba služby pro přidání, odstranění, aktivaci a lokalizaci komponent, které nejsou závislé na detailech specifikace systému. 45
Návrhový vzor Broker Z pohledu vývojáře by neměl být zásadní rozdíl mezi vývojem software pro centralizovaný systém nebo distribuovaný systém. Objektová aplikace by měla vidět pouze rozhraní poskytované objektem a neměla by vědět nic o implementačních detailech objektu eventuálně o jeho fyzickém umístění. 46
Návrhový vzor Broker Architektura vzor Broker by měla vybalancovat následující síly: Komponenty by měly být schopny zpřístupnit služby poskytované jinými komponentami prostřednictvím vzdálených volání služeb, které jsou transparentní k umístění (lokalizaci). Je třeba zabezpečit změnu, přidání resp. odstranění komponenty za běhu. Navržená architektura (vzor) by měl ukrýt systémové a implementační detaily od uživatelů komponent a služeb. 47
Řešení: Návrhový vzor Broker Zavést komponentu Broker, která dosáhne lepšího oddělení komponent klientů a serverů. Servery se registrují u brokerů a umožňují tak, aby jejich služby byly dostupné pro klienty prostřednictvím rozhraní metod. Klienti si zpřístupní funkcionalitu serverů zasláním požadavků prostřednictvím brokeru. 48
Návrhový vzor Broker Úloha Brokeru zahrnuje lokalizaci vhodného serveru, zasláním požadavků na server a přesun výsledků a výjimek ze serveru zpět klientovi. Využitím vzoru Broker, může aplikace jednoduše zpřístupnit distribuované služby zasláním volání zprávy vhodnému objektu, místo zaměření se na nízko úrovňovou komunikaci procesů. 49
Návrhový vzor Broker Vzor Broker (zprostředkovatel, dohodce) snižuje náročnost distribuované aplikace tím, že je pro vývojáře transparentnější. Využívá k tomu integrace dvou technologií: distribuované technologie a objektové technologie, v objektovém modelu jsou distribuované služby zapouzdřeny uvnitř objektů. 50
Struktura Brokeru Client-side Proxy -transfer message Broker -transfer message Server-side Proxy +packdata() +sendrequest() +return() +maineventloop() +registerservice() +acknowledgement() +findserver() +fincclient() +forwardrequest() +forwardresponse() +packdata() +callservice() +sendresponse() -calls -calls -calls Client +callserver() +starttask() +usebrokerapi() -users API Brodge +packdata() +forwardmessage() +transmitmessage() -users API Server +initialize() +entermainloop() +runservice() +usebrokerapi() 51
Komponenta Server Komponenta server implementuje objekty, které vystavují svoji funkčnost prostřednictvím rozhraní, které se skládá z operací a atributů. Tato rozhraní je dostupné buď prostřednictvím interface-definition-language (IDL), nebo prostřednictvím binárního standardu. Rozhraní typicky seskupují sémanticky blízké funkcionality. Existují dva druhy serverů: servery poskytující běžné služby mnoha aplikačním doménám; servery implementující specifickou funkcionalitu pro jednu aplikaci, doménu, nebo úlohu. 52
Komponenta Client Komponenty client jsou aplikace, které přistupují ke službám alespoň jednoho serveru. K vyvolání vzdálené služby klienti zašlou požadavek brokeru. Po provedení operace obdrží od brokeru výsledky, nebo výjimky. 53
Komponenta Client Interakce mezi komponentami klientů a serverů je založena na dynamickém modelu, který znamená, že servery mohou také působit jako klienti. Tento dynamický interakční model se liší od tradičního označení klient/server výpočtů v tom, že role klientů a serverů nejsou staticky definovány. 54
Komponenta Client Z pohledu implementace můžeme považovat klienty za aplikace a servery za knihovny. Všimněte si, že klienti nepotřebují znát umístění serverů, ke kterým přistupují. To je důležitá vlastnost, protože dovoluje přidání nových služeb a přesun existujících služeb na jinou adresu dokonce za běhu systému. 55
Komponenta Broker Komponenta broker je zprostředkovatel zodpovědný za rozeslání požadavků od klientů k serverům, stejně jako rozeslání odpovědí a výjimek zpět klientům. Komponenta broker musí mít nějaké prostředky pro adresaci příjemce požadavku založeném na jednotném systémovém identifikátoru. Broker poskytuje API klientům a serverům, jenž zahrnuje operace pro registraci serverů a pro vyvolání metod serveru. 56
Komponenta Broker Když přijde požadavek na server, který je udržován místní komponentou broker, tak broker předá požadavek přímo serveru. Není-li právě server aktivní, broker ho aktivuje. Všechny odpovědi a výjimky z prováděné služby jsou zaslány komponentou broker zpět klientovi, který vyslal požadavek. 57
Komponenta Broker Je-li daný server hostem jiné komponenty broker, místní broker nalezne cestu (route) ke vzdálenému brokeru a zašle požadavek používajíc tuto cestu. Je zde potřeba, aby brokery navzájem komunikovaly. V závislosti na požadavcích celého systému, mohou být do komponenty broker integrovány dodatečné operace jako name service nebo marshaling support. 58
Proxy na straně klienta Client-side proxies reprezentuje vrstvu mezi komponentami client a broker. Tato vrstva poskytuje transparentnost v tom, že vzdálený objekt se klientovi jeví jako lokální. Konkrétně proxies umožňují ukrývání detailů implementace od klienta jako např.: mezi procesorový komunikační mechanismus používaný pro přenos zpráv mezi klienty a brokery; tvorba a rušení paměťových bloků; řazení (marshaling) parametrů a výsledků. 59
Proxy na straně klienta V mnoha případech client-side-proxies převádějí objektový model, specifikovaný jako část brokeru, do objektového modelu programovacího jazyka použitého k implementaci klienta. 60
Proxy na straně serveru Server-side proxies je analogické k client-side proxies. Rozdílnost je v tom, že server-side proxies jsou zodpovědné za příjem požadavků, rozbalování příchozích zpráv a volání odpovídajících služeb. Jsou také použity pro řazení výsledků a výjimek před odesláním klientovi. 61
Komponenta Bridge Bridges jsou volitelné komponenty použité k ukrývání implementace detailů, když spolu komunikují dvě komponenty broker. Nejpoužívanější scénář použití ilustruje případ, kdy se komponenta server registruje u komponenty místní (lokální) broker: komponenta broker je odstartovaná v inicializační fázi systému. Vstoupí do smyčky ve které očekává příchod zpráv. uživatel, nebo nějaká jiná entita odstartuje komponentu server aplikace. Po inicializaci se server zaregistruje u komponenty broker. 62
Komponenta Bridge když komponenta broker dostane požadavek registrace od serveru, vybere si z ní všechny potřebné informace a ty si uloží. Tyto informace jsou využity pro nalezení a aktivaci příslušného serveru. Zpět serveru je poslána potvrzovací zpráva. Po obdržení potvrzovací zprávy od komponenty broker, server vstoupí do čekací smyčky na požadavky od klientů. 63
Dynamické chování vzoru Client Client-side Proxy Broker Server-side Proxy Server callserver sendrequest packdata forwardrequest findserver callservice unpackdata runservice forwardresponse packdata return findclient result unpackdata 64
Implementace 1. Definovat objektový model, nebo použít stávající model. 2. Definovat, který druh komponentní interoperability bude systém nabízet. Interoperabilita může být buď specifikovaná binárním standardem, nebo interface definition language (IDL). 3. Specifikovat API, které komponenta brokeru poskytuje pro spolupráci s klienty a servery. 4. Použít objekty proxy k ukrytí implementačních detailů od klientů a serverů. 5. Navrhnout komponentu broker. 6. Vytvořit překladač IDL. 65
Broker - varianty Přímo komunikující Broker System Po počáteční inicializaci klient komunikuje se serverem přímo. Systém Broker předávající zprávy Brokery poskytující rozhraní RPC jsou typickými představiteli. Servery užívají typ zprávy ke stanovení co musí dělat, místo poskytování služeb. Trader system. Standardně Broker zasílá zprávy pouze jednomu serveru. Tento systém je orientovaný na služby. Broker musí vědět, který server(y) poskytuje jaké služby. 66
Broker - varianty Adapter Broker System. Broker funguje jako dodatečná vrstva na serveru. Tato vrstva adapteru je zodpovědná za registraci serverů a interakci se servery. Doplněním více než jednoho adapteru, je možné podporovat různé strategie granularity serveru a jeho lokace. 67
Broker - varianty Callback Broker System. Reaktivní model je řízený událostmi, nedělá rozdíl mezi klienty a servery. Kdykoli přijde událost, broker vyvolá metodu callback komponenty, která je registrovaná, že reaguje na událost. Může vyvolat novou událost 68
Použití V objektových technologiích pro distribuované zpracování. Tento vzor je použit ke specifikaci Common Object Request Broker Architecture (Corba). Pro podporu interoperability je definován interface definition language (IDL). Java EE distribuovaná technologie firmy (Sun) Oracle..NET distribuovaná technologie firmy Microsoft. 69
Výhody Transparentnost umístění je umožněna tím, že komponenta broker je zodpovědná za vyhledání serveru podle jedinečného identifikátoru. Zaměnitelnost a rozšiřitelnost komponent. Portabilita systému s komponentou broker. Interoperabilita mezi různými systémy s komponentou broker. Znovupoužitelnost. 70
Slabá místa Omezená výkonnost. Nízká odolnost vůči chybám. Testování a ladění. 71