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

Se chiamo:Come modificare il codice in modo che aderisce alla Legge di Demetra

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

Presumo che ciò questo rompe il Law of Demeter/Principle of Least Knowledge?
Se sì, come posso rimediare a questo se ho un gran numero di proprietà di classe interna?

risposta

0

Questo non sta infrangendo la legge di Demeter, perché stai usando un contratto pubblico di lezioni.

+0

Questo non è corretto; vedere la risposta di 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 della proprietà è un metodo –

3

Se stai parlando di Law of Demeter come "non chiamare i vicini dei vicini" puoi delegarlo ad altri metodi che fanno ciò che vuoi.

Dal tuo esempio, suppongo che tu voglia reimpostare il valore della prestazione o qualcosa del genere. È possibile modificare il codice di esempio in modo che siano incatenati intrinsecamente invece:

Category cat = new Category(); 

cat.resetPerf(); 

il codice sarebbe qualcosa di simile a questo:

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(); 
    } 
} 

In questo modo la classe Category non ha bisogno di sapere come reimpostare il valore nel caso in cui il valore predefinito sia qualcosa di diverso o il suo tipo sia cambiato in futuro.

Personalmente, se il rischio di modifica è basso, preferisco utilizzare lo juharr's answer.

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

è

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

Quindi si infrange le regole, se la definizione di Wikipedia è corretta:

.. [M] etodo M di un oggetto O può solo invocare la metodi dei seguenti tipi di oggetti :

  • O si
  • parametri di M
  • oggetti creati/istanziati all'interno M
  • componente continua di O oggetti
  • una variabile globale, accessibile da O, nell'ambito di M

In particolare , un oggetto dovrebbe evitare di invocare metodi di un oggetto membro restituito con un altro metodo

Se si è preoccupati che il 3 sia strettamente accoppiato, rimuovere i metodi di accesso pubblici e aggiungere un metodo in Categoria per impostare il valore. Quindi refactor Performance e BigPerformance diventano membri privati.

1

Se si mantiene sempre tenendo in considerazione la testabilità dei tuoi corsi e utilizzando IoC, noterai che non devi preoccuparti di LoD tanto.

Guardate in questo modo

Come faccio a testare Category? I non voglio creare automaticamente a Performance che utilizza il file system lento. Passiamo un IPerformance attraverso Category e sostituire l'effettiva attuazione con un manichino Performance istanza.

Come faccio a testare Performance? Non voglio che sia automagicamente creare una connessione a un database. Passiamo uno Performance e sostituiamo l'effettiva implementazione con un'istanza fittizia BigPerformance.
...
ovviamente nota il modello

Il tuo codice sarebbe in linea di

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.) 

Sembra (e nel shortrun probabilmente è) come un sacco più lavoro ma i benefici si ripagheranno a lungo termine essendo in grado di testare le lezioni in isolamento.

Dai uno sguardo al blog Misco Hevery's per aprire gli occhi su questo e altri argomenti.

Problemi correlati