2010-10-21 10 views
5

La descripción de LOD que he visto (por ejemplo, Wikipedia, C2 Wiki) habla sobre métodos de no llamada. Para citar a Wikipedia:¿La Ley de Demeter solo se aplica a los métodos?

La Ley de Demeter de funciones requiere que un método M de un objeto O puede solamente invocar los métodos de los siguientes tipos de objetos:
- O sí
- parámetros de M
- cualquier objeto creado/M instanciados dentro
- objetos componente directa de O
- una variable global, accesible por O, en el ámbito de M

¿Pero qué pasa con el acceso a propiedades, variables o enumeraciones? Por ejemplo, dado esto:

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"; 
} 

¿Hay alguna o todas estas infracciones de LOD? (No haga caso de la variable de acceso directo por ahora, si se puede ..)

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

que no haría las primeras dos (si violaciónes 'oficiales' o no), no es tan seguro acerca de la enumeración sin embargo.

Respuesta

6

No puedo responder a la pregunta de enumeración - Me parece recordar que la recomendación estándar no es definir enumeraciones dentro de una clase.

Para las propiedades, realmente puede considerar las propiedades como accesos directos a los métodos (getProperty() y setProperty(value)). En ese caso, su respuesta es que los accesos a propiedades son violaciones.

Para los campos (variables), una vez más, la práctica común es no exponerlos sino utilizar propiedades, realmente exponer campos es una violación de la encapsulación.

En última instancia, la intención de la Ley de Demeter es limitar el conocimiento de la implementación entre las clases. Para mí eso significa que todos tus ejemplos son violaciones.

+0

De hecho. La razón por la cual C2 Wiki no habla de variables de instancia, campos, propiedades, enumeraciones, atributos, ranuras, etc. es simplemente porque una gran parte de los miembros de esa comunidad son antiguos Smalltalkers, de todos modos, todos son privados. Los campos, atributos, variables de instancia, ranuras o lo que se les llame son isomorfos a un par de métodos getter/setter de todos modos, y como * are * isomorphic debe ser obvio que el cambio de un campo a un getter no debería cambiar las propiedades de Demeter de cualquier manera.Un campo debe ser simplemente tratado como un método. –

1

Fwiw ...

Violación # 1 (x) se ve como un patrón de ubicación de servicio en bruto, por lo que podría sospechar que el ejemplo no es una violación.

La infracción # 2 (y) parece un olor de diseño de clase, pero en general no demuestra nada por encima de lo que demuestra la violación # 1.

No creo que las enumeraciones públicas (z), sin importar su alcance, contasen en contra de LOD aquí.

¿Tiene un mejor ejemplo del mundo real para demostrar sus preocupaciones? Sin un contexto adecuado, los ejemplos de código simple podrían estar bien, o podrían violar los principios de diseño.

+0

Quizás, aunque creo que se parece menos a eso si lo escribe todo junto (que desde el punto de vista de LOD es el mismo): 'x = first.GetRelatedClass(). Property;'. ¿O quizás la ubicación del servicio es a veces una violación de LOD? –

Cuestiones relacionadas