Builder (design pattern)
Bc. Martin Petruňa2.10.2012
SAI
Zaradenie
• Builder patrí medzi vytváracie návrhové vzory
• Schéma:
Účastníci• Builder – definuje rozhranie pre konštrukciu častí
vytváraného objektu• ConcreteBuilder – napĺňa kontrakt Buildera a zároveň
zapúzdruje internú reprezentáciu stavaného objektu
• Director – postupne pomocou Buildera stavia objekt Product
• Product – definuje rozhranie budovaného objektu• ConcreteProduct – reprezentuje budovaný objekt
spĺňajúci kontrakt Product
Príklad
PríkladVytvárajúci kód je oddelený od reprezentácie vytváraného objektu, ktorý je vytváraný pomocou jednotného rozhrania.
Implementačné detaily
• Abstraktná trieda Builder definuje prázdne metódy, ConcreteBuilder implementuje tie, ktoré podporuje.
• Novo pridané časti obyčajne stačí „pripojiť“ do internej štruktúry, inokedy ale potrebuje Director Identifikovať predchádzajúce časti.
• Niekedy sa nedefinuje abstraktná trieda pre Produkt (ten kto vyberá ConcreteBuilder vie aký ConcreteProduct dostane).
• Použitie tzv. Fluent interface.
Vzťah k iným návrhovým vzorom
• Factory metóda nám umožní vytvoriť objekt v jedným volaním, AbstractFactory nám umožní vytvárať konzistentné sady objektov, Builder naopak umožňuje postupné vytváranie a skladanie objektu
• Jeho produktom je často Composite
Builder a doporučené postupy OOP
• Zapúzdrenie – žiadne zbytočné setre
• Platný stav objektu – je možné interne kontrolovať stav budovaného objektu a odhaliť prípadné nezrovnalosti
• Absencia úzkych väzieb – v tomto prípade oddelenie konštrukcie (príp. validácie) od reprezentácie
• Čitateľnejší a prehľadnejší kód
• Lepšia testovateľnosť kódu
Builder ktorý používam ja• package upjs.petruna.sai.builder;
• public class FTPRequest {
• private int port;• private String host;• private byte[] payload;• private Timestamp timestamp;
• private FTPRequest(Builder builder) {• this.port = builder.port;• this.host = builder.host;• this.payload = builder.payload;• this.timestamp = builder.timestamp;• }
• @Override• public String toString() {• return "FTPRequest [port=" + port + ", host=" + host + ", payload="• + Arrays.toString(payload) + ", timestamp=" + timestamp + "]";• }
• public static class Builder {…}• }
Builder ktorý používam ja• public static class Builder {
• private int port;• private String host;• private byte[] payload;• private Timestamp timestamp;
• public Builder port(int port){ this.port=port; return this; }
• public Builder host(String host){ this.host=host; return this; }
• public Builder payload(byte[] payload){ this.payload=payload; return this; }
• public Builder timestamp(Timestamp timestamp){ this.timestamp=timestamp; return this; }
• public FTPRequest build(){• return new FTPRequest(this);• }
• }
• package upjs.petruna.sai.builder;
• import java.sql.Timestamp;
• public class Director {
• public static void main(String[] args) {
• FTPRequest request = new FTPRequest.Builder().port(200)• .payload("payload".getBytes()).host("localhost")• .timestamp(new Timestamp(System.currentTimeMillis())).build();
• System.out.println(request);• }• }
Builder ktorý používam ja
FTPRequest [port=200, host=localhost, payload=[112, 97, 121, 108, 111, 97, 100], timestamp=2012-10-01 22:05:36.671]
Príklady z Javy (1)
• StringBuilder
Príklady z Javy (2)
• SaxParser
Príklady z Javy (3)
• MapMaker (Guava)
Ďakujem za pozornosť!