2010-10-21 17 views
5

La descrizione LOD che ho visto (ad esempio, Wikipedia, C2 Wiki) parla di non chiamare metodi. Per citare Wikipedia:La legge di Demeter si applica solo ai metodi?

La Legge di Demetra per le funzioni richiede che un metodo M di un oggetto O può solo richiamare i metodi dei seguenti tipi di oggetti:
- O si
- parametri
di M - eventuali oggetti creati/istanziati all'interno M
- objects componente continua di O
- una variabile globale, accessibile da O, nell'ambito di M

Ma per quanto riguarda l'accesso a proprietà, variabili o enumerazioni? Ad esempio, dato questo:

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

Sono alcune/tutte queste violazioni di LOD? (Ignorare l'accesso variabili diretta, per ora, se è possibile ..)

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

che non farei i primi due (se le violazioni 'ufficiali' o meno), non così sicuro circa l'enum però.

risposta

6

Non riesco a rispondere alla domanda enum - Mi sembra di ricordare che la raccomandazione standard non è quella di definire le enumerazioni all'interno di una classe.

Per le proprietà, è possibile considerare le proprietà come scorciatoie per i metodi (getProperty() e setProperty(value)). In tal caso, la tua risposta è che gli accessi alle proprietà sono violazioni.

Per i campi (variabili), ancora una volta, la pratica comune non è quella di esporli ma piuttosto di usare le proprietà, in realtà l'esposizione dei campi è una violazione dell'incapsulamento.

In definitiva, tuttavia, l'intento della legge di Demeter è limitare la conoscenza dell'implementazione tra le classi. Per me questo significa che tutti i tuoi esempi sono violazioni.

+0

Infatti. Il motivo per cui il Wiki di C2 non parla di variabili di istanza, campi, proprietà, enumerazioni, attributi, slot, ecc. È semplicemente perché una gran parte dei membri di quella comunità sono vecchi Smalltalker in cui comunque tutti sono privati. Campi, attributi, variabili di istanza, slot o qualunque cosa essi siano chiamati sono comunque isomorfi a una coppia di metodi getter/setter, e poiché essi * sono * isomorfi dovrebbe essere ovvio che il passaggio da un campo a un getter non dovrebbe cambiare le proprietà Demeter in alcun modo.Un campo dovrebbe essere semplicemente trattato come un metodo. –

1

FWIW ...

Violazione # 1 (x) si presenta come un modello di posizione di servizio difficili, quindi ho il sospetto che l'esempio non è una violazione.

La violazione n. 2 (y) si presenta come un odore di design di classe, ma generalmente non dimostra nulla al di sopra di ciò che la violazione n. 1 dimostra.

Non penso che le enumerazioni pubbliche (z), per quanto siano conteggiate, contassero il LOD qui.

Avete un esempio migliore del mondo reale per dimostrare le vostre preoccupazioni? Senza un contesto appropriato, esempi di codice semplici potrebbero essere ok o potrebbero violare i principi di progettazione.

+0

Forse, anche se penso che sembra meno simile se si scrive tutto insieme (che dal punto di vista di LOD è lo stesso): 'x = first.GetRelatedClass(). Proprietà;'. O forse la posizione del servizio a volte è una violazione LOD? –

Problemi correlati