Я хотел бы знать, является ли хорошей практикой обобщение переменных (используйте одну переменную для хранения всех значений).
Рассмотрим простой пример
Strings querycre,queryins,queryup,querydel;
querycre = 'Create table XYZ ...';
execute querycre ;
queryins = 'Insert into XYZ ...';
execute queryins ;
queryup = 'Update XYZ set ...';
execute queryup;
querydel = 'Delete from XYZ ...';
execute querydel ;
и
Strings query;
query= 'Create table XYZ ... ';
execute query ;
query= 'Insert into XYZ ...';
execute query ;
query= 'Update XYZ set ...';
execute query ;
query= 'Delete from XYZ ...';
execute query ;
В первом случае я использую 4 строки, каждая из которых хранит данные, для выполнения действий, указанных в их суффиксах.
Во втором случае просто 1 переменная для хранения всех видов данных.
Наличие разных переменных облегчает чтение и понимание кем-то еще. Но слишком много из них затрудняет управление.
Кроме того, слишком много переменных влияют на мою производительность?
PS: пожалуйста, не отвечайте на код в примере, просто чтобы передать то, что я имею в виду.
programming-practices
variables
Shirish11
источник
источник
Ответы:
Необходимость задать себе этот вопрос - довольно сильный запах, который вы не соблюдаете за СУХОЙ (не повторяйте себя). Предположим, у вас есть это на гипотетическом языке фигурных скобок:
Преобразуйте это в:
Обратите внимание на то, что отпадает необходимость принятия решения о том, использовать или нет разные переменные, и как теперь можно изменить логику для выполнения запроса и печати результата в одном месте, а не применять одну и ту же модификацию три раза. (Например, вы можете решить, что хотите пропустить результат запроса через систему шаблонов, а не распечатывать его сразу).
источник
runAndPrint
выталкивает один кадр стека при его вызове, а затем возвращает его обратно при выходе из функции. Если вы вызываете его три раза, он выполняет три пары push / pop, но стек никогда не увеличивается более чем на один кадр за раз. Вы должны действительно беспокоиться о глубине стека вызовов с рекурсивными функциями.Обычно это плохая практика.
Повторное использование переменной - это способ создать код, который запутывает чтение.
Те, кто читает код, не ожидают повторного использования переменной таким образом и не будут знать, почему значение, установленное в начале, имеет другое значение в конце функции.
Примеры, которые вы опубликовали, очень просты и на самом деле не страдают от этой проблемы, но они не являются репрезентативными для некоторого кода, который повторно использует переменные (где он установлен в начале, повторно используется где-то посредине - вне поля зрения).
Приведенные вами примеры пригодны для инкапсуляции в функции, где вы будете передавать запрос и выполнять его.
источник
Самодокументированный код легче читать и поддерживать
Следуйте принципу наименьшего искупления и принципу « код как документация» : используйте одну переменную для одной цели, чтобы и ее было легко понять, и код легко прочитать без объяснений.
Правильно структурированный код проще (а значит и дешевле) использовать (пере)
Кроме того , здесь , казалось бы , что
query
всегда используется для подготовки заявления перед его выполнением. Это, вероятно, признак того, что вы хотите реорганизовать часть этого кода в один (или несколько) вспомогательных методов для подготовки и выполнения запроса (в соответствии с принципом DRY ).Таким образом, вы эффективно:
Примеры:
Подумайте об этом, взятом из вашего примера, где измененная версия явно лучше. Конечно, ваш фрагмент был просто примером для целей этого вопроса, но концепция все еще остается верной и масштабной.
Ваш пример 1:
Ваш пример 2:
Пример 3 (Рефакторированный псевдокод):
Преимущество показывает с регулярным повторным использованием.
Персональный анекдот
Я изначально начинал как программист на C, работающий с ограниченным пространством экрана, поэтому повторное использование переменных имело смысл как для скомпилированного кода (тогда), так и для того, чтобы больше кода можно было читать одновременно.
Однако затем, перейдя к языкам более высокого уровня и освоив функциональное программирование, я привык использовать неизменяемые переменные и неизменяемые ссылки везде, где это возможно, для ограничения побочных эффектов.
Что это значит для меня?
Если вы привыкли иметь неизменяемость всех входных данных вашей функции и возвращать новый результат (как истинная математическая функция), вы приобретаете привычку не дублировать магазины.
По сути, это приводит к:
Я не говорю, что здесь нет никакой пользы для изменчивого состояния, я просто указываю, как эта привычка может вырасти на вас и как это влияет на читабельность кода.
источник
С точки зрения дизайна кода
В общем, допустимо повторное использование переменных для хранения разных значений - в конце концов, именно поэтому они называются переменными, потому что значение, хранимое в них, варьируется - при условии, что значение не только одного и того же типа, но также означает одно и то же . Например, конечно, можно использовать
currentQuery
переменную здесь:Естественно, есть цикл, поэтому вы должны повторно использовать переменную, но даже если бы цикла не было, все было бы хорошо. Если значение не означает одно и то же, используйте отдельную переменную.
В частности, код, который вы описываете, выглядит не очень хорошо - он повторяется . Гораздо лучше использовать циклические или вспомогательные вызовы методов (или оба). Лично я очень редко видел рабочий код, который выглядит как ваша 1-я или 2-я версии, но в тех случаях, которые у меня были, я думаю, что 2-я версия (повторное использование переменных) была более распространенной.
С точки зрения производительности
Это зависит от языка, используемого компилятора (ов) и систем (а) времени выполнения, но в целом не должно быть никакой разницы - в частности, компиляторы для машин с регистрами на основе стека (например, популярные x86 / x86-64) будут в любом случае просто используйте любую свободную стековую память или зарегистрируйте их в качестве цели назначения, полностью игнорируя, хотите ли вы ту же самую переменную или нет.
Например,
gcc -O2
генерирует точно такой же двоичный файл, и единственное различие в производительности, о котором я знаю, это размер таблицы символов во время компиляции - совершенно незначительный, если вы не вернетесь во времени к 60-м годам.Компилятор Java сгенерирует байт-код, который нуждается в большем объеме памяти для первой версии, но джиттер JVM все равно удалит его, поэтому, опять же, я подозреваю, что заметного влияния на производительность практически не будет, даже если вам потребуется высоко оптимизированный код.
источник
Я думаю, что повторное использование переменной в большинстве случаев нормально.
Для меня я просто использую переменную запроса большую часть времени. Я почти всегда выполняю запрос сразу после. Когда я не выполняю запрос сразу, я обычно использую другое имя переменной.
источник
Это может увеличить использование стека, если ваш компилятор особенно тупой. Лично я не думаю, что наличие отдельной переменной для каждого запроса добавляет читабельности, вам все равно нужно на самом деле взглянуть на строку запроса, чтобы увидеть, что она делает.
источник
В примере я бы пошел со вторым примером. Как читателю, так и оптимизаторам вполне понятно, что вы делаете. Первый пример немного более правильный, и с более сложным кодом я бы его использовал, но сделаю это так:
(На данный момент, я мог бы рассмотреть решение tdammers .)
Проблема с первым примером заключается в том, что он
querycre
находится в области действия всего блока, который может быть обширным. Это может сбить с толку тех, кто читает код. Это также может сбить с толку оптимизаторы, которые могут оставить ненужную запись в память, поэтомуquerycre
доступны позже, если это необходимо (а это не так). Со всеми фигурными скобками,query
хранится только в реестре, если что.С такими фразами, как «Создать таблицу» и «выполнить», мне не кажется, что здесь будет замечена дополнительная запись в память, так что я бы только ошибся в коде, чтобы запутать читателя. Но это полезно знать, если вы пишете код, где скорость имеет значение.
источник