2010-10-21 16 views
5

La description LOD que j'ai vu (par exemple, Wikipedia, C2 Wiki) parle de ne pas appeler des méthodes. Pour citer Wikipedia:La loi de Demeter ne s'applique-t-elle qu'aux méthodes?

La loi de Déméter pour les fonctions exige qu'une méthode M d'un objet O peut n'invoquer les méthodes des types d'objets suivants:
- O se
- paramètres de M
- tout objet créé/instanciés à l'intérieur de M
- O objets de composante directe de
- une variable globale, accessible par O, dans le champ d'application de M

Mais qu'en est-il de l'accès aux propriétés, aux variables ou aux énumérations? Par exemple, étant donné ceci:

class FirstClass { 
    public SecondClass GetRelatedClass() { 
     return new SecondClass(); 
    } 

    public enum InnerEnum { 
     Violated, 
     NotViolated 
    } 
} 

class SecondClass { 
    public int Property {get; set;} 
    public string _variable = "Danny Demeter"; 
} 

Y at-il une ou toutes ces violations LOD? (Ignorer l'accès à une variable directe pour l'instant, si vous le pouvez ..)

void Violate(FirstClass first) { 
    SecondClass second = first.GetRelatedClass(); 
    var x = second.Property; 
    var y = second._variable; 
    var z = FirstClass.InnerEnum.Violated; 
} 

Je ne ferais pas les deux premiers (si les violations « officielles » ou non), pas tout à fait sûr de l'ENUM bien.

Répondre

6

Je ne peux pas répondre à la question enum - Je crois me rappeler que la recommandation standard n'est pas de définir des énumérations à l'intérieur d'une classe. Pour les propriétés, vous pouvez réellement considérer les propriétés comme des raccourcis vers les méthodes (getProperty() et setProperty(value)). Dans ce cas, votre réponse est que les accès aux propriétés sont des violations.

Pour les champs (variables), encore une fois, la pratique courante n'est pas de les exposer, mais plutôt d'utiliser des propriétés, exposer vraiment des champs est une violation de l'encapsulation.

En fin de compte cependant, l'intention de la loi de Demeter est de limiter la connaissance de la mise en œuvre entre les classes. Pour moi, cela signifie que tous vos exemples sont des violations.

+0

En effet. La raison pour laquelle le C2 Wiki ne parle pas de variables d'instance, de champs, de propriétés, d'enums, d'attributs, d'emplacements, etc. est simplement qu'une grande partie des membres de cette communauté sont de vieux Smalltalkers. Les champs, les attributs, les variables d'instance, les slots ou tout ce qu'ils appellent sont de toute façon isomorphes à une paire de méthodes getter/setter, et comme ils sont * isomorphes, il devrait être évident que les changements de champs ne doivent pas changer. les propriétés Demeter en aucune façon.Un champ devrait être simplement traité comme une méthode. –

1

FWIW ...

Violation # 1 (x) ressemble à un modèle d'emplacement de service difficile, donc je suppose que l'exemple n'est pas une violation. La violation n ° 2 (y) ressemble à une odeur de conception de classe, mais ne montre généralement rien au-dessus de ce que démontre la violation # 1.

Je ne pense pas que les énumérations publiques (z), quelle que soit leur portée, compteraient ici contre la LD.

Avez-vous un meilleur exemple concret pour démontrer vos préoccupations? Sans contexte approprié, de simples exemples de code pourraient être acceptables, ou ils pourraient violer les principes de conception.

+0

Peut-être, bien que je pense que ça ressemble moins à ça si vous écrivez tous ensemble (ce qui est du même point de vue de LOD): 'x = first.GetRelatedClass(). Property;'. Ou peut-être l'emplacement du service est parfois une violation de la LDD? –