21 Aralık 2020 Pazartesi

Cognitive Complexity

Cognitive Complexity Nedir?
Sonar McCabe "Cyclomatic Complexity" dışında Cognitive Complexity diye bir metrik sunuyor. Açıklaması şöyle.
"Cognitive Complexity breaks from the practice of using mathematical models to assess software maintainability. It starts from the precedents set by Cyclomatic Complexity, but uses human judgment to assess how structures should be counted and to decide what should be added to the model as a whole. As a result, it yields method complexity scores which strike programmers as fairer relative assessments of maintainability than have been available with previous models."
Null Check - Increased Complexity
Null check yerine Optional kullanılabilir.

Switch/Case- Increased Complexity
Switch/Case Cognitive Complexity değerini azaltıyor

Sequences of Logical Operator — Reduced Complexity
Eğer bir if içinde sürekli aynı logical operator kullanılıyorsa (örneğin sadece &&) bu Cognitive Complexity değerini artırmaz. Ancak bir tane && bir tane de || kullanılıyorsa bu Cognitive Complexity değerini artırır

Nested Flow Breaks Structures - Increased Complexity
Açıklaması şöyle. İç içe geçmiş if/try gibi bloklar kodun okunurluğunu azaltır
Nested code is much difficult to read than the same code as a liner series. A mix of different code structures like try, for, while, if together increase complexity significantly. This why Cognitive Complexity for nested structures adds a point. 
Örnek
Normalde 15 olması gerekir. Açıklaması şöyle.
SonarQube tells me that the Cognitive Complexity is too high: 21, and the current (default, out of the box) metric limit is 15.
21 olan kod şöyle.
public PdfEncryptedPayloadDocument getEncryptedPayloadDocument2() {
  if (getReader() != null && getReader().isEncrypted()) {
    return null;
  }
  PdfCollection collection = getCatalog().getCollection();
  if (collection != null && collection.isViewHidden()) {
    ...
    if (fileSpecObject != null && fileSpecObject.isDictionary()) {
      try {
        ...
        if (fileSpec != null) {
          ...
          PdfStream stream = embeddedDictionary.getAsStream(PdfName.UF);
          if (stream == null) {
            ...
          }
          if (stream != null) {
            return new ...
          }
        }
      } catch (PdfException e) {
        ...
      }
    }
  }
  return null;
}
Bu kod şu hale gelince metric 7'ye düşüyor.
public PdfEncryptedPayloadDocument getEncryptedPayloadDocument2() {
  if (readerIsEncrypted(getReader())) {
    return null;
  }
  PdfCollection collection = getCatalog().getCollection();
  if (collectionIsNotViewHidden(collection)) {
    return null;
  }
  ...
  PdfObject fileSpecObject = embeddedFiles.getNames().get(documentNameUnicode);
  if (fileSpecObjectIsNoDictionary(fileSpecObject)) {
    return null;
  }
  try {
    PdfFileSpec fileSpec = ...;
    if (fileSpec != null) {
      PdfStream stream = ...
      if (stream != null) {
        return new ...
      }
    }
  } catch (PdfException e) {
    ...
  }
  return null;
}
Örnek
Şu kodun Cognitive Complexity değeri 21.
for (String item1 : itemList1){
  for (String item2 : itemList2){
    for (String item3 : itemList3){
      for (String item4 : itemList4){
        for (String item5 : itemList5){
          for (String item6 : itemList6){
            methodToRun(item1, item2, item3, item4, item5, item6);
          }
        }
      }
    }
  }
}

Hiç yorum yok:

Yorum Gönder