62 votes

Les interfaces fluides violent-elles la loi de Demeter?

L' article de wikipedia à propos de la Loi de Déméter dit:

La loi dit simplement que "utiliser un seul point".

Cependant un exemple simple d'une interface fluide peut ressembler à ceci:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

Donc cela va ensemble?

90voto

Sebastian Rittau Points 4041

Eh bien, la courte définition de la loi raccourcit trop. Le véritable "droit" (en réalité, des conseils sur la bonne conception d'API) dit en substance: Seuls les objets d'accès que vous avez créé vous-même, ou ont été transmis à vous en tant qu'argument. Ne pas accéder à des objets indirectement à travers d'autres objets. Les méthodes de fluent interfaces reviennent souvent l'objet lui-même, de sorte qu'ils n'enfreignent pas la loi, si vous utilisez à nouveau l'objet. D'autres méthodes permettent de créer des objets pour vous, donc il n'y a pas d'infraction.

À noter également que la "loi" n'est qu'une des meilleures pratiques des conseils pour les "classiques" des Api. Couramment les interfaces sont une approche complètement différente de l'API de dessin et ne peuvent pas être évalués avec la Loi de Déméter.

28voto

Jon Limjap Points 46429

Pas nécessairement. "Utiliser un seul point" est inexacte résumé de la Loi de Déméter.

La Loi de Déméter décourage l'utilisation de plusieurs points lors de chaque point représente le résultat d'un autre objet, par exemple:

  • Premier point est une méthode dite de ObjectA, en retournant un objet de type ObjectB
  • Prochain point est une méthode uniquement disponible en ObjectB, en retournant un objet de type ObjectC
  • Prochain point est une propriété disponible uniquement dans ObjectC
  • à l'infini

Cependant, au moins à mon avis, la Loi de Déméter n'est pas violé si le retour de l'objet de chaque point est toujours le même type que l'original de l'appelant:

var List<SomeObj> list = new List<SomeObj>();
//initialize data here
return list.FindAll( i => i == someValue ).Sort( i1, i2 => i2 > i1).ToArray();

Dans l'exemple ci-dessus, les deux FindAll() et de Tri() retourne le même type d'objet que la liste originale. La Loi de Déméter n'est pas violé: la liste seulement parlé à ses amis proches.

Cela étant dit, pas tous couramment interfaces de violer la Loi de Déméter, juste aussi longtemps qu'ils le retour du même type que leurs appelant.

9voto

Mark Cidade Points 53945

L'esprit de la Loi de Déméter, c'est que, étant donné un objet de référence ou de la classe, vous devriez éviter accédant aux propriétés d'une classe plus d'une sous-propriété ou de la méthode de l'écart depuis qui couplent les deux classes, ce qui peut être involontaire et peut causer des problèmes de maintenabilité.

Couramment les interfaces sont un acceptable exception à la loi, car ils sont censé être au moins quelque peu étroitement associée, comme toutes les propriétés et méthodes sont les conditions d'un mini-langage qui sont composées ensemble à la forme fonctionnelle des phrases.

8voto

Quibblesome Points 14441

Oui, même si vous devez appliquer un peu de pragmatisme à la situation. Je prends toujours la Loi de Déméter comme un guide plutôt qu'une règle.

Certes, vous avez peut bien vouloir éviter ce qui suit:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);

peut-être remplacer par:

CurrentCustomer.Orders[0].EmailManufacturer(text);

Comme de plus en plus de l'utilisation d'un ORM qui se présente généralement à l'ensemble du domaine comme un objet graphique, il pourrait être une idée à définir acceptable "portée" d'un objet particulier. Nous devrions peut-être prendre la loi de déméter à suggérer que vous ne devriez pas la carte graphique entière comme accessible.

6voto

Andrei Rînea Points 7554

1) Il ne viole pas du tout.

Le code est équivalent à

 var a = new ZRLabs.Yael.Pipeline("cat.jpg");
a = a.Rotate(90);
a = a.Watermark("Monkey");
a = a.RoundCorners(100, Color.Bisque);
a = a.Save("test.png");
 

2) Comme le dit le bon vieux Phil Haack: La loi de Demeter n’est pas un exercice de comptage de points

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X