Главная » C# » Решение проблемы пробельных символов приложения перевода в Visual C# (Sharp)

0

Проблему пробельных символов можно решить несколькими способами. Какой из них выбрать, зависит от ваших требований. Рассмотрим несколько решений, чтобы выяснить, какое из них подходит лучше всего для нашей программы перевода.

Удаление пробельных символов

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

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

в его начальное состояние может оказаться весьма проблематичным, а то и вовсе не возможным.

ПРИМЕЧАНИЕ

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

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

public static string TrimmingWhitespace(string buffer) { string trimmed = buffer.Trim();

return  LanguageTranslator.Translator.TranslateHello(trimmed);

}

Временный метод TrimmingWhitespace () удаляет пробельные символы из строки, которую нужно перевести. В нем применяется метод buffer .Trim(), который проставляет новую функциональность предварительной обработки буфера. После этого метода вызывается первоначальный метод TranslateHello О, чтобы выпоить перевод.

Конечно же, новый метод необходимо протестировать, чтобы убедиться в том, что он должным образом удаляет пробельные символы из строк, которые нужно перести. Соответствующий код будет таким:    •

verifyValue = TrimmingWhitespace("alio"); if (verifyValue.CompareTo("hallo") != 0) {

Console.WriteLineC’Test failed of extra white spaces alio to hallo");

}

Код тестирования вызывает рабочий метод TrimmingWhitespace(), чтобы провить, что все работает должным образом. Код собственно верификации не меняется.

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

Обнаружение подстроки

Другим способом решения проблемы пробельных символов является поиск опреленной подстроки в буфере. Этот подход можно рассматривать как поисковое решение, где метод в цикле последовательно сравнивает элементы буфера с обраом текста. Рабочий код для этого способа показан на рис. 3.8.

Рис. 3.8. Решение проблемы пробельных символов способом нахохедения подстроки

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

Какое решение лучшее?

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

Что я хочу этим сказать? Необходимо создать дополнительные тесты, чтобы вислить, какие сценарии могут вызвать проблемы в вашей программе. Решение, состоящее в удалении пробельных символов, не является идеальным и в  опреденных ситуациях не работает, как доказывается следующим тестовым кодом. Сколько бы вы ни пытались исправить решение, чтобы оно успешно прошло этот тест, сделать это вам не удастся.

verifyValue = TrimmingWhitespace ("a alio"); if (verifyValue.CompareTo("hallo") != 0) {

Console.WriteLine("Test failed: cannot parse multiple words");

}

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

пешной, т. к. метод CompareTo () сбивает с толку смещение буфера, вызванное нальной буквой "а".

Но второе  решение, нахождение подстроки,  успешно проходит  испытание новым тестом, который находит слово "alio". Так как первое решение не выдерживает ный тест, то можно сказать, что данное решение неприемлемо. В то же самое время успешное прохождение вторым решением второго теста вдобавок к первому пышает наше доверие этому решению. Но не стоит торопиться делать заключение касательно его надежности, т. к. оно не выдерживает испытания следующим тестым кодом:

verifyValue = FindSubstring("allodium"); if (verifyValue.CompareTo("hallo") != 0) {

Console.WriteLineC’Test failed: cannot parse multiple words");

}

Проверяемое слово, "allodium", содержит символы "alio". Верификация будет уешной, когда она не должна быть таковой, что является примером ложноположельного результата.

ПРИМЕЧАНИЕ

Важно иметь большое количество тестов, чтобы можно было проверить как можно больше возможных сценариев. Эти тесты должны содержать такие, которые должны вызывать успешное выполнение, и такие, которые должны вызывать неудачное волнение.

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

САМОИСТЯЗАНИЕ      ПРИ      РАЗРАБОТКЕ

С первого взгляда может показаться, что создание решений, следуемое созданием тестов, которые сводят на нет эти решения, является  упражнением  в  самоистязании. Еще бы — вы намеренно стараетесь завалить код, в создание которого  вложили столько усилий. Но вы должны осознавать, что этот процесс является частью общего процесса разработки программного обеспечения,  и  обязаны  относиться  к  нему  со всей серьезностью. Некоторые программисты не заботятся  о создании  тестов  для своего кода, но это те программисты, которые создают профессии разработчика прраммного  обеспечения дурную  славу.

Вы должны стремиться быть разработчиком, которому можно доверять, а для этого необходимо тестировать свой код. Я работал, а моя жена и сейчас работает, рукодителем проектов по разработке прогрвммного обеспечения. В ее словах: "Я могу терпеть медленных разработчиков, но я не  выношу  разработчиков,  которым  я  не могу доверять в написании  стабильного  и  надежного  кода.  Проблема  с  ненадежни  разработчиками  заключается  в  том,  что  я  не  могу  позволить  им  отправить  код в промышленный выпуск, и мне всегда  нужно  иметь  кого-либо,  чтобы  присматрать  за  их работой".

Пишем тест, прежде чем писать код

Предыдущие решения были неудачными, потому  что каждое из  них было своего рода коленным рефлексом. В программировании  коленный  рефлекс — это  создие решения, направленного на исправление обнаруженной ошибки,  и  не  более того. Вместо этого подхода следует вычислить, о чем говорит нам данная ошибка. Первоначальная проблема с ведущими пробельными символами не заключалась лишь в наличии пробельных символов, а была своего рода вопросом: "А что, если текст не выровнен или является частью предложения и т. п.?"

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

Таблица      3.1.       Ситуации       для       тестирования       программы       перевода

Ситуация

Результат  верификаци и

ali o

Успех

"   ali o   "

Успех

wor d    ali o

Неудача:  нельзя  переводить одно слово без перевода всех других слов

wor d   ali o   wor d

Неудача: по той же само причине, что и в случае с текстом wor d ali o

prefixall o

Неудача: не то слово

alloappen d

Неудача: не то слово

prefixalloappen d

Неудача:  не то слово

Как можно видеть, исполнение большинства тестов заканчивается неудачей, т. к. компонент перевода способен переводить только отдельные слова. Тесты в табл. 3.1 вроде бы охватывают все возможные ситуации, но в действительности это не так. Имеются еще две возможные ситуации, которые показаны в табл. 3.2.

Таблица       3.2.     Дополнительные         ситуации         для         тестирования

Ситуация

Результат   верификаци и

Alio

Успех

" alio "

Успех

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

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

На рис. 3.9 показано рабочее решение проблемы.

Рис. 3.9. Конечное приложение перевода

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

ПРИМЕЧАНИЕ

Во всех рассмотренных решениях применялись  методы  типа  string .  Это  очень сложный тип, который поддерживает многие операции, часто применяющиеся на тетовых  данных.

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

Заключение строк в кавычки

Вы, наверное, обратили внимание на использование двойных и одинарных кавычек в вызове метода CompareTo (). Эти два типа кавычек существенно отличаются друг от друга. Двойные кавычки определяют строковый тип, как показано в следующем примере:

"usin g   doubl e   quotes "

Одинарные же кавычки применяются для определения символа, например  ‘а’ .

Соответственно, одинарные кавычки можно использовать только с одиночным символом. Одиночный символ можно рассматривать  как букву,  но  это  не  всегда так, поскольку не во всех языках имеются буквы. При попытке определить строку с   помощью  одинарных  кавычек  компилятор  С#  сгенерирует  ошибку,   которая в .NET обычно называется исключением (exception).

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

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