Fluent interface May 16, 2008 05:44 over 4 years ago
Jeg sider på et projekt og abstrahere nogle skatteberegninger som skal eksekveres i Java. Alt det kryptiske gøjl omkring opsætning og små ligegyldige spidsfindigheder er på plads. Det som holder mig vågen er hvordan jeg skal synliggøre eller promote grænsefladen til disse beregninger for en stribe udviklere.
Jeg kan jo bare lade dem konstruere en stribe objekter og invokere set metoder på objekterne. Det er bare så almindeligt og jeg er dødtræt af hele termologien omkring set og get metoder. Jeg kunne også bruge injection framework eller måske factory metoden.
Flere af beregninger kan udføre alene men nogle andre er afhængige af delberegninger. Hvordan udtrykker jeg det på en simple og hensynsfuld måde? Alle beregninger kræver forskellige input og nogle resultater er input til andre hvilket medfører en bestemt rækkefølge.
Fluent interface kunne være en løsning nu da platformen er Java. Martin Fowler har skrevet flere blogs omkring emnet og de er for det meste fornuftige. Et sandt fluent interface kan være en fornøjelse at bruge. Man behøver ikke huske alle mulige ting om implementeringen og man kan direkte fortolke lingo’en.
Fluent interface har levet i lange tider i dynamiske sprog men gode eksempler er der ikke mange af.
Fluent interface kan tvinge en til at tænke hårdt over selve forretningen og det det er der jo aldrig tid til. Så hellere lave én dårlig løsning. Nå det handler om Lingo.
Beregn beregn new BeregnImpl();
beregn.befordring().
beregn.fribil().
beregn.skat();
Dette er en fin løsning og næsten helt deklarativ programmering, men tager ikke højde for input/output og heller ikke for selve eksekveringen. Fluent interface er måske den bedste metode til at gøre statiske Java til et DSL sprog? Måske ikke helt men næsten, der er stadig de grimme parenteser alle vegne og lidt gentagelse men det kan lade sig gøre at skrive noget kode som næsten lader sig læse som plain sprog.
Når man arbejder med fluent interface drejer det sig om at opbygge en kontekst der kan opereres på. Så fribil er altså en metode på beregn og fribil returnere samme kontekst osv.
At designe et fluent interface er svært, at implementere bibliotekerne bag er endnu sværere.
- Skjul dit arbejde. Hvis du hele tiden føler dig nødsaget til at fortælle hvor langt du er kommet er der noget galt.
- Hold din kontekst for dig selv. Klienten må naturligt kunne fornemme konteksten.
- Eksponer ikke din implementation. Klienten må kun se de valg som findes netop i denne kontekst.
- Brug lang tid på navn konvention. Perspektivet er klientens og DSL’en skal udtrykke forståelige koncepter.
- Lav flere design. Fly ikke med det første.
- Lad aldrig klienter gentage sig selv.
Lad mig prøve at gøre det lidt bedre:
Beregn().befordring().fribil().skat();
Gentagelserne er væk. Desværre kan jeg ikke styre eksekveringen, skal hver metoder invokere en del beregning? Og hvad med input og det faktum at befordring er en del af skatberegningen.
Vil jeg sætte input på Beregn(), så input gælder alle beregninger? Behøver jeg en metode til sidst som eksekvere koden? Hvad er output?
Mens jeg tænker over dette har min kollega lavet denne presentation om fluent interfaces.
Fluent interface for SQL in Java
By Frank Vilhelmsen - 3 tags: dsl java patterns - Add comment