Строки в отдельном файле .pas

Это не может быть правильным местом для этого вопроса, если вы не можете его перемещать. Я отмечен как Delphi/Pascal, потому что это то, что я работаю в atm, но это может относиться ко всему программированию, которое я предполагаю.

В любом случае я делаю очистку кода и думаю о перемещении всех строк в моей программе в отдельный одиночный .pas файл. Есть ли какие-либо плюсы и минусы для этого? Это даже стоит делать?

Чтобы уточнить: я имею в виду, что я буду создавать отдельный файл, Strings.pas в нем я сделаю все свои текстовые переменные строки.

Ex

Текущий код

 Messages.Add('The voucher was NOT sent to ' + sName+
                          ' because the application is in TEST MODE.');
 Messages.Add('Voucher Saved to ' + sFullPath);
 Messages.Add('----------------------------------------------------------');

Новый код будет выглядеть примерно так:

Messages.Add(sMsgText1 + '' + sName + '' + sMsgText2 + '' + sFullPath)

В файле Strings.pas будут храниться все строковые данные. Надеюсь, что это имеет смысл

Ответ 1

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

Но, код вроде:

Messages.Add(sMsgText1 + '' + sName + '' + sMsgText2 + '' + sFullPath)

не лучше, чем код:

Messages.Add('The voucher was NOT sent to ' + sName+
                      ' because the application is in TEST MODE.');

Вы превратили беспорядочный, но читаемый вызов функции в беспорядочный и нечитаемый вызов функции. Со старым кодом (второй фрагмент чуть выше) вы можете прочитать код и посмотреть примерно то, что сообщение собирается сказать, потому что его много в тексте. С новым кодом вы не можете.

Во-вторых, причина для перемещения строк для сохранения связанных элементов и упрощения их изменения. Что делать, если вы хотите изменить вышеприведенное сообщение, чтобы вместо того, чтобы говорить "Файл" foo "в пути" bar "...", он сформулирован "Панель файлов \foo is..."? Вы не можете: способ построения сообщений по-прежнему фиксирован и разбросан по всему вашему коду. Если вы хотите изменить несколько сообщений для форматирования одинаково, вам нужно будет изменить множество отдельных мест.

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

Рефакторинг еще на один шаг

Я бы предложил вместо этого более агрессивный рефакторинг вашего кода сообщения. Вы определенно находитесь на правильном пути, когда предлагаете переместить свои сообщения в отдельный файл. Но не просто переместите строки: переместите также функции. Вместо большого количества Messages.Add('...'), разбросанных по вашему коду, найдите общее подмножество создаваемых вами сообщений. Многие будут очень похожи. Создайте семейство функций, которые вы можете вызвать, чтобы все подобные сообщения были реализованы с помощью одной функции, и если вам нужно изменить формулировку для них, вы можете сделать это в одном месте.

Например, вместо:

Messages.Add('The file ' + sFile + ' in ' + sPath + ' was not found.');
... and elsewhere:
Messages.Add('The file ' + sFileName + ' in ' + sURL + ' was not found.');

имеют одну функцию:

Messages.ItemNotFound(sFile, sPath);
...
Messages.ItemNotFound(sFileName, sURL);

Вы получаете:

  • Централизованные строки сообщений
  • Централизованные функции сообщений
  • Меньшее дублирование кода
  • Чистый код (без сборки строк в вызове функции, только параметры)
  • Легче переводить - обеспечить альтернативную реализацию функций (не забывайте, что просто перевод подстрок может быть недостаточным, вам часто нужно иметь возможность существенно изменять формулировку.)
  • Четкое описание того, что сообщение находится в имени функции, например ItemNotFount(item, path), что приводит к
  • Более четкий код, когда вы его читаете

Звучит неплохо для меня:)

Ответ 2

Я думаю, что имеет смысл переместить все строковые константы в одну единицу. Это значительно облегчает изменение текстов, особенно если вы хотите перевести на другие (человеческие) языки.

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

unit Strings;

resourcestring
  strMsgText1 = 'The voucher was NOT sent to ';

etc...

Но такая строка, вероятно, лучше сделать как:

resourcestring
  strVoucherNotSent = 
    'The voucher was NOT sent to %s because the application is in TEST MODE.';
  strVoucherForNHasValueOf =
    'The voucher for %s has a value of $%.2f'; 

Преимущество заключается в том, что на некоторых языках размещение и порядок таких подстановок различны. Таким образом, переводчик может размещать аргументы везде, где это необходимо. Конечно, приложение должно использовать Format() для обработки строки:

Messages.Add(Format(strVoucherNotSent, [sName]));
Messages.Add(Format(strVoucherSavedTo, [sFullPath]));
Messages.Add(Format(strVoucherForNHasValueOf, [sName, dblValue]));

Ответ 3

Если вы хотите перевести пользовательский интерфейс на разные языки, вы можете воспользоваться всем своим текстом в одном файле или, возможно, несколькими файлами, предназначенными для объявления строковых констант.

Однако, если вы сделаете это изменение без такой сильной мотивации, вы можете просто сделать свой код трудным для чтения.

Как правило, вы должны спросить, какие преимущества такого крупного рефакторинга есть, и если они не являются самоочевидными, тогда вы, возможно, меняете вещи только ради изменения.

Ответ 4

Если вы хотите перевести свое приложение, подумайте об использовании Gnu GetText для delphi, также известного как dxGetText. Это лучше, чем перенос ваших строк в отдельный .pas файл, поскольку он позволяет включать перевод без каких-либо специальных инструментов, любой перекомпиляции, даже конечными пользователями.

Ответ 5

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

Одно из преимуществ, которое я все еще не вижу, - это повторное использование строк. Хотя это не является прямой выгодой от доставки в другую единицу, это от перемещения строковых литералов до констант.

Но довольно значительный недостаток - это необходимое время для создания этого отдельного исходного файла. Вы можете рассмотреть возможность реализации этой хорошей практики программирования в следующем проекте. Это зависит от того, достаточно ли у вас времени (например, проект для хобби) или крайнего срока, на следующий проект или нет (например, студент) или просто на то, чтобы сделать некоторую практику. Как ответы Дэвида H и комментарии, как и все принятые вами решения, вы должны весить преимущества.

Если смотреть на всевозможные инструменты для рефакторинга, которые могут обеспечить некоторую автоматическую помощь, поймите, что перемещение строковых литералов в другую единицу не выполняет эту работу. Как Rudy и David M уже ответили, вам отчасти нужно переписать свой источник. Кроме того, поиск читаемых, коротких и применимых постоянных имен требует времени. Поскольку многие комментарии уже заявили, что контроль над написанием согласованности важен, мне нравится думать, что тот же аргумент относится и к замене самих констант.

И о ответах на перевод, независимо от того, применимо ли это к OP или нет, перемещение всех исходных строк в отдельный блок является лишь частью решения для перевода. Вы также должны заботиться о конструкторских строках (например, титры) и совместимости с графическим интерфейсом: более длинный перевод по-прежнему должен соответствовать вашей метке.

Если у вас есть роскошь или необходимость: пойдите для этого. Но я бы взял это на следующий проект.

Ответ 6

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

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

(*), используя dxgettext для "общих" dirs.