Złożoność cyklomatyczna

Jednym z wcześniejszych postów przedstawiłem aplikację nDepend obliczającą przeróżne metryki kodu. Większość metryk obliczanych przez program jest oczywista (liczba linii kodu, procent komentarzy, liczba klas itp). Na solidny komentarz zasługuje jednak złożoność cyklomatyczna (w skrócie CC).

Aby obliczyć CC, należy najpierw należy narysować graf przepływu informacji dla badanego kodu. Złożoność można obliczać zarówno dla konkretnej metody jak i całego systemu. Rozpatrzmy następujący fragment kodu:

private int Method1()
{
  while (exit_condition == false)
  {
      if (condition1 == true)
      {
          if (condition2 == false)
          {
              //do something
          }
          else
          {
              //do something
          }
      }
      else
      {
          //do something
      }
  }
  return result;
}

Kod zawiera jedną pętle oraz kilka rozgałęzień. Graf przepływu informacji pokazuje w jakiej kolejności poszczególne instrukcję są wykonywane:

image

Na grafie zaznacza się miejsca rozgałęzień. Jeśli kilka operacji jest wykonywanych sekwencyjnie (jedna po drugiej) wystarczy zaznaczyć tylko jeden węzeł. Mając narysowany graf można przejść do obliczenia CC za pomocą:

M = E − N + 2P,

gdzie:

M – złożoność cyklomatyczna,

E – liczba krawędzi grafu,

N – liczba węzłów grafu,

P – liczba grafów spójnych.

Graf spójny to taki graf w którym dla dowolnych dwóch węzłów istnieje ścieżka. Jeśli badamy kompletnie niezależne od siebie  3 metody, wtedy będą występować 3 grafy spójne. Dla pojedynczej metody zawsze P jest równe 1.

W przypadku powyższego grafu CC wynosi więc:

M = 10 – 8 + 2 = 4

CC jest o tyle przydatna, że określa dokładnie dozwolone przedziały wartości:

Przedział

Skutek

1-10

Kod bardzo prosty, nie stwarza ryzyka związanego z dalszymi rozszerzeniami systemu.

11-20

Kod dość złożony jednak wszelkie modyfikacje wciąż możliwe.

21-50

Kod wysoce skomplikowany.

powyżej 50

Ekstremalnie źle napisany kod. Wszelkie modyfikacje oraz poprawy błędów ponoszą ze sobą ogromne koszty.

 

Na koniec wróćmy jeszcze do grafu. Powiedziałem, że liczba operacji sekwencyjnych nie ma znaczenia. Dopiszmy więc kilka węzłów:

image

Wartość wynosi wciąż 4, M=13 – 11 + 2 = 4. Oznacza to, że kod napisany w mało elegancki sposób może mieć “dobrą” wartość CC. Wniosek z tego jest taki, że w celu oceny kodu należy obliczyć różne metryki i podejmować decyzje o refaktoryzacji na podstawie wielu kryteriów a nie tylko CC.

Leave a Reply

Your email address will not be published.