No most már tudunk bármit hozzátenni:
public class WindowTest extends Form {
public static void main(String[] args) {
window("Hello")
.add(label("Hello Geza!"))
.add(akarmi("Hello Geza!"))
.build();
}
}
(Az akarmi() factory method csak a példa kedvéért van ott, igaziból nem csináltam ilyet :))
De ugye, egy ablakban van vagy 30 vezérlő, akkor most 30x fogjuk leírni, hogy add() - az 5 betű!? Ne már, emlékszel... KisHerceg... szóval ezt lehetne okosabban csinálni?
Merthogy, kellene egy olyan 1 paraméteres add() ami 1 vezérlőt - izé, a vezérlő builderét - kapja, és akkor lehet olyat írni, hogy:
.add(label("Hello Geza!"))
Aztán kellene 2, 3, 4, 5, 6, 7 ... 30? 31? ... sok egyéb variáció:
.add(label("Hello Geza!"),label("Hello Sara!"))
.add(label("Hello Geza!"),label("Hello Sara!"),label("Hello Fruzsi!"))
jjaj... Ezt így kényelmesen lehetne használni, de leprogramozni az elég kényelmetlen, mert annyiféle add metódust kell csinálnunk, amennyi darab paraméter variációt akarunk megengedni.
Ezt jobban kellene csinálni. Ez egy okos trükk amit először a C nyelvben használtak, és persze a Java is tudja, és úgy nevezik, hogy varargs - vagy pontosabban variable number of arguments - azaz változó számú paraméter.
Szerencsére ez elég egyszerű, egyszerűen három pontot ... kell tenni a paraméter típusa után, és akkor utána ott 0, 1, 2, 30, bármennyi olyan típusú paraméter állhat. A metódus ezt úgy kapja meg, mintha egy tömb lenne, amin for-each ciklussal végig lehet szaladni, így minden egyes builderen meghívjuk a build() metódust, és beletesszük az elkészült igazi Swing vezérlőt a komponenseink listájába:
public Builder add(ComponentBuilder... builders) {
for (ComponentBuilder builder:builders) {
components.add(builder.build());
}
return this;
}
A paramétereket híváskor vesszővel választjuk el, tehát így már ez működik:
.add(label("Hello Geza!"),label("Hello Sara!"),label("Hello Fruzsi!"))
Persze a paramétereket akár külön sorba is írhatjuk:
public class WindowTest extends Form {
public static void main(String[] args) {
window("Hello")
.add(
label("Hello Geza!"),
label("Hello Sara!"),
label("Hello Fruzsi!"),
akarmi("Hello Geza!") // ez kamus :)
)
.build();
}
}
Hogy miért jó külön sorba írni? Mert így olvashatóbb! Az ember a hosszú soroktól mindig megijed egy kicsit. (Emlékszel, amikor kötelező olvasmányt kellett olvasni, mert muszáj volt? :)) A rövid sorokat meg az ember könnyen és gyorsan elolvassa!
Húú, nagyon jók vagyunk! Egyetlenegy dolog van, ami a KisHerceg szabályt megszegi: a window builderének a végén ott van még egy build() hívás.
Vajon működhet a szokásos trükk, amit a vezérlők builderével csináltunk, hogy a build hívását rábíztuk az add() metódusra?
Sajnos nem, hiszen itt a window buildert senkinek nem adjuk át paraméternek, ezért senki sem tudja helyettünk meghívni a build()-et.
Amit tehetünk, az egy kis szemantikai javítás: azaz tegyük értelmessé a dolgot. Az értelmesebb, hogy "és a végén jelenítsd meg", mint a build() önmagában. Hívjuk tehát show()-nak a build metódust.
Tehát a Window.Builder így néz ki akkor:
public static class Builder {
private String text;
private List<Component> components=new ArrayList<Component>();
public Builder text(String text) {
this.text=text;
return this;
}
public Builder add(ComponentBuilder... builders) {
for (ComponentBuilder builder:builders) {
components.add(builder.build());
}
return this;
}
// inkább show!
public Window show() {
return new Window(this);
}
}
public class WindowTest extends Form {
public static void main(String[] args) {
window("Hello")
.add(
label("Hello Geza!"),
label("Hello Sara!"),
label("Hello Fruzsi!")
)
.show();
}
}