Monday, December 17, 2007

Fluent Interface w Egg Framework 2.0

Jedną z najciekawszych funkcjonalności wprowadzonych do Egg Framework 2.0 jest Fluent Interface - API, za pomocą którego można tworzyć czytelny kod aplikacji www w języku Java - wyglądający o dziwo bardzo podobnie do HTMLa.

Fluent Interface to pojęcie wprowadzone przez Martina Fowlera i Erica Evansa. Nazwali oni tym terminem pewien styl tworzenia interfejsów programowych. Więcej można przeczytać na blogu Martina Fowlera.

Oto przykład strony www stworzonej przy użyciu Fluent Interface zaimplementowanym w Egg Framework 2.0:

package org.eggframework2.view.examples.xhtml;

import static org.eggframework2.view.elements.xhtml.ext.FluentInterfaceMethods.*;

import org.eggframework2.view.elements.IElement;
import org.eggframework2.view.elements.xhtml.tags.Html;

public class FluentInterfaceUsageExample extends Html {

    public FluentInterfaceUsageExample() {
        IElement body = //
        body( //
                p("Hello World"), //
                a("Egg Framework Page", href("http://eggframework.org")), //
                form(action("/action.do"), method("post"), //
                        input(type("text"), name("Login")), br(), //
                        input(type("password"), name("Password")), br(), //
                        input(type("submit"), value("Please log me in"))//
                ),//
                table(//
                        tr(//
                                td("Cell 1"), td("Cell 2"), td("Cell 3")//
                        ),//
                        tr(//
                                td("Cell 1"), td("Cell 2"), td("Cell 3")//
                        )//
                ));

        add(body);
    }

    public static void main(String[] args) {
        System.out.println(new FluentInterfaceUsageExample());
    }
}

Jak widać kod Javy jest bardzo czytelny i podobny do wynikowego kodu HTML. Wszystko dzięki wykorzystaniu metod statycznych i statycznych importów. Dzięki zaimportowaniu wszystkich metod z klasy FluentInterfaceMethods możemy ich użyć w kodzie strony tak jakby były one jej częścią. Nie musimy więc poprzedzać nazwy metody nazwą klasy w jakiej jest ona zdefiniowana. To sprawia, że kod jest znacznie bardziej zwięzły.

Klasa FluentInterfaceMethods oprócz metod tworzących instancje elementów (znaczników) HTML posiada metody tworzące atrybuty np. type, name, id. Dzięki temu można w jednej linijce utworzyć element i ustawić jego atrybuty.

Jeśli często używasz układania kodu źródłowego (Pretty Print) to musisz być przygotowany na to, iż większość IDE ułoży kod takiej strony w jednej linijce (albowiem całą zawartość tworzysz poprzez zagnieżdżone wywołania metod). To na pewno nie przyczyni się do zwiększenia czytelności kodu, wręcz odwrotnie - znacznie ją pogorszy. Aby ustrzec się przed taką sytuacją należy użyć komentarzy ("//") w miejscach gdzie IDE ma złamać linię. Dzięki nim nawet po operacji układania kodu kod będzie ładnie się prezentował.

Fluent Interface w Egg Framework to sposób na zwiększenie czytelności tworzonego kodu. Jest to swojego rodzaju nakładka i wykorzystuje istniejące API. Po kilkunastu/kilkudziesięciu minutach pracy powinieneś się przyzwyczaić do tego "dziwnego stylu programowania". Od Ciebie zależy czy będziesz go wykorzystywał czy nie - w wielu wypadkach może okazać się lepszy, jednak mogą zdarzyć się sytuacje gdy utworzenie zawartości strony "w standardowy sposób" będzie prostsze i szybsze.

1 comment:

Anonymous said...

Hejka,

mma wrażenie, że to nie jest dokładnie to o co chodzi Ericowi i Martinowi - wg nich Twój fluent interface powinien bardziej przypominać coś takiego:

Body dody = new Body()
.p("Hello World")
.a("Egg Framework Page", href("http://eggframework.org")
.table()
.tr()
itd.

Tzn. chodzi o ciągłe wywoływanie metod na tym samym obiekcie, przy czym za każdym razem wywoływana metoda zwraca referencję do tego samego obiektu lub obiektu na którym zostanie wywołana kolejna metoda.

aczkolwiek Twój sposób też nie wygląda źle :-)

Pozdr