вторник, 21 апреля 2009 г.

Строки-ресурсы или магические строки (draft)

В продолжение предыдущего поста возникли логичные вопросы. А что делать с
String.Format(StringResourse.TotalString, total)? Кстати, вам легко понять это? А я ещё не начал перечислять минусы :)

Итак, начну с переносом строк в ресурсы. Начнём сначала. Какой смысл был у строки? Если смысл кокатация строчек. То первичный вопрос - накой козе баян? Зачем делать форматирование строке "Всего: " + total + " штук"? А потом повышаем косвенность, закидывая строку "Всего: {0} штук" в ресурсы?

В отличии от string, StringBuilder, String.Format назначение ресурсов в предоставление вариационности. Вариационности в способе отображения, а для строк это либо другой язык, либо другая система отображения значений (пример: дата, дроби и т.п.). Вы часто имеете дело с мультикультурными приложениями? :) Да и там чуток по другому делают. Причем не на стадии программирования, а это свойство относится к всем процессу разработки. Другой нюанс - некоторое множество сообщений, которое на каждом углу программы используется. Некое постоянное магическое множество. Типа "Всего: {0} руб.". Тут ещё можно подумать. Но вредно. Для этого есть специальные классы. Которые должны сразу выплёвывать такие строчки и мы не должны волноваться как это получилось.

Другой сногсшибательный аргумент - если у вас есть технический редактор, и ему удобно работать с одним списком сообщений. Представляю я работу этого редактора. Вместо того, чтобы заранее написать текст, который он ожидает. Или с программистом договориться во время непосредственного написания кода. Он будет открывать файл ресурсов и не соображая, что за туча сообщений, править. Полностью оторвав от контекста применения. Кто нибудь так делает? Ух ты! Ну и как часто так делаете? Чаще чем пишете код? :)

А теперь какие бонусы мы получаем от такой системы (не для варианта мультикультурной платформы, а для нашей простой разработки)
Бонус 1. Попробуйте посчитать количество ваших действий, чтобы внести изменение в вашу строчку. Ужас на крыльях ночи. И это только ради того, чтобы внести маленькое исправление в строчку. Боюсь если вы уделяете столько внимания строчкам, то время на полезный код у вас не остаётся вообще :) Мне намного легче править то, что я вижу непосредственно.
Бонус 2. Даже если не менять. Чтобы читатель мог понял, что тут написано и что ожидается, вам прийдётся скакать как минимум по двум файлам. Кстати, поиск таких вещей и мест их потребления - это другая тема. А разговор идёт не об одной сущности, а просто об одной строчке кода. Да к тому же ещё среди кучи строчек вам нужно ещё вашу. Упасть не встать.
Бонус 3. Я молчу, насколько это эффективно программируется по сравнению с простой строчкой кода :)
Бонус 4. Нарушение ценностей и принципов Implementation Patterns и Simple Design.
Бонус 5. Программирование ради неопределенного будущего. Какой то технический

Задайте себе вопрос - что вы чаще меняете: кучу сообщений без привязки к месту использования или конкретное сообщение в конкретном коде. И из этого делайте вывод. Если вы днями программируете текст в ресурсном файле. То ресурс это ваше все. А если вы пишите код программы и добавляете в него сообщения - то вывод очевиден. Что данные (а строка это данные) должны быть в непосредственной близости от места потребления.

Следующий вопрос - Magic String. Звучит очень странно. Но давайте вернёмся к аналогии. У нас есть Magic Number. Пример: 12. Конечно, любой скажет, что нужно напрячься, причем очень сильно, чтобы найти СМЫСЛ этого. Поэтому СМЫСЛ мы заключаем в название переменной int interest = 12. Ещё раз подчеркиваю, чтобы не искать смысл числу 12 по крупицам в коде окружающем это значение мы вводим переменную, в название которой перенесли смысл числа. В нашем примере 12 означает interest (процент). Теперь взглянем на наши Magic String:

string errorMessage = "Произошла ошибка. Повторите операцию";

Вот скажите, а чего вам не понятно в исходном сообщение? Смысл? Там же по-русски написано :) Я понимаю, что фраза "@#$#@$^%$" может запутать и нужно ввести поясняющую переменную. Но в примере то чего сложного?

Теперь пошли нюансы Magic String:
Бонус 1. Переменная, у которой область видимости максимум круглые скобочки в качестве параметра вызова в MessageBox, почему то становиться видна всей нашей функции. Как будто без этого мало строчек кода.
Бонус 2. При чтение кода нам нужно прыгать сначала к тексту применения, а потом к определению. Хотите скачи - идите на ипподром.
Бонус 3. Некоторые умельцы ещё и форматирование туда запихивают. Мозг выносится напрочь, когда обнаруживается код типа:
string totalString = "Всего: {0} штук";
....
String.Format(totalString , total);

Итог, использование Magic String и ресурсов в большенстве своём плохой и неоправданный стиль программирования. Но когда же их исползовать? Ресурсы - когда вариационность текстовой составляющей (языки, отображение и т.п.), Magic String - ну когда одно и тоже в многих местах или ну совсем длинная или непонятная строчка :)

2 комментария:

  1. >>Magic String - ну когда одно и тоже в многих местах

    Не согласен; основной повод magicString -- дать осмысленное наименование. Остальное -- вторично.

    Насчет ресурсных строк -- согласен, этот момент очень непроработан в .net

    -- meowth

    ОтветитьУдалить
  2. Я про это и говорю. Цитирую самого себя:

    string errorMessage = "Произошла ошибка. Повторите операцию";

    Не требует переменной. А вот если строка - "@#$#@$^%$" уже треубет

    string sendManFarAway = "@#$#@$^%$";

    :)

    ОтветитьУдалить