Question

Je suis après quelques bons conseils pour des interfaces fluides en C #. J'apprends cela moi-même, mais je souhaite entendre ce que les autres pensent en dehors des articles que je lis. En particulier je suis après:

  1. quand parle-t-on trop?
  2. existe-t-il des profils fluides?
  3. ce qui est en C # qui rend les interfaces fluides plus fluides (par exemple, les méthodes d'extension)
  4. l'interface complexe est-elle toujours fluide?
  5. refactoring pour arriver à une interface fluide ou refactoring d’une interface existante
  6. avez-vous de bons exemples avec lesquels vous avez travaillé ou que vous pourriez recommander?

Si vous pouviez publier un conseil, une pensée ou quoi que ce soit par message. Je veux aussi voir comment ils obtiendront un vote.

Merci d'avance.

Était-ce utile?

La solution

Sur votre 4ème point;

Oui, je pense qu'une interface complexe et fluide peut encore être fluide.

Je pense que les interfaces fluides sont un peu un compromis. (Bien que ce soit un bon choix!) Il existe de nombreuses recherches sur l’utilisation du langage naturel pour la programmation et le langage naturel n’est généralement pas assez précis pour exprimer des programmes.

Les interfaces Fluent sont construites de manière à écrire comme un langage de programmation. Seul un petit sous-ensemble de ce que vous pouvez exprimer dans un langage naturel est autorisé, mais elles se lisent comme un langage naturel.

Si vous regardez les rhinocéros par exemple, la partie écriture est compliquée comparée à une bibliothèque normale. J'ai pris plus de temps à apprendre principalement à cause de l'interface fluide, mais cela rend le code beaucoup plus facile à lire. Parce que les programmes sont généralement écrits une fois et lus beaucoup plus d’une fois, c’est un bon compromis.

Donc, pour nuancer un peu mon propos. Une interface fluide, complexe à écrire mais facile à lire, peut toujours l'être.

Autres conseils

Le plus gros défi que j'ai rencontré en tant que consommateur d'interfaces fluides est que la plupart d'entre elles ne sont pas vraiment des interfaces fluides, mais plutôt des exemples de ce que j'ai tendance à appeler des "interfaces lisibles".

Une interface fluide implique que son objectif principal est de faciliter la prise de parole, tandis qu'une interface lisible implique que son objectif principal est d'être facile à lire. La plupart des interfaces fluides ont tendance à être ridiculement difficiles à coder, mais sont incroyablement faciles à lire plus tard.

Assert().That().This(actual).Is().Equal().To(expected).
    Except().If(x => x.GreaterThan(10));

... est beaucoup plus facile à lire plus tard que de composer du code!

Vous utiliserez l'héritage avec des interfaces fluides car l'utilisation de méthodes polymorphes rompra vos chaînes d'appels et vous ne voudrez certainement pas faire en sorte que vos interfaces ne soient pas fluides en utilisant des conversions et des phrases moche qui ne sont pas nécessaires. J'ai écrit un article sur un modèle qui vous fournit une solution de contournement à l'aide de générateurs génériques et de méthodes d'extension génériques avec des contraintes génériques: http://liviutrifoi.wordpress.com / 2009/02/16 / fluent-interfaces-contraintes-à-la compilation /

Moq masque des méthodes non répétées telles que equals, ToString et ainsi de suite pour rendre leur interface fluide encore plus simple à utiliser.

Masquer un objet système est un article expliquant l'intérêt de le faire.

Et sur votre deuxième et troisième question;

J'ai remarqué trois profils fluides

Le premier utilise l'instruction using (C # 2.0) pour exécuter du code dans un certain contexte, par exemple:

using(var transaction = new Transaction())
{
  // ..
  // ..
}

Ceci utilise le constructeur et l'élimination de Transaction pour configurer une transaction, puis exécute le code dans ce contexte.

La seconde fait presque la même chose, mais avec lambda, cela est beaucoup utilisé dans Rhino Mocks par exemple.

(new Transaction()).Run( () => mycode(); );

La meilleure interface connue consiste à utiliser les types de retour pour chaîner les appels de méthode. Généralement, les méthodes renvoient ceci afin que vous puissiez enchaîner les appels sur le même objet. Mais vous pouvez également renvoyer différents objets pour modifier le contexte en fonction de la méthode appelée. Si vous avez un objet qui ne peut être exécuté que dans une transaction (par exemple, vous ne pouvez pas penser à un exemple différent), vous pouvez lui donner une méthode StartTransaction qui renvoie une transaction initialisée dans laquelle vous pouvez exécuter call run et stoptransaction, en pseudocode:

class Runner
{
  Transaction StartTransaction()
  {
    return new Transaction(this);
  }
}

class Transaction
{
  Transaction Run()
  Transaction StopTransaction()
}

où l'appel ressemble

var runner = new Runner();
runner
  .StartTransaction()
  .Run()
  .StopTransaction();

Bien sûr, vous devez ajouter toutes sortes de méthodes de gestion des erreurs, etc.

Moi aussi, je suis en train de sauter pour apprendre à écrire une interface fluide pour une petite application au travail. J'ai posé des questions et fait des recherches et découvert qu'une bonne approche pour écrire une interface fluide consiste à utiliser le "motif Builder", en savoir plus à ce sujet ici .

En gros, voici comment j'ai créé le mien:

public class Coffee
{
    private bool _cream;
    private int _ounces;

    public Coffee Make { get new Coffee(); }

    public Coffee WithCream()
    {
        _cream = true;
        return this;
    }

    public Coffee WithOuncesToServe(int ounces)
    {
        _ounces = ounces;
        return this;
    }
}

Voici un message croisé sur une question similaire que j'ai pour la mise en oeuvre d'une fermeture dans une interface fluide.

Une chose est que vous devez tenir compte de la morphologie de la syntaxe anglaise et vous assurer que vous n'avez pas introduit de couplage séquentiel non documenté en dessous.

// Snarky employees get a raise.
employees.WhereSnarky().GiveRaise();

vs.

// Depending on implementation, everyone may get a raise.
employees.GiveRaise().WhereSnarky();

Il y a quelque temps, j'avais les mêmes doutes que vous avez maintenant. J'ai fait des recherches et maintenant j'écris des articles pour vous aider dans ces domaines.

Vérifiez-le sur mon blog:

Principes directeurs pour la conception d'interface fluide en C # partie 1

Et dans les articles suivants, je couvrirai chacun des points que vous avez mentionnés.

Cordialement André Vianna

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top