Les interfaces "qui nous parlent", ou Fluent Interfaces, sont à la mode, et comme toutes les modes IT on peut déjà prévoir qu'il y a aura des excès dont on aura à souffrir. Pour mémoire XML nous avait amené une épidémie de xml-ite aigue, caractérisée essentiellement par des noeuds XML en lieu et place des entités, des repository XML plutôt que des SGDB, et des transformations XSLT pour la logique métier et la création des vues. Sharepoint par exemple, dont la version beta que j'avais testée aux alentours de 2000 reposait largement sur XML/XSLT, commence à peine à s'en remettre.
A trop haute dose, quels peuvent être les effets indésirables des Fluent Interfaces ?
- Des interfaces tortueuses, difficiles à appréhender parce que passées au moule de la Fluent Interface sans que le domaine modélisé s'y prête. A titre d'exemple, une API de construction de documents XML gagne-t-elle à être "fluide" ? Pour ma part j'ai l'impression que le phrasé naturel amène un gain en lisibilité quand les sujets, verbes et compléments ont un sens précis (les Call() et Expect() de Rhino Mocks), moins quand ils sont génériques (les Nodes() et Attributes() d'un XML Builder).
- Un refactoring compromis. Une des bases des
méthodes de développement agiles est le refactoring. Mais quand le code
dupliqué se trouve enfoui au milieu d'une longue phrase fluente, il
devient difficile de le factoriser. En tout cas les outils de
refactoring intégré aux IDE, que ce soit Resharper ou le refactoring
natif de Visual Studio ne peuvent pas appliquer un "extract method" sur
ceci :
XmlOutput xo = new XmlOutput()
Ca devient aussi facile à refactorer qu'un roman aux phrases trop longues.
.XmlDeclaration()
.Node("root").Within()
.Node("user").Within()
.Node("username").InnerText("orca")
.Node("realname").InnerText("Mark S. Rasmussen")
.Node("description").InnerText("I'll handle any escaping (like < & > for example) needs automagically.")
.Node("articles").Within()
.Node("article").Attribute("id", "25").InnerText("Handling DBNulls")
.Node("article").Attribute("id", "26").InnerText("Accessing my privates")
.EndWithin()
.Node("hobbies").Within()
.Node("hobby").InnerText("Fishing")
.Node("hobby").InnerText("Photography")
.Node("hobby").InnerText("Work"); - Une lecture pas si évidente. Paradoxalement, il se pourrait bien que l'objectif initial de lisibilité soit manqué par excès de Fluent Interfaces. D'habitude (si seulement c'était une habitude), la lisibilité d'un logiciel est en grande partie déterminée par la clarté des noms de méthodes et de variables. Ou à défaut, et particulièrement dans le cas de méthodes trop longues candidates au refactoring, par des commentaires. Dans le cas d'une Fluent Interface, l'exemple précédent le montre bien, le risque est que le développeur se repose entièrement sur la "fluency" de l'API, et oublie les commentaires et le découpage en méthodes courtes et "parlantes".
Donc, à consommer avec modération, comme d'hab.
Les commentaires récents