Как я могу уменьшить цикломатическую сложность этого? - PullRequest
16 голосов
/ 02 мая 2011

У меня есть метод, который получает объект и что-то делает в зависимости от того, какой тип объекта он обнаруживает:

void receive(Object object) {
    if (object instanceof ObjectTypeA) {
        doSomethingA();
    }
    else {
        if (object instanceof ObjectTypeB) {
            doSomethingB();
        }
        else {
            if (object instanceof ObjectTypeC) {
                doSomethingC();
            }
            else {
                if (object instanceof ObjectTypeD) {
                    doSomethingD();
                }
                else {
                    // etc...
                }
            }
        }
    }
}

Как можно уменьшить цикломатическую сложность?Я искал вокруг, но не мог найти ничего слишком полезного.

Ответы [ 5 ]

40 голосов
/ 02 мая 2011

Разве вы не можете использовать объектно-ориентированный подход для этого? Создать интерфейс с методом doSomething(), затем создать подклассы, которые реализуют желаемое поведение? Тогда вызов object.doSomething() будет выполнять соответствующее поведение?

28 голосов
/ 02 мая 2011

Цикломатическая сложность - это мера, основанная на графической структуре кода.В частности, он основан на количестве возможных путей через код;см здесь для более подробной информации.Хотя существует связь между CC и тем, что типичный программист считает сложностью кода, это не одно и то же.Например:

  • CC не учитывает семантику кода;например, что делает тот или иной метод, который вызывается, или математические свойства алгоритма.

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

Вы можете сказать, что взаимосвязь между CC и сложностью реального кода подобна взаимосвязи междуIQ и реальный интеллект.

Таким образом, Cyclomatic Complexity следует рассматривать как индикатор того, где находятся сложные части вашего кода ... не как истинный показатель сложности или качества кода.В самом деле, очень сложный код не обязательно должен иметь плохое качество.Зачастую сложность присуща, и попытка избавиться от нее только усугубляет ситуацию.


В этом конкретном примере высокая мера CC не соответствует тому, что могло бы вызвать у типичного программиста какие-либо трудности,Лучший ответ (IMO) - оставить метод в покое.Назовите это ложным срабатыванием.

9 голосов
/ 31 марта 2014
void receive(ObjectTypeA object) {
        doSomethingA();
}

void receive(ObjectTypeB object) {
        doSomethingB();
}

void receive(ObjectTypeC object) {
        doSomethingC();
}

...

// Your final 'else' method
void receive(Object object) {
        doSomethingZ();
}
0 голосов
/ 02 мая 2011

Почему нужно уменьшить сложность? Это достаточно простой шаблон, который любой компетентный разработчик посчитал бы его тривиальной функцией.

Я бы, наверное, так написал

    if (object instanceof ObjectTypeA) 
    {
        doSomethingA();
    }
    else if (object instanceof ObjectTypeB) 
    {
        doSomethingB();
    }
    else if (object instanceof ObjectTypeC) 
    {
        doSomethingC();
    }

Если для удовлетворения некоторой эзотерической потребности необходимо, чтобы "CC должен быть меньше, чем x", то общее правило, согласно которому существуют стандарты для обеспечения поддерживаемого кода, означало бы, что это приемлемо, независимо от того, как высоко поднимается CC.

0 голосов
/ 02 мая 2011

Никогда не было цели "уменьшить цикломатическую сложность", хотя были времена, когда мне платили LOC.

Ваш код "достаточно хорош". Мой взгляд наткнулся на квадратные скобки, поэтому я пожертвовал немного производительностью и сделал следующее (при условии, что типы A, B и т. Д. Не находятся в одной иерархии):

receive(Object object) {
    if (object intanceof ObjectTypeA) doSomethingA();
    if (object instanceof ObjectTypeB) doSomethingB();
    ...

или (если они находятся в одной иерархии):

receive(Object object) {
    if (object intanceof ObjectTypeA) { doSomethingA(); return; }
    if (object instanceof ObjectTypeB) { doSomethingB(); return; }
    ...

Не знаю, уменьшит ли это цикломатическую штуковину, и наплевать на это.

...