Самая вопиюще избыточная конструкция кода, которую я часто вижу, включает использование кодовой последовательности
if (condition)
return true;
else
return false;
вместо того, чтобы просто писать
return (condition);
Я видел эту ошибку новичка на всех языках: от Pascal и C до PHP и Java. Какие еще подобные конструкции вы бы отметили при проверке кода?
Я установил бит сообщества вики - спасибо за предложение.
Избыточные конструкции кода? Каждая программа, написанная не на Python. (Я, очевидно, пытаюсь быть смешным, не устраивайте войну, ребята :)





Возвращение без толку в конце:
// stuff
return;
}
Наверное, забыли заполнить возврат.
Использование .tostring в строке
if (condition == true)
{
...
}
вместо
if (condition)
{
...
}
Редактировать:
или даже хуже и оборачиваясь условным тестом:
if (condition == false)
{
...
}
что легко читается как
if (condition) then ...
Я думаю, ты опередил меня на несколько секунд!
Да, должно быть, я был немного быстрее. Я все же поддержал твой из-за юмора :)
if (foo == true)
{
do stuff
}
Я все время говорю разработчику, который это делает, что это должно быть
if ((foo == true) == true)
{
do stuff
}
но он еще не понял намек.
Не давайте им обратных советов, это их просто запутает.
Собственно, это должен быть if (((foo == true) == true) == true) { ... }
void myfunction() {
if (condition) {
// Do some stuff
if (othercond) {
// Do more stuff
}
}
}
вместо
void myfunction() {
if (!condition)
return;
// Do some stuff
if (!othercond)
return;
// Do more stuff
}
Эта конструкция может считаться действительной, если вы относитесь к типу "структурированный код множественных возвратов voilates".
Вам нужен лучший пример. Имея только один уровень вложенности, стиль «раннего возврата» ничем не лучше. В этом примере я предпочитаю первое. Но я знаю, к чему вы клоните, и согласен с этой идеей.
Даже при одном уровне вложенности «раннее возвращение» по-прежнему экономит этот уровень вложенности. Я не понимаю, почему один уровень не лучше, а 2+ уровня. :)
В любом случае отредактировал его, чтобы сделать более вопиющий пример.
Ну, по крайней мере, для меня один уровень условного чтения читается очень естественно, без путаницы.
Однажды у меня был парень, который неоднократно проделывал это:
bool a;
bool b;
...
if (a == true)
b = true;
else
b = false;
б = а? истина: ложь; Это зависит от того, хотели бы вы, чтобы b равнялось 17, если бы это было равным a?
Какие? Почему они просто не использовали b = a?
Помещение оператора exit в качестве первого оператора в функции, чтобы отключить выполнение этой функции, вместо одного из следующих вариантов:
Использование exit в качестве первого утверждения делает его очень трудным для обнаружения, вы можете легко прочитать его.
Однако для отладки удаление функции часто не является вариантом (если она вызывается во многих местах), комментирование тела не работает, если есть вложенные комментарии, а удаление кода означает, что вы должны где-то его сохранить. «Настоящий WTF» (tm) оставляет оператор выхода внутри.
Удаление кода всегда должно быть вариантом, потому что у вас есть система контроля версий. так что у Real WTF нет контроля версий.
хех, я продолжаю читать, кто-то уже упоминал об этом :)
Я столкнулся с этим случаем с кодом, только что вышедшим из системы контроля версий от коллеги. Сделано для головокружения, даже если двое парней смотрят на этот код :)
Объявление отдельно от присваивания на языках, отличных от C:
int foo;
foo = GetFoo();
На самом деле я довольно часто делаю это на C++ с не встроенными модулями, где я могу или не могу добавлять что-то, например, в вектор.
Использование комментариев вместо системы управления версиями:
-Комментарий или переименование функций вместо их удаления и доверия к исходному контролю может вернуть их вам, если это необходимо.
-Добавление комментариев типа «RWF Change» вместо того, чтобы просто вносить изменения и позволять системе управления версиями возложить вину.
Где-то я заметил это, и я считаю, что это вершина логической избыточности:
return (test == 1)? ((test == 0) ? 0 : 1) : ((test == 0) ? 0 : 1);
:-)
Я часто сталкиваюсь со следующим:
function foo() {
if ( something ) {
return;
} else {
do_something();
}
}
Но это не помогает им сказать, что все остальное здесь бесполезно. Это должно быть либо
function foo() {
if ( something ) {
return;
}
do_something();
}
или - в зависимости от продолжительности проверок, которые выполняются перед do_something ():
function foo() {
if ( !something ) {
do_something();
}
}
Я не согласен с этим. Исходный код работает не хуже, а фактическая работа находится в коде на том же уровне вложенности, что я считаю более читаемым. Это действительно сводится к соглашению о командном стиле.
Я считаю, что и первый случай легче читать. Может быть, помогает визуальная симметрия.
По-разному. Если мы говорим о раннем выходе, то лучше вторая форма; Если два случая имеют одинаковую важность, я выберу первую форму.
Использование массива, когда вы хотите установить поведение. Вам нужно проверить все, чтобы убедиться, что его нет в массиве, прежде чем вставлять его, что делает ваш код длиннее и медленнее.
Избыточный код сам по себе не является ошибкой. Но если вы действительно пытаетесь спасти каждого персонажа
return (condition);
тоже является избыточным. Ты можешь написать:
return condition;
Боязнь нуля (это тоже может привести к серьезным проблемам):
if (name != null)
person.Name = name;
Избыточные if (без использования else):
if (!IsPostback)
{
// do something
}
if (IsPostback)
{
// do something else
}
Избыточные проверки (Split никогда не возвращает null):
string[] words = sentence.Split(' ');
if (words != null)
Подробнее о проверках (вторая проверка избыточна, если вы собираетесь зацикливаться)
if (myArray != null && myArray.Length > 0)
foreach (string s in myArray)
И мой любимый вариант для ASP.NET: разбросанные по всему коду DataBind для отрисовки страницы.
Скопируйте избыточность вставки:
if (x > 0)
{
// a lot of code to calculate z
y = x + z;
}
else
{
// a lot of code to calculate z
y = x - z;
}
вместо
if (x > 0)
y = x + CalcZ(x);
else
y = x - CalcZ(x);
или даже лучше (или более запутанный)
y = x + (x > 0 ? 1 : -1) * CalcZ(x)
Размещение элементов в куче, а не в стеке.
{
char buff = malloc(1024);
/* ... */
free(buff);
}
вместо
{
char buff[1024];
/* ... */
}
или же
{
struct foo *x = (struct foo *)malloc(sizeof(struct foo));
x->a = ...;
bar(x);
free(x);
}
вместо
{
struct foo x;
x.a = ...;
bar(&x);
}
Это справедливо только в тех случаях, когда вы точно знаете, какого размера должен быть буфер. У меня также были проблемы с некоторыми дистрибутивами Linux - они просто отказывались предоставить мне буфер размером 4 Кбайт.
Конечно! Я говорю о случаях, когда malloc предназначен для фрагмента памяти фиксированного размера.
Из кошмарных обзоров кода .....
char s[100];
с последующим
memset(s,0,100);
с последующим
s[strlen(s)] = 0;
с множеством противных
if (strcmp(s, "1") == 0)
замусорили про код.
Избыточные вызовы .ToString ():
const int foo = 5;
Console.WriteLine("Number of Items: " + foo.ToString());
Ненужное форматирование строки:
const int foo = 5;
Console.WriteLine("Number of Items: {0}", foo);
Самая распространенная конструкция избыточного кода, которую я вижу, - это код, который никогда не вызывается из любого места программы.
Другой - шаблоны проектирования, которые используются там, где нет смысла их использовать. Например, писать везде «new BobFactory (). CreateBob ()» вместо того, чтобы просто писать «new Bob ()».
Удаление неиспользуемого и ненужного кода может значительно улучшить качество системы и способность команды поддерживать ее. Преимущества часто поражают команды, которые никогда не думали об удалении ненужного кода из своей системы. Однажды я провел обзор кода, сидя с командой и удалив более половины кода в их проекте, не изменяя функциональность их системы. Я думал, что они обидятся, но после этого они часто просили меня дать совет по дизайну и отзывы.
Договорились о дублирующих фабриках. Очевидно, проблема с ними в том, что для их написания требуется слишком много печатать. Итак, я сделал общую версию: gist.github.com/629145
Однако бывают случаи, когда вы разрабатываете код, который нужно заполнить. В этом случае имеет смысл оставить эту конструкцию на месте в качестве строительных лесов. Но если функция считается «завершенной», кодировщик должен был ее оптимизировать для удобства обслуживания.