La Ley de Deméter establece lo siguiente:
- Cada unidad debe tener un conocimiento limitado sobre otras unidades: solo unidades "estrechamente" relacionadas con la unidad actual.
- Cada unidad solo debe hablar con sus amigos; No hables con extraños.
- Solo habla con tus amigos inmediatos.
C # 6.0 introdujo un nuevo operador llamado operador condicional nulo . En mi humilde opinión, facilita la codificación y mejora la legibilidad. Pero también hace que sea más fácil escribir más código acoplado, ya que es más fácil navegar por los campos de clase, ya verificando la nulidad (algo así como var x = A?.B?.C?.D?.E?.F?
).
¿Es correcto afirmar que este nuevo operador va en contra de la Ley de Demeter?
c#
design-patterns
object-oriented-design
Arthur Rizzo
fuente
fuente
A?.B?.C?.D?.E?.F?
lo violaría? LoD no se trata de cuántos puntos y si el método de llamada tiene tal información sobre la estructura que no está en violación de sus puntos, tal llamada sería perfectamente aceptable. Que dicho código podría violar LdD no es suficiente decir que todos los usos de que hacer violan LdD.X.Y.Z.W.U
violación de la "ley". Pero, en mi experiencia con el código, el 90% de las veces es un código simple y feo..?
no viola más LoD que+
o lo-
hace.Respuestas:
No *
* El operador condicional nulo es una herramienta dentro del lenguaje y el marco .NET. Cualquier herramienta tiene la capacidad de ser abusada y utilizada de manera que pueda dañar la capacidad de mantenimiento de una aplicación determinada.
Pero el hecho de que una herramienta puede ser objeto de abuso no necesariamente significa que tiene que ser objeto de abuso, ni que la herramienta viola cualquier principio en particular (s) que pueden poseer.
La Ley de Demeter y otras son pautas sobre cómo debe escribir su código. Está dirigido a humanos, no a las herramientas. Por lo tanto, el hecho de que el lenguaje C # 6.0 tenga una nueva herramienta no necesariamente afecta la forma en que debería escribir y estructurar su código.
Con cualquier nueva herramienta, es necesario evaluarlo como ... si el tipo que termina el mantenimiento de su código será un psicópata violento ... . Tenga en cuenta nuevamente, que esto es una guía para la persona que escribe el código y no sobre las herramientas que se utilizan.
fuente
foo = new FiveDMatrix(); foo.get(0).get(0).get(0).get(0).set(0,1);
estaría bien (y no peor quefoo[0][0][0][0][0] = 1
) ... y muchas otras situaciones en las que eso no viola LoD.Dom file = prase("some.xml"); file.get(tag1).getChild().get(tag2).getChild() ...
: es una cuestión de procesar la estructura de algún código tonto. No es un extraño ... es simplemente tonto. El se.?
vuelve muy útil en tales estructuras.Más o menos.
Si solo está haciendo un acceso (
a?.Foo
), entonces es equivalente a:que la mayoría de la gente estaría de acuerdo no es una violación de la Ley de Demeter. En ese punto, es solo azúcar sintáctico para mejorar la legibilidad.
Algo más que eso, y probablemente violaría la Ley de Demeter, y esta característica tiende a promover ese tipo de uso. Incluso diría que el uso "bueno" anterior solo no es suficiente para garantizar este tipo de cambio en el idioma, por lo que espero que se haya hecho para admitir el uso claramente menos bueno.
Dicho esto, vale la pena recordar que la Ley de Demeter no es una ley per se, sino más bien una guía. Gran cantidad de código lo viola y funciona bien. A veces, la simplicidad del diseño o del código vale más que el riesgo que supone violar la Ley de Demeter.
fuente
a?.Func1(x)?.Func2(y)
El operador nula coalescencia es otra cosa.No. Consideremos tanto al operador por sí solo como al uso fuertemente encadenado que tiene para él.
Por sí solo
.?A
depende de la misma cantidad de conocimiento de la clase que es el valor izquierdo y del tipo devuelto por el método como lo.A != null
hace, a saber. Necesita saber que laA
propiedad existe y devuelve un valor con el que se puede compararnull
.Solo podemos argumentar que esto viola la ley de Demeter si las propiedades escritas lo hacen. Ni siquiera estamos obligados a tener
A
un tipo concreto (su valor podría ser de tipo derivado). El acoplamiento aquí es mínimo.Ahora consideremos
var x = A?.B?.C?.D?.E?.F
.Lo que significa que
A
debe ser de un tipo que podría ser nulo, o podría tener unaB
propiedad, que debe ser de un tipo que podría ser nulo o tener unaC
propiedad, y así sucesivamente hasta que el tipo deE
propiedad sea algo que podría ser nulo o Podría tener unaF
propiedad.En otras palabras, debemos hacerlo con un lenguaje de tipo estático o aplicando una restricción a los tipos que se pueden devolver si el tipo de letra es suelto. C # en la mayoría de los casos usa escritura estática, por lo que no hemos cambiado nada.
Si lo tuviéramos, el siguiente código también violaría la ley:
Que es exactamente lo mismo . Este código que usa el acoplamiento de diferentes elementos necesita "saber" sobre la cadena completa de acoplamiento, pero está usando un código que no viola la Ley de Demeter para hacerlo, con cada unidad que tiene un acoplamiento bien definido con el siguiente.
fuente
var x = A?.B?.C?.D?.E?.F
todos esos if / elses, incluso si al final son iguales.A?.B?.C?.D?.E?.F
porque hay menos cosas que pueden estar mal; o deberíamos estar tratando de llegar aF
través de ese camino, o no deberíamos, mientras que la forma más larga podría tener errores, así como el error de que no es lo correcto.A.B.C.D
. Es mucho más simple tener una sola cosa a tener en cuenta (acceso a la propiedad encadenada) en lugar de dos cosas diferentes que dependen de un detalle bastante irrelevante (verificación nula)Los objetos pueden crearse con el fin de encapsular comportamientos o mantener datos, y los objetos pueden crearse con el fin de compartirlos con código externo o mantenerlos en privado con su creador.
Los objetos que se crean con el fin de encapsular el comportamiento (ya sea compartido o no), o para ser compartido con el código externo (ya sea que encapsulan el comportamiento o los datos) generalmente se debe acceder a través de su interfaz de superficie. Sin embargo, cuando los objetos que contienen datos se crean para uso exclusivo de su creador, las razones normales de la Ley del Demeter para evitar el acceso "profundo" no se aplican. Si parte de una clase que almacena o manipula datos en el objeto se cambia de una manera que requeriría ajustar otro código, será posible garantizar que todo ese código se actualice porque, como se indicó anteriormente, el objeto fue creado para El uso exclusivo de una clase.
Mientras pienso en el?. El operador quizás podría haber sido mejor diseñado, hay suficientes situaciones en las que los objetos hacen uso de estructuras de datos anidados que el operador tiene muchos casos de uso que no violarían los principios expresados por la Ley de Demeter. El hecho de que pueda usarse para violar el LoD no debe tomarse como un argumento en contra del operador, ya que no es peor que el "." operador en ese sentido.
fuente