То, что вы должны сделать в первую очередь, это попытаться визуализировать цикломатическую сложность с помощью графиков.Проходя через ваш код, мне удалось вычислить 10. Чтобы лучше понять это, взгляните на следующее:
public void MyMethod()
{
Console.WriteLine("Hello ShennyL");
}
Это имеет цикломатическую сложность 1, потому что здесь есть только один возможный путь, и эточтобы отобразить сообщение.
public void AnotherMethod()
{
if (someCondition)
{
Console.WriteLine("Hello Shennly");
}
}
На этот раз мы имеем цикломатическую сложность 2. +1 добавляется к if, while, for, foreach.В этом случае есть два пути.Если someCondition имеет значение true, сообщение будет отображаться (первый возможный путь), а если someCondition - false, сообщение не будет отображаться (второй возможный путь).
Если вы посмотрите на реализацию Dispose в WindowsФормы выглядят так:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
Здесь у вас цикломатическая сложность 3. В случае && оба значения должны быть истинными, чтобы оценить выражение внутри.Это означает, что если оба disposing
истинны и (components != null)
истинны, у вас есть первый путь.Если disposing
ложно, у вас есть второй путь.Третий путь проистекает из того факта, что components
может быть нулевым и, как таковой, он оценивается как ложный.Следовательно, у вас цикломатическая сложность три.
В случае switch
вы получаете +1, а за каждый case
(и default
), который появляется внутри, вы получаете +1.В случае вашего метода у вас есть шесть case
операторов и один default
плюс switch
, что в сумме составляет 8.
Как я сказал в начале, если вы попытаетесь визуализировать свой код вВ терминах графика это можно разбить следующим образом (я добавляю свои комментарии к вашему коду и удаляю ваши комментарии):
public ActionResult Edit(string id, string value)
{
string elementId = id; // First path, cyclomatic complexity is 1
string fieldToEdit = elementId.Substring(0, 4); // Same path, CC still 1
int idToEdit = Convert.ToInt32(elementId.Remove(0, 4)); // Same path, CC still 1
string newValue = value; // Same path, CC still 1
var food = dbEntities.FOODs.Single(i => i.FoodID == idToEdit); // Boolean expression inside your lambda. The result can go either way, so CC is 2.
switch (fieldToEdit) // Switch found, so CC is 3
{
case "name": food.FoodName = newValue; break; // First case - CC is 4
case "amnt": food.FoodAmount = Convert.ToInt32(newValue); break; // Second case - CC is 5
case "unit": food.FoodUnitID = Convert.ToInt32(newValue); break; // Third case - CC is 6
case "sdat": food.StorageDate = Convert.ToDateTime(newValue); break; // Fourth case - CC is 7
case "edat": food.ExpiryDate = Convert.ToDateTime(newValue); break; // Fifth case - CC is 8
case "type": food.FoodTypeID = Convert.ToInt32(newValue); break; // Sixth case - CC is 9
default: throw new Exception("invalid fieldToEdit passed"); // Defaul found - CC is 10
}
dbEntities.SaveChanges(); // This belongs to the first path, so CC is not incremented here.
return Content(newValue);
}
В некоторых моментах я могу ошибаться, но в основном это идеяРасчет цикломатической сложности.Вы также должны понимать, что есть случаи, когда вы не можете уменьшить это (если вам нужно использовать переключатель / case, CC увеличивается).Кроме того, если ваши переменные имеют ужасное наименование (как если бы вы пытались запутать свой код), цикломатическая сложность может возвращать меньшее значение, потому что она не может понять, что ваше именование ужасно.Присвоение имен может усложнить для вас, и если вы не используете комментарии в своем коде, через 6 месяцев вам будет сложно понять, почему цикломатическая сложность равна 3, но вы просто не можете понять, что пишется.