Builder Builder - motivácia  Motivácia  sitemap v rôznych výstupoch      HTML XML Plain text … Ako na to?  triviálne, ale…     znovupoužiteľnosť kódu prehľadnosť „sadnem si ku kódu za 2 roky“ builder.

Download Report

Transcript Builder Builder - motivácia  Motivácia  sitemap v rôznych výstupoch      HTML XML Plain text … Ako na to?  triviálne, ale…     znovupoužiteľnosť kódu prehľadnosť „sadnem si ku kódu za 2 roky“ builder.

Builder
Builder - motivácia

Motivácia

sitemap v rôznych výstupoch





HTML
XML
Plain text
…
Ako na to?

triviálne, ale…




znovupoužiteľnosť kódu
prehľadnosť
„sadnem si ku kódu za 2 roky“
builder
Builder

„Definícia“
vytvárací návrhový vzor (creational design pattern)
 oddeľuje konštrukciu zložitých objektov od ich reprezentácie


Problém

máme rôzne zložité objekty s podobným postupom konštrukcie


sitemap v HTML, sitemap v XML, ...
Zámer
vytvoriť rovnakým postupom rôzne reprezentácie
 systematicky vytvárať zložité objekty
 zjednodušiť rozšíriteľnosť do budúcnosti


ešte sitemap v Plain text, ešte sitemap v UltraXYZ, ...
sprehľadniť zdrojový kód
 skryť konkrétne implementačné detaily


že tam je presne <a href=... a <span style=“color: red“> nemusí nikto vedieť
Builder – schéma

Štruktúra

Časti

Director


Builder


definuje interface pre konštrukciu jednotlivých častí výsledného objektu
ConcreteBuilder



použije predhodený builder a po krokoch vytvorí objekt
implementuje interface Builder-u
definuje a skladuje vytvorenú reprezentáciu, na požiadanie ju vráti
Product

reprezentuje vytváraný objekt, prístup z ConreteBuilder-u
Builder - príklad

Príklad: Fast-food


vo fast-foode robia o. i. hamburgery
jednotný postup


žemľa, syr, omáčka, mäso, zelenina, ...
Direktor

nikto „neexperimentuje“

do hamburgerov sa dajú pridať iba vyššie spomenuté prísady
 jednotné rozhranie
 Builder
líšia sa v zložkách




„chickenburger“ - kuracie mäso, „cheeseburger“ – bez mäsa, viac syru, ...
ConcreteBuilder
hotový hamburger


Product
na požiadanie vydá ConcreteBuilder

ten, kto ho vyrobil
Builder – schéma volaní
Builder - implementácia

Builder

typicky abstraktná trieda


niekedy interface
virtuálne metódy


definujú, čo ma každý ConcreteBuilder vedieť
nie nutne „pure virtual“ metódy



dostatočne všeobecné rozhranie
nie nutne „void“



reimplementovať iba tie, ktoré mienime spracovávať z daného CBuilder-u
identifikácia vytvorených častí
poradie, náväznosť dielcov vedúcich k výslednému Product
Product

žiadna abstraktná trieda


nemalo by zmysel – zväčša sa dosť odlišujú
výzor produktu je daný konkrétnym ConcreteBuilder-om
Builder – príklad na UML diagramoch
Kód tvorby sa
nezaoberá konkrétnou
reprezentáciou
každému ConcreteBuilder-u prislúcha
reprezentácia výsledku
jednotné rozhranie
Builder – súvislosti, dôsledky

Štruktúra Produktu je viazaná na ConcreteBuilder

interface pre konštrukciu rovnaký
vnútorná štruktúra produktu schovaná

aj to, jak je presne zostavený (skryté konkrétne implementačné detaily)
zmena produktu = nový builder



Oddelenie konštrukcie od reprezentácie

modularita, zapuzdrenie (encapsulation)




Client nepotrebuje nič vedieť o triedach definujúcich Produkt (nie sú ani v rozhraní)
jeden Builder sa dá použiť pre rôzne Director-y
Director nevie presne o konkrétnej štruktúre Produktu
Umožňuje kontrolu konštrukcie za jej priebehu
konštrukcia produktu „step-by-step“ (riadi Director)
 interface odráža proces konštrukcie produktu

