Не слишком ли много такого стиля программирования?

#java #coding-style

#java — язык #стиль кодирования #java

Вопрос:

Я знаю, что жестко кодировать что-либо плохо. Обычно мы создаем большую часть переменной среды с помощью файла конфигурации. Например, свойство базы данных, конфигурация проекта, log4j, ввод, вывод.

Но сегодня я видел, как кто-то писал подобный код:

 public void updateExistedRecord(SgsnMapping sgsnMapping) throws Exception {
        PreparedStatement ps = null;

        try {
            String updateSql = "";
            updateSql  = "UPDATE "   schema   "."   tableSgsnMapping   " SET ";
            //other where clause

            ps = dbConn.prepareStatement(updateSql);

            ps.executeUpdate();
        } catch (Exception ex) {
            logger.error("Error when update an existing record on "   tableSgsnMapping   " table.n"   ex.getMessage(), ex);
            throw ex;
        } finally {
            SqlHelper.close(ps);
        }
    }
  

Основное внимание уделяется таблице — tableSgsnMapping, она написана в другом месте таким образом:

 private String tableSgsnMapping = ConstantManager.TABLE_SGSN_MAPPING;
  

В свою очередь, TABLE_SGSN_MAPPING определяется в другом месте:

 public final static String TABLE_SGSN_MAPPING = "OBDUA_SGSN_MAPPING";
  

Не слишком ли это много? Таблица не изменит своего названия, и она всегда будет там. Почему бы просто не закодировать это жестко в программе? Почему?

Комментарии:

1. таблицы не изменили бы свое имя, но в коде могло бы быть несколько ссылок на имя таблицы, т. е. константа могла бы использоваться более чем в одном месте. И вам действительно не нужна частная строка tableSgsnMapping = ConstantManager. TABLE_SGSN_MAPPING и ConstantManager. TABLE_SGSN_MAPPING можно использовать сразу, и в дальнейшем, используя статический импорт, вы могли бы уменьшить его до TABLE_SGSN_MAPPING

2. Человек, лучше всего подходящий для ответа на вопрос «почему», — это тот, кто написал этот код. Почему бы тебе не спросить его? Вы оба знаете намного больше о конкретных обстоятельствах этого проекта, чем мы когда-либо узнаем.

Ответ №1:

Существует более серьезная проблема с использованием инструкций, созданных из строк (даже если они в константах) — вы можете открыть дверь для SQL-инъекции. С точки зрения безопасности, вместо этого лучше использовать подготовленные инструкции, задавая параметры с помощью setXXX() методов, а не объединяя строки, как в вопросе.

И было бы неплохо иметь текст подготовленного оператора, определенный как постоянная строка в классе, где он используется, с заполнителями для параметров. Например:

 private static final String query = 
"update dbName.tableName set field = ? where condition = ?";
  

Комментарии:

1. Хорошие моменты. PreparedStatements более эффективно выполняются СУБД.

2. В примере используются подготовленные утверждения. И SQL-инъекция обычно связана с неправильным пользовательским вводом, а не с саботажем со стороны команды разработчиков, не доверяющей константам из других классов. IMO это слишком параноидально для обычных вариантов использования

Ответ №2:

Значение tableSgsnMapping всегда ConstantManager.TABLE_SGSN_MAPPING равно? Тогда я бы использовал эту константу, возможно, как статический импорт, чтобы сэкономить немного места. Переназначение его локальной переменной может сбить с толку читателей и привести к ошибкам, если ее значение будет случайно изменено.

Ответ №3:

Имя таблицы может измениться не так, как вы говорите. Но кто знает будущее?

Но мой главный аргумент в пользу ConstantManager.TABLE_SGSN_MAPPING заключается в том, что имена таблиц и столбцов обычно используются несколько раз в разных операторах и местах кода. Используя константы, вы можете быть уверены, что в одном редко используемом операторе SQL, касающемся этих вещей, нет опечаток. Мой любимый вопрос в этом углу: было ли имя таблицы во множественном числе или нет? («клиенты» против «customer»). Я просто не хочу думать об этом каждый раз снова — используя константы.