Вопрос

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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


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

void receive(ObjectTypeA object) {
        doSomethingA();
}

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

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

...

// Your final 'else' method
void receive(Object object) {
        doSomethingZ();
}

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

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

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

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

Никогда не было цели «уменьшить цикломатическую сложность», хотя были времена, когда мне платят 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; }
    ...

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top