web-dev-qa-db-fra.com

Quelle est la différence entre une interface fluide et le modèle Builder?

Je suis très nouveau dans la conception de modèles et j'ai des problèmes avec la différence entre interfaces fluides et le modèle Builder.

Je comprends le concept des interfaces fluides. Mais le modèle de constructeur est un peu déroutant. Je ne peux pas comprendre l'utilisation d'un directeur dans le modèle Builder.

Puis-je utiliser le modèle Builder et l'interface Fluent ensemble? Si oui, comment dois-je le faire avec un directeur et un constructeur de béton?

Ma question n'est pas pas sur les avantages du modèle de générateur. Mais le but de cette question est de connaître la relation entre le modèle de générateur et l'interface fluide.


Modifier avec le diagramme de séquence UML pour Builder à partir de GoF:

Sequence diagram with director

46
Sagar

L'idée derrière une interface Fluent est que l'on peut appliquer plusieurs propriétés à un objet en les connectant avec des points, sans avoir à spécifier de nouveau l'objet à chaque fois. L'idée derrière le modèle de générateur est que les objets mutables non partagés sont souvent plus faciles à travailler que ceux immuables non partagés, mais il est beaucoup plus facile de raisonner sur les objets immuables partagés que sur les objets mutables partagés. Ainsi, le code peut utiliser un objet mutable facile à travailler pour produire un "modèle" d'une instance souhaitée, puis l'utiliser pour créer un objet immuable facile à partager qui contient les mêmes données.

Les deux idées peuvent bien fonctionner ensemble, mais sont quelque peu orthogonales.

Notez qu'il existe au moins trois façons dont une interface fluide peut fonctionner:

  • En demandant à chaque membre d'une instance de renvoyer une nouvelle instance avec la modification appropriée appliquée.
  • En demandant à chaque membre de muter l'instance sur laquelle il est invoqué et de le renvoyer.
  • En demandant à chaque membre de renvoyer une instance d'un objet patch léger qui contient un lien vers la chose en cours de modification ou vers le patch précédent.

Le dernier style nécessite que certaines mesures soient prises pour appliquer tous les correctifs, mais si l'objet en cours de modification est volumineux et que de nombreuses modifications sont nécessaires, il peut minimiser la quantité de copie requise.

40
supercat

Fluent Interfaces sont des façades sémantiques . Vous les placez au-dessus du code existant pour réduire le bruit syntaxique et pour exprimer plus clairement ce que fait le code dans un langage omniprésent. C'est un modèle utilisé lors de la création d'un langage spécifique au domaine interne. Il s'agit de lisibilité.

Un réalisateur/constructeur orchestre la construction de quelque chose. Autrement dit, si vous construisez une machine de cuisson de pizza, le directeur s'assurera que les étapes de la commande à la pizza sont exécutées dans le bon ordre avec les bonnes données par le bon constructeur. Il s'agit de validation et de délégation.

Vous pouvez certainement mettre une interface Fluent au-dessus d'un modèle Director/Builder pour la faire lire plus - bien - couramment et pour mettre l'accent sur les concepts de domaine (par rapport au processus technique de construction et de délégation). Ce serait probablement un Expression Builder alors.

Je voudrais souligner que les interfaces fluides ne sont pas seulement chaînage de méthodes . C'est une idée fausse commune. Le chaînage de méthodes est une approche pour implémenter une interface fluide mais ce n'est pas la même chose, car elle n'a pas les qualités sémantiques, par exemple ce n'est pas une interface fluide:

SomeObject.setFoo(1).setBar(2).setBaz(3);

Ce qui précède n'exprime rien à propos de SomeObject. Ce n'est pas une façade au-dessus d'un modèle sémantique. C'est juste quelques méthodes enchaînées. Un exemple d'interface fluide serait un générateur de requêtes SQL, par exemple.

SQLBuilder.select('foo').from('bar').where('foo = ?', 42).prepare();

Sous le capot de cette API se trouve le code pour créer une instruction SQL. Il peut inclure plusieurs objets et les appels affichés peuvent très bien créer un objet Select, appeler un setter dessus, créer un objet Condition et l'appliquer à l'objet Select et enfin retourner un objet Statement. Mais tout cela nous est caché. Cela met également en évidence un autre aspect des interfaces fluides: elles pourraient violer SOLID et Law of Demeter . Mais comme il s'agit d'une façade au-dessus du code qui, espérons-le, suit ces principes de conception, cela n'a pas beaucoup d'importance, car vous localisez les violations sur l'interface Fluent.

129
Gordon