Príklad Builder-u: Sitemap
Príklad Builder-u: Sitemap - Client
Požadovaný Builder
SiteMapBuilder builder = new XMLSiteMapBuilder();
SiteMapDirector director = new SiteMapDirector(builder);
director.Construct(webPageData);
Director dostane daný Builder
Necháme Director-a robiť svoju prácu
(nad zadanými dátami)
String siteMap = builder.GetSiteMap();
Sami z BUILDERU vyberieme výsledok
Príklad Builder-u: Sitemap - Director
public class SiteMapDirector {
SiteMapBuilder builder;
public void Construct(WebPageData data) {
try {
builder.BuildHeader();
siteMapBuilder.buildHeader();
for (int i = 0; i < data.webpages.length; i++) {
for (int i = 0; i < Data.webpages.length; i++) {
builder.BuildPage(new URL(data.webpages[i].getUrl()));
siteMapBuilder.buildPage(new YRL(Data.webpages[i].getUrl()));
}
}
builder.BuildFooter();
siteMapBuilder.buildFooter();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
Vlastná logika Director-u
Príklad Builder-u: Sitemap – XML builder
public class XMLSiteMapBuilder implements SiteMapBuilder {
private String siteMap;
public void BuildHeader() {
siteMap += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<urlset xmlns=\"...\">\n";
}
public void BuildPage(URL url) {
siteMap += "<url><loc>" + url.urlString + "</loc></url>";
}
public void BuildFooter() {
siteMap += "</urlset>\n</xml>\n";
}
public String GetSiteMap() {
return siteMap;
}
}
Príklad Builder-u: Sitemap – Text builder
public class TextSiteMapBuilder implements SiteMapBuilder {
private String siteMap;
public void BuildPage(URL url) {
siteMap += url.urlString + "\n";
}
public String GetSiteMap() {
return siteMap;
}
}
Príklad Builder-u 2 - motivácia
public class User
private final
private final
private final
private final
private final
}


chceme konštruktory s povinnými + všetky možné podmnožiny voliteľných argumentov
zásadne nechceme „setters“



konzistentný kód
viacvláknová aplikácia
jak vynútiť immutability...?
Riešenie 1: Použiť voliteľné argumenty


//required
//required
//optional
//optional
//optional
Konštruktory s voliteľnými argumentmi


{
String firstName;
String lastName;
int age;
String phone;
String address;
v Java, .NET staršom než 3.0, nejde!
Riešenie 2: Naprogramovať všetky možné konštruktory

...
Príklad Builder-u 2 – riešenie 2
public User(String firstName, String lastName)
this(firstName, lastName, 0);
}
public User(String firstName, String lastName,
this(firstName, lastName, age, "");
}
public User(String firstName, String lastName,
this(firstName, lastName, age, phone, "");
}
public User(String firstName, String lastName,
address) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.phone = phone;
this.address = address;
}
{
int age) {
int age, String phone) {
int age, String phone, String
// ... ešte treba ďalších 4 ...
// ... a čo zámena? „phone“ a „address“ sú rovnakého typu ...
Príklad Builder-u 2 – riešenie 3: Builder pattern

Riešenie 3: Použijeme Builder pattern

Jak?

Programátor, ktorý volí argumenty: Director
ConcreteBuilder: jediný argument konštruktoru triedy „User“

trieda „User“ si z ConcreteBuilder vytiahne Product

public class User
private final
private final
private final
private final
private final
{
String firstName;
String lastName;
int age;
String phone;
String address;
//
//
//
//
//
required
required
optional
optional
optional
// len 1 konštruktor s jediným argumentom: ConcreteBuilder
private User(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
Príklad Builder-u 2 – riešenie 3: Builder pattern
public static class UserBuilder {
private final String firstName;
private final String lastName;
private int age;
private String phone;
private String address;
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age; return this;
}
public UserBuilder phone(String phone) {
this.phone = phone; return this;
}
public UserBuilder address(String address) {
this.address = address; return this;
}
public User build() {
return new User(this);
}
}
}
Príklad Builder-u 2 – riešenie 3: Builder pattern
User user = new User.UserBuilder("John", "Doe")
.age(30)
.phone("1234567")
.address("Fake address 1234")
.build();
Builder - zhrnutie

Kedy použiť Builder?

Algoritmus tvorby objektu nezávislý od konkrétnych „dielcov“


Treba viacero reprezentácií výsledku



dielce = typicky reprezentácia objektu
do budúcna
Konštruktory
Prečo ho použiť?
izolácia konštrukcie a reprezentácie
 umožňuje zmeniť štruktúru bez prepisovania všetkých ConcreteBuilderov
 nie je nutné presne vedieť, ako sa to poskladá


nasadenie v skupinách vývojárov
Builder – praktické príklady

Kde možno nájsť Builder, kde ho použiť

Častý pri konverziách

Vektorová grafika


GUI



SVG, Flash, konverzia do rastru
rovnaký obsah položiek
iné farby, tvar
Obsah podľa prihláseného užívateľa


jadro rovnaké
ďalšie položky zobrazené/vynechané podľa privilégií
Builder – súvisiace NV

Súvisiace návrhové vzory

Abstract Factory

dá sa chápať ako limitný prípad Builder-u




Builder vytvára objekty postupne, po častiach, vráti až na požiadanie
Produkty Builder-u nemusia implementovať spoločný interface
nasadenie Abstract Factory v prípade, že celý objekt je možné vytvoriť „jediným
volaním“
Composite

je často výsledkom práce Builder-u