2010-04-19 13 views
6
public class BigPerformance 
{ 
    public decimal Value { get; set; } 
} 

public class Performance 
{ 
    public BigPerformance BigPerf { get; set; } 
} 

public class Category  
{ 
    public Performance Perf { get; set; }  
} 

Si llamo:Cómo modificar el código para que se adhiera a la Ley de Demeter

Category cat = new Category(); 
cat.Perf.BigPerf.Value = 1.0; 

que supongo que esto rompe la Law of Demeter/Principle of Least Knowledge?
Si es así, ¿cómo remedio esto si tengo una gran cantidad de propiedades de clase interna?

Respuesta

0

Esto no infringe la Ley de Demeter, porque está utilizando un contrato público de clases.

+0

Esto es incorrecto; ver la respuesta de Chris S http://stackoverflow.com/questions/2666930/how-to-modify-code-so-that-it-adheres-to-the-law-of-demeter/2667019#2667019 – Spoike

+0

Getter de la propiedad es un método –

3

Si está hablando de la Ley de Demeter como en, "no llame a los vecinos de los vecinos" puede delegarlo a otros métodos que hacen lo que quiere.

Según su ejemplo, supongo que desea restablecer el valor de rendimiento o algo así. Puede modificar el código de ejemplo para que se encadenan inherentemente lugar:

Category cat = new Category(); 

cat.resetPerf(); 

el código sería algo parecido a esto:

public class BigPerformance 
{ 
    //constructors 'n stuff 

    public static decimal DEFAULT; 

    public decimal Value {get; private set;} 

    public void reset() { 
     Value = BigPerformance.DEFAULT; 
    } 
} 

public class Performance 
{ 
    //constructors 'n stuff 

    private BigPerformance BigPerf {get; set}; 

    public reset() { 
     BigPerf.reset(); 
    } 
} 

public class Category 
{ 
    // constructors 'n stuff 

    public Performance Perf {get; private set;} 

    public resetPerformance() { 
     Perf.reset(); 
    } 
} 

De esta manera la clase Category no necesita saber cómo restablecer el valor en caso de que el valor predeterminado sea algo diferente o su tipo se modifique en el futuro.

Personalmente si el riesgo de cambio es bajo, iría por juharr's answer en su lugar.

1
Category cat = new Category(); 
cat.Perf.BigPerf.Value = 1.0; 

es

Category cat = new Category(); 
cat.GetPerf().GetBigPerf().SetValue(1.0); 

Por lo tanto, es romper las reglas si la definición de Wikipedia es correcta:

.. [M] étodo M de un objeto O sólo se puede invocar la métodos de los siguientes tipos de objetos:

  • O sí
  • los parámetros de M
  • ningún objeto creado/instanciados dentro M
  • componente directa de O objetos
  • una variable global, accesible por O, en el ámbito de M

En particular , un objeto debe evitar invocar métodos de un objeto miembro devuelto por otro método

Si le preocupa que los 3 estén estrechamente acoplados, elimine los accesadores públicos y agregue un método en Categoría para establecer el valor. Luego, refactorice Performance y BigPerformance para que sean miembros privados.

1

Si siempre mantener testabillity de sus clases en mente y use IoC, notará que no tiene que preocuparse tanto por LoD.

a ver de esta manera

¿Cómo voy a probar Category? I no quiero que cree automágicamente a Performance que está usando el lento sistema de archivos . Pasemos un IPerformance hasta Category y reemplacemos la implementación real con una instancia ficticia Performance.

¿Cómo voy a probar Performance? No lo quiero automágicamente crear un BigPerformance haciendo una conexión a una base de datos. Pasemos un IBigPerformance hasta Performance y reemplacemos la implementación real con una instancia ficticia BigPerformance.
...
es obvio que observa el patrón

Su código estaría en la línea de

BigPerformance BigPerf = new BigPerformance(); 
BigPerf.Value := 1.0; 
Performance Perf = new Performance(BigPerformance); 
Category cat = new Category(Performance); 

(This would be retrieved from a factory.) 

Parece (y en el shortrun probablemente es) como un montón más trabajo, pero los beneficios se verán recompensados ​​a largo plazo al poder evaluar sus clases en forma aislada.

Eche un vistazo al blog Misco Hevery's para abrir los ojos en este y otros temas.

Cuestiones relacionadas