2011-05-16 30 views
20

sto guardando la lcom metrica come mostrato qui,Perché la mancanza di coesione di metodi (lcom) Inserisci getter e setter

http://www.ndepend.com/Metrics.aspx

Così dicono alcune cose,

1) A class is utterly cohesive if all its methods use all its instance fields 
2) Both static and instance methods are counted, it includes also constructors, properties getters/setters, events add/remove methods 

Se guardo una classe come questa,

public class Assessment 
{ 
    public int StartMetres { get; set; } 
    public int EndMetres { get; set; } 
    public decimal? NumericResponse { get; set; } 
    public string FreeResponse { get; set; } 
    public string Responsetype { get; set; } 
    public string ItemResponseDescription { get; set; } 
    public string StartText { get; set; } 
    public decimal? SummaryWeight { get; set; } 
} 

Ottiene un punteggio negativo di 0,94 poiché ciascun getter e setter non accede a "tutti gli altri campi di istanza".

Si calcola in questo modo,

accessAverage - methodCount/1 - methodCount 

(2 - 17)/(1 - 17) = 0.94 (rounded) 

non sto capendo questa metrica, perché dovrebbe includere getter e setter? Un getter e setter accedono sempre a un solo campo di istanza.

+1

Direi che la metrica LCOM dovrebbe considerare le proprietà automatiche come gli stessi campi. – Gabe

+3

La cosa sulle metriche di tipo LCOM è che, quella cosa 'Assessment', non è davvero una classe. È solo una stupida POCO ("stupida" che ha un significato specifico e non dispregiativo), una struttura (o un registro in un linguaggio simile a Pascal). Non ha alcun comportamento (il comportamento è tipicamente rappresentato dalle relazioni tra i metodi). Ergo, è non è una vera ** classe **. Potrebbe provenire da un POV in linguaggio, ma non da un dominio POV (che è quello che ti interessa veramente). Evito di raccogliere le metriche LCOM in POJOS o nelle strutture, o di ignorarne i risultati. LCOM ha ragione - non è una classe. Basta usare le informazioni di conseguenza. –

+1

Forse perché getter e setter stanno effettivamente abbassando la coesione della classe e devono essere evitati nella programmazione orientata agli oggetti: http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil. html – yegor256

risposta

26

Ciò dimostra che ogni metrica del software è difettosa se ciecamente ci si porta al suo estremo.

Conosci una classe "incoesiva" quando ne vedi una. Per esempio:

class HedgeHog_And_AfricanCountry 
{ 

    private HedgeHog _hedgeHog; 
    private Nation _africanNation; 

    public ulong NumberOfQuills { get { return _hedgeHog.NumberOfQuills; } } 
    public int CountOfAntsEatenToday { get { return _hedgeHog.AntsEatenToday.Count(); } } 

    public decimal GrossDomesticProduct { get { return _africanNation.GDP; } } 
    public ulong Population { get { return _africanNation.Population; } } 
} 

Si tratta ovviamente di una classe coeso, perché contiene due pezzi di dati che non hanno bisogno di essere uno con l'altro.

Ma mentre è ovvio per noi che questa classe è incoinente, come si può ottenere un programma software per determinare l'incoe- sione? Come direbbe che la suddetta classe è incoesiva, ma non è così?

class Customer 
{ 
    public string FullName { get; set; } 
    public Address PostalAddress { get; set; } 
} 

La metrica che hanno individuato sicuramente rileva l'incoe- sione, ma genera anche falsi positivi.

E se decideste che questa metrica è importante? È possibile creare una classe "CustomerData" contenente solo campi e una classe "Cliente" che espone i campi dati come proprietà.

// This has no methods or getters, so gets a good cohesion value. 
class CustomerData 
{ 
    public string FullName; 
    public Address PostalAddress; 
} 

// All of the getters and methods are on the same object 
class Customer 
{ 
    private CustomerData _customerData; 
    public string FullName { get { return _customerData.FullName; } } 
    // etc 
} 

Ma se sto giocando a questo gioco, posso applicarlo all'esempio coeso così:

class Hedgehog_And_AfricanCountry_Data 
{ 
    public Hedgehog _hedgehog; 
    public AfricanNation _africanNation; 
} 

class Hedgehog_And_AfricanCountry 
{ 
    private Hedgehog_And_AfricanCountry_Data _hedgehogAndAfricanCountryData; 
    // etc; 
} 

Davvero, penso che sia meglio per capire ciò che la coesione è, e perché si tratta di un obiettivo utile, ma capire anche che uno strumento software non può misurarlo correttamente.

+1

Punti molto interessanti. Grazie. – peter

+0

Pensandoci un po 'di più, però, un getter e setter non accedono mai ad un campo solo in ogni caso? O il valore della metrica dovrebbe essere abbassato su classi dove ci sono un sacco di metodi? – peter

+1

Immagino che cosa sto cercando di dire è non dovremmo rimuovere i getter e setter? Non darebbe risultati più accurati? – peter