Почему отсутствие связности методов (LCOM) включает геттеры и сеттеры

Я смотрю на метрику LCOM, как показано здесь,

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

Итак, мы говорим несколько вещей,

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

Если я посмотрю на такой класс,

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

Он получает плохую оценку 0,94, потому что каждый геттер и сеттер не имеют доступа ко «всем другим полям экземпляра».

Рассчитывается так,

accessAverage - methodCount / 1 - methodCount

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

Я не понимаю эту метрику, почему она должна включать геттеры и сеттеры? Геттер и сеттер всегда будут иметь доступ только к одному полю экземпляра.


person peter    schedule 16.05.2011    source источник
comment
Я бы сказал, что метрика LCOM должна рассматривать автоматические свойства так же, как поля.   -  person Gabe    schedule 16.05.2011
comment
Дело в метриках, подобных LCOM, в том, что эта штука Assessment на самом деле не является классом. Это просто тупой POCO (dumb имеющий конкретное, не уничижительное значение), структура (или запись на языке Паскаля). У него нет поведения (поведение, обычно представленное отношениями состояния между методами). Следовательно, это не настоящий класс. Это может быть точка зрения языка, но не точка зрения домена (это то, что вас действительно волнует). Я либо избегаю сбора метрик LCOM в POJOS или структурах, либо игнорирую результаты для них. LCOM прав - это не класс. Просто используйте эту информацию соответствующим образом.   -  person luis.espinal    schedule 13.07.2012


Ответы (1)


Это демонстрирует, что каждая метрика программного обеспечения ошибочна, если вы слепо доводите ее до крайности.

Вы узнаете «бессвязный» класс, когда увидите его. Например:

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

Очевидно, что это несвязный класс, потому что он содержит две части данных, которые не обязательно должны быть связаны друг с другом.

Но хотя для нас очевидно, что этот класс несвязный, как вы можете заставить программу определять несвязность? Как бы он сказал, что вышеприведенный класс несвязный, а этот нет?

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

Метрика, которую они придумали, безусловно, выявляет несвязность, но также дает ложные срабатывания.

Что, если вы решили, что этот показатель важен? Вы можете создать класс «CustomerData», содержащий только поля, и класс «Customer», который предоставляет поля данных как свойства.

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

Но если я играю в эту игру, я могу применить ее и к несвязному примеру:

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

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

На самом деле, я думаю, что лучше понять, что такое сплоченность и почему это достойная цель, но также понимать, что программный инструмент не может ее правильно измерить.

person Andrew Shepherd    schedule 16.05.2011
comment
Просто подумав об этом немного подробнее, разве геттер и сеттер все равно не будут получать доступ только к одному полю? Или значение метрики предполагается валить на классы, где есть куча методов? - person peter; 16.05.2011
comment
Я думаю, что я пытаюсь сказать, разве мы не должны удалить геттеры и сеттеры? Разве это не даст более точных результатов? - person peter; 16.05.2011
comment
Затем это перетекает в дебаты о свойствах и полях. См. csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx. - person Andrew Shepherd; 16.05.2011
comment
Вещи, в которых нет ничего, кроме сеттеров и геттеров (Java POJO, C# POCO, структуры C/C++), они не являются классами в истинном смысле. У них нет интересующего поведения, поэтому очевидно, что метрики LCOM-* будут давать бессмысленное число (мусор на входе, мусор на выходе). Еще хуже, если инструмент LCOM-* не может определить CustomerData как патологический случай (нет методов -> нет сообщений; нет сообщения -> нет поведения, нет поведения -> не объект.) Так что это не недостаток LCOM-*, а а) недостаток инструмента, принимающего метрику, и б) принятие результатов LCOM как есть без дальнейшего анализа . Метрики — это ориентиры, а не священное евангелие. - person luis.espinal; 13.07.2012
comment
Мы принимаем к сведению обнаружение POCO при расчете метрики LCOM. - person Patrick from NDepend team; 13.06.2017