XXP

octobre 2011

lun. mar. mer. jeu. ven. sam. dim.
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

« Fluent Interfaces (do you speak API ?) | Accueil | Fluent Interfaces (do you speak API ?) »

15 juillet 2008

Fluent Interfaces (do you speak API ?)

Pour l'essentiel, le pattern des interfaces dites "fluentes" consiste à proposer aux développeurs d'écrire du code dont le phrasé ressemble au langage naturel.

Par exemple ce phrasé fluide (exemple tiré du site de Martin Fowler):

	TimeInterval meetingTime = fiveOClock.until(sixOClock);

exprime la même chose que cette version plus classique :

TimeInterval meetingTime = new TimeInterval(fiveOClock, sixOClock);

L'usage du mot 'until' (jusqu'à), courant dans la vraie vie, plutôt rare en programmation, fait la différence. De façon générale, les Fluent Interfaces privilégient l'emploient de méthodes au nom simples et issus du langage courant.

Deux exemples pour fixer les idées.

1. Rhino Mocks, framework open-source de mocks dynamiques développé par l'inévitable Ayende, permet d'écrire ça dans un test unitaire :

	Expect.Call(myObject.Concat("a","b")).Return("ab");

Joli non ?

Si on portait cette Fluent Interface en français, ça donnerait quelque chose comme :

 	JeMAttendsACeQue.CetAppel(monObjet.Concat("a","b")).Retourne("ab");

2. ReadableRex, API qui encapsule la complexité des expressions régulières :

    Regex socialSecurityNumberCheck = new Regex(Pattern.With.AtBeginning

            .Digit.Repeat.Exactly(3)

            .Literal("-").Repeat.Optional

            .Digit.Repeat.Exactly(2)

            .Literal("-").Repeat.Optional

            .Digit.Repeat.Exactly(4)

            .AtEnd);


Implémentation

Dans les grandes lignes, l'implémentation d'une Fluent Interface en elle-même n'a rien de sorcier et consiste souvent à retourner dans les méthodes et accesseurs le contexte en construction. Par exemple :

	public class Configuration
{
string color;
int height;
Configuration Color(string color)
{
this.color = color;
return this;
}
Configuration Height(int height)
{
this.height = height;
return this;
}
}

Dans le détail, développer une Fluent Interface peut s'avérer extrémement complexe. La complexité tient à l'inconsistance fréquente du langage naturel. Qu'il s'agisse de l'anglais ou du français, la grammaire qui le définit regorge de contradictions, d'exceptions et d'effets de contexte.

Défi

Pour vous en convaincre, essayez d'implémenter une API fluente d'expression des nombres littéraux tel celui suggéré par Michael Feathers, et dont voici un aperçu des spécifications :

  Assert.AreEqual(1, (int)FluentNumber.One);
  Assert.AreEqual(23, (int)FluentNumber.Twenty.Three);
  Assert.AreEqual(912, (int)FluentNumber.Nine.Hundred.And.Twelve);
  Assert.AreEqual(777000, (int)FluentNumber.Seven.Hundred.And.Seventy.Seven.Thousand);

Ce que ne dit pas cet essemble de tests à faire réussir, c'est que l'autocompletion doit aussi fonctionner au mieux : taper 'Twenty' doit déclencher les propositions 'One', 'Two', ... 'Thousand" et 'Hundred', mais ni "Twenty" et autres dizaine, ni 'Thirteen' et autres 'teens'. C'est sûrement un excellent exercice pour appréhender les difficultés de développement d'une Fluent Interface.

Serez-vous capable de développer une API robuste vis-à-vis des tournures aberrantes telles que

	FluentNumber.One.Thousand.One.Thousand

Un vrai travail de linguiste...

Liens :

TrackBack

URL TrackBack de cette note:
http://www.typepad.com/services/trackback/6a00d8341c871f53ef00e553ad0d1c8834

Listed below are links to weblogs that reference Fluent Interfaces (do you speak API ?):

Commentaires

Vérifiez votre commentaire

Aperçu de votre commentaire

Ceci est un essai. Votre commentaire n'a pas encore été déposé.

En cours...
Your comment could not be posted. Error type:
Votre commentaire a été enregistré. Poster un autre commentaire

Le code de confirmation que vous avez saisi ne correspond pas. Merci de recommencer.

Pour poster votre commentaire l'étape finale consiste à saisir exactement les lettres et chiffres que vous voyez sur l'image ci-dessous. Ceci permet de lutter contre les spams automatisés.

Difficile à lire? Voir un autre code.

En cours...

Poster un commentaire