Pregunta

El artículo de wikipedia acerca de Ley de Deméter dice:

La ley se puede expresar simplemente como "use solo un punto".

Sin embargo un ejemplo sencillo de un interfaz fluida puede verse así:

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

Entonces, ¿esto va de la mano?

¿Fue útil?

Solución

Bueno, la breve definición de la ley la acorta demasiado.La verdadera "ley" (en realidad, un consejo sobre un buen diseño de API) básicamente dice:Acceda únicamente a los objetos que usted mismo creó o que se le pasaron como argumento.No acceda a objetos indirectamente a través de otros objetos.Los métodos de interfaces fluidas a menudo devuelven el objeto en sí, por lo que no violan la ley si usas el objeto nuevamente.Otros métodos crean objetos por usted, por lo que tampoco hay infracción.

Tenga en cuenta también que la "ley" es sólo un consejo de mejores prácticas para las API "clásicas".Las interfaces fluidas son un enfoque completamente diferente al diseño de API y no pueden evaluarse con la Ley de Demeter.

Otros consejos

No necesariamente."Utilice sólo un punto" es un resumen inexacto de la Ley de Demeter.

La Ley de Demeter desaconseja el uso de múltiples puntos cuando cada punto representa el resultado de un objeto diferente, por ejemplo:

  • El primer punto es un método llamado desde ObjetoA, que devuelve un objeto de tipo ObjetoB
  • El siguiente punto es un método que solo está disponible en ObjectB y que devuelve un objeto de tipo ObjectC.
  • El siguiente punto es una propiedad disponible sólo en ObjectC
  • indefinidamente

Sin embargo, al menos en mi opinión, la Ley de Demeter no se viola si el objeto de retorno de cada punto sigue siendo del mismo tipo que el llamador original:

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

En el ejemplo anterior, tanto FindAll() como Sort() devuelven el mismo tipo de objeto que la lista original.No se viola la Ley de Demeter:la lista sólo hablaba con sus amigos inmediatos.

Habiendo dicho eso no todo Las interfaces fluidas violan la Ley de Demeter, siempre y cuando devuelvan el mismo tipo que la persona que llama.

Sí, aunque hay que aplicar algo de pragmatismo a la situación.Siempre tomo la Ley de Demeter como una guía y no como una regla.

Ciertamente es posible que desees evitar lo siguiente:

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

tal vez reemplazar con:

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

Como cada vez más de nosotros utilizamos ORM, que generalmente presenta todo el dominio como un gráfico de objetos, podría ser una idea definir un "alcance" aceptable para un objeto en particular.Quizás deberíamos tomar la ley de Demeter para sugerir que no se debe mapear todo el gráfico como accesible.

El espíritu de la Ley de Demeter es que, dada una referencia de objeto o clase, se debe evitar acceder a las propiedades de una clase que esté a más de una subpropiedad o método de distancia, ya que eso acoplará estrechamente las dos clases, lo que podría no ser intencionado y puede causar problemas de mantenibilidad.

Las interfaces fluidas son una excepción aceptable a la ley ya que son quiso decir estar al menos algo estrechamente acoplados, ya que todas las propiedades y métodos son términos de un minilenguaje que se componen para formar oraciones funcionales.

1) No lo viola en absoluto.

El código es equivalente a

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) Como dice el buen Phil Haack: La ley de Demeter no es un ejercicio de contar puntos

No hay ningún problema con tu ejemplo.Después de todo, estás rotando, haciendo marcas de agua, etc.Siempre la misma imagen.Creo que estás hablando con un objeto Pipeline todo el tiempo, por lo que mientras tu código solo dependa de la clase de Pipeline, no estás violando LoD.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top