Сочинение на Java

Д

Анная глава начинает часть ΓV, "Архитектура проекта". Каждая из трех глав этой части представляет собой довольно короткое пояснение, как с помощью JBuilder написать понятный код.

Во всех трех главах, но в этой главе особенно, вы также узнаете, как с помощью

JBuiIder распутать плохо написанный код. Если вам от кого-то достался плохо напи­санный проект, то эта глава поможет вам разобраться в нем.

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

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

Код в стиле Колодной Горы

Известны такие японские стихотворения, называемые "Холодная Гора". Счита­ется, что их написал японский отшельник, который сначала жил как обычный чело­век, но закончил свои дни отшельником-провидцем в месте, которое называется Холодная Гора.

Вот одно из последних стихотворений Холодной Горы:

И Хэншэн написал эти строки

Этим строкам никто не поверит,

Приятен на вкус сладкий мед

Нелегко проглотить горькую пилюлю,

Нас радует то, что услаждает чувства

А что не нравится — вызывает наш гнев.

Но посмотрите на маленьких марионеток,

Они обессилели, играя на сцене.

{Перевод Александра Моргунова)

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

Конечно, вначале поэт заявляет, что как бы ни было просто его сообщение, ему все равно никто не поверит. В мире программирования на Java есть много людей, обсуждающих достоинства хорошей программной архитектуры и правильного пост­роения программ; наверно, они чувствуют себя немножко Хэншэном. Большая часть того, что они предлагают, очень проста, иногда даже совершенно очевидна, и все же большинство программистов продолжают вести себя беспечно, полностью игнорируя эти простые советы. В результате эти упрямцы наталкиваются на просто — таки немыслимые трудности. Грустно, что такой простой совет так часто игнорируется.

О чем эта глава

В данной главе мы обсудим следующие темы:

■ Соглашения по именам: искусство правильного именования переменных, ме-

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

■ В данной главе также обсуждается искусство поиска и исследования свойств переменных с помошью средств JBuilder, таких как Find Resources, Find Definition и Find In Path. Эти средства уже упоминались ранее в книге, но здесь вам будет продемонстрировано их практическое применение.

В следующих главах мы обсудим такие темы:

■ Комментирование кода. Опять-таки, многие программисты считают, что в этом вопросе они понимают все, но на практике не могут выполнить даже его основы. Большинство программистов, чтобы не писать комментарии, нахо­дят оправдание в лени или нехватке времени. Но более серьезное изучение вопроса показывает, что здесь все не так просто. Дело здесь в непонимании сути этого вопроса, которая приводит многих программистов к неспособнос­ти писать полезные комментарии. В главе 21 также рассматривается создание Javadoc-документации.

■ Модульность и повторное использование. Мастерством отыскания верной ар­хитектуры программы овладеть трудно. В основе этой задачи лежит искусство видения методов, объектов и пакетов в любой конкретной задаче. C помощью любой версии JBuilder вы можете реструктурировать свою программу. Но если у вас JBuilder редакции SE или Enterprise, то его средства корректировки свя­зей могут существенно упростить этот процесс.

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

примечаниеЯ хочу сделать нечто несколько необычное и посвятить эту часть книги себе. Все ошибки, рассмотренные в этих главах — это ошибки, сделанные мною в соб­ственных программах. Некоторые из них я совершаю и сейчас.

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

Проще, проще и еще проще

Основная тема текущего раздела — необходимость упрощения вашего кода. Я покажу, как это можно сделать с помощью создания правильных соглашений об именовании; с помощью разбиения вашего кода на отдельные методы, объекты и пакеты; с помощью написания хороших комментариев; и с помощью утилит вроде JUnit или средств корректировки связей JBuilder.

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

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

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

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

Спасительный язык Java

Я считаю, что сам язык Java является в программировании одним из лучших за­щитников подхода "чем проще, тем лучше". Большая часть JDK состоит из простых и понятных объектов. Сравните, насколько проще применять контейнеры списков Java, чем использовать STL-контейнеры языка C++. STL является знаменитой и ин­тересной библиотекой, но на ее полное освоение можно потратить годы. Многие программисты просто боятся ее и бегут он нее как от чумы. C другой стороны, боль­шинство программистов могут понять контейнеры списков Java после нескольких часов их изучения.

Объектная модель Java, спецификация JavaBean-компонент, классы работы с се­тью и клюс String Все это дальнейшие примеры того, как успешно Java делает простымр сложные темы. Есть места, где Java сложна, но в общем это замечательно простая спецификация.

Простота и понятность JDK повышает производительность труда программис­тов. Его методы и классы придерживаются хороших соглашений об именовании и здравого смысла в отношении модульности, а, кроме того, они хорошо документи­рованы. Сам JDK является реальным примером того стиля программирования, на стороне которого я выступаю в этой главе.

Соглашения об именовании

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

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

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

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

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

Абстрактный язык или конкретный язык

В данном разделе я предлагаю заняться медитацией на тему применения точных соглашений об именовании. Основная тема раздела проста и понятна: используйте для идентификаторов легко узнаваемые и очень точные существительные и глаголы.

Не применяйте имена переменных вроде num, Item, Value Или StrɪTem (по-рус­ски это примерно соответствует именам: Число, элемент, значение Или СтрЭле- мент). Эти имена недостаточно конкретны. Гораздо лучше имена типа book‰ist, NumPencils, StrPensilDescription ИЛИ SalaryTotal (списокКниг, колКаранда­шей, стрОписаниеКарандаша Или ИтогоЗарплата). Все это очень просто, по крайней мере, на бумаге. Но на практике оказывается, что это гораздо труднее, чем кажется вначале. Давайте разберемся почему.

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

примечаниеВозможно, первое, что она использует, будет средство Browse Classes (Просмотр классов) в меню Search (Поиск) JBuilder. Это средство может вывести все классы те­кущего проекта, как показано на рис. 20.1.

ιa**u⅛∙aι*uβ Поймите, что на рис. 20.1 и на других снимках экранов, приведенных в данной главе, не показаны реальные файлы, с которыми работает Виктория при поиске ошибки. Это просто файлы одного из проектов, приведенных в данной книге. Я исполь­зую их просто для иллюстрации. Проект такого размера, как у Виктории, занял бы не­Сколько экранов, забитых информацией, а здесь вы видите весь проект в одном окне.

После просмотра классов и пакетов проекта следую­щее, что может сделать Виктория — использовать диаг­раммы UML. Это средство доступно только разработ­чикам, работающим в продукте Enterprise. Но про­граммистам вроде Виктории оно может помочь оценить масштаб проекта.

Эта диаграмма может многое рассказать о структуре, и в особенности о взаимосвязях различных классов, со­ставляющих проект. (Подробнее об UML будет расска­зано в главе 31.)

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

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

Разыскивая код, содержащий список книг, она на-

И4 Vzse F U<⅛Et

CMsnaffic Jorg

! æ itt∣ IOflIS S [⅛i Ottdwortds. S ⅛entlb"j

; ⅛ BadOuy ‘ ⅛ Character I ⅛ EntttfBase : & EntItfList * £ OoodOuf I ⅛ Hero ‘ ⅛ Thing

‘ fe JBjImages

. w∣ Orassglf ; ⅛J grass2 gif J aJ hero. glf ‘ mI SoII gIf

M∣ SOllZglf s⅛∣ unis

∣⅛ JarResources 4, ResourceMlnder

` A TcoordlnateComerslon ■A Appisti

■■ ⅛ OameOblect ⅛ Olobals

• SkOndCamas A OrIdVlew A Playfleld

№ ⅛ Images

[oΓ]

Cancel

Zi

Рис. 20.1. Просмотр всех классов в проекте среднего размера с помощью средства Browse Classes

Тыкается на переменную с именем сан типа ArrayLiet. "Интересно, что делает эта переменная?" — проявляет интерес Виктория.

Виктория размышляет, может ли эта переменная содержать нужный список книг. Она не знает, как обрабатывается этот список. Находится ли он в хеш-табли­це? Или в связном списке? Или в массиве? Может быть, он хранится в текстовом файле? Она даже не знает наверняка, существует ли переменная, которую она ра­зыскивает. Может быть, книги хранятся в структуре данных совершенно другого типа.

SF~bJUF

OWect l

OridworMe

I

GameOtseci

Oridworids

[ EIfDraw-I I CrMCanvasJ |_ CrMlflesyJ

OridworidsMiUties

FnlHylist Ii Него

OrMwarMs-UtHs

H∏

TcoortSnateConvprsinn

⅜ Characteiust EntityList ⅛r CoordConvert TcoordinateConverslon ⅛ draw LItDraw

⅜∙ FCoIHeight: int ⅛∙ FCotWidth: int ⅛∙ FXPos. int ⅜ FYPos: Int ⅜ hero: Hero ⅛∙ playField GntMew

OridworMsjMntes

⅛j BitItyBase

JBvaJWt ∣

* CharacterAtO: void

* GameObJectO fold handlekevθ: void

⅛∕F run0 void

Draw6ackgroundθ void

,> drawMalnCharacterθ: void drawStatsO :void

GfBJ,, 1 Point

IwaJano

Рис. 20.2. UML-диаграмма части программы, приведенной на рис. 20.1

Она снова обращается к переменной с именем caii. По внешнему виду об этой переменной многого не скажешь.

Может, это слово "Call", но со второй заглавной буквой? Вряд ли это так, но от­брасывать этот вариант пока не стоит. Возможно, здесь применяется какая-то форма венгерской нотации. А, может, "с" значит "container" (контейнер), а "АП" может оз­начать все, что угодно. Это немного более похоже на правду, но опять-таки, с пол­ной уверенностью это утверждать нельзя. Например, "с" может значить и "char", и "calc", и “calendar" или "caption", и "certificate" или "class", и "check box" или "client". Вообще-то, оно может значить чуть ли не все что угодно.

Разочарованная Виктория решает продолжить поиск. Следующий вопрос, ко­нечно, состоит в том, что означает слово "АП" (Все)? Относится ли оно ко всем при — бамбасам в программе? Ко всем строкам в программе? Или, может быть, оно озна­чает все книги в программе?

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

Однако подумайте. Предположим, что код этой программы содержит 50 000 строк. И предположим, что Виктория просматривает фрагмент из 1 200 строк, в на­чале которого объявлено 35 переменных, и у всех имена вроде сан. Например, есть еще одна переменная ħMask, и еще cstuff, и третья — cList. Может быть, суще­ствуют и другие переменные с именами сАггау и CLinkedList Как после просмот­ра всех этих переменных Виктория может быть уверена в том, что именно caii со­держит список книг, который она разыскивает?

Некоторые программисты могут заявить, что Виктория просто лентяйка, и что ей надо начать просматривать код, дабы определить, как используется эта перемен­ная. Они защищают технику грубой силы для определения значения переменной по ее контексту. Это не им надо корректно называть переменные, а Виктории надо быть очень умной, чтобы определить, что они означают!

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

Смягчение удара грубого программирования с помощью JBuiIder

Чтобы хоть как-то продвинуться вперед, Виктория может воспользоваться сред­ством Find References (Найти ссылки), доступным в JBuilder. Она может перейти в начало файла, где описана переменная, и подвести курсор к нужному элементу кода. Затем она должна щелкнуть правой кнопкой мыши и выбрать в контекстном меню пункт Find References. Появится панель сообщений и диаграмма вроде пока­занной на рис. 20.3. Здесь можно увидеть все места программы, где используется указанная переменная. Если Виктория щелкнет на любом из элементов на панели сообщений, то она перейдет сразу в требуемое место кода.

Если эта техника не поможет, то может оказаться полезным другое средство — пункт Find in Path (Найти в каталоге) из меню Search. Если Виктория найдет все ссылки на нужную переменную с помощью упомянутой возможности, то она полу­чит листинг наподобие приведенного на рис. 20.4. Как ждите, рисунки 20.3 и 20.4 очень похожи. Возможно, небольшим преимуществом средства Find in Path является то, что для его работы не требуется, чтобы код уже был откомпилирован.

b-cjχ references io field aaii in class myproject appletl θ ⅛ appletl java
‰ arraylist aaii = new arraylisto; l ⅜ aall.addfsam"); aall.addf samm/); n3∙ aall.addf fred'');
■■■■ aall.addf fred”); l cf∙ aall.addf fred''); aall.addffred");
'" aah.addffred"); l∙∙ > aall.addf fred");
s-∙φ. findmorejava
l tħis.appletaa∣∣.c∣earθ;
1∙∙∙∙ applet.aaii.addf more data");
рис. 20.3. поиск ссылок на все переменные программы с помощью средства find references
s-βk search results for ,aaiΓ й tʌ appletl java
« arraylistaaii = new arraylisto;
* aall.addfsam*);
* aall.addfsamm∕);
* aall.addffred");
-♦ aall.addffred");
-∙ aall.addffred'');
* aah.addffred");
 * aall.addffred");
∙ ♦ aall.addf fred");
ej [д findmorejava
this.applelaall.clearo;
■ ■■■ * applet.aaii.addf more data");
рис. 20.4. поиск ссылок на переменную в нескольких файлах с помощью средства find in path

примечаниеСредство Find in Path может оказаться очень полезным, если вы хоти­те убедиться, что пользуетесь хорошими соглашениями об именовании. Например, с его помощью вы можете найти все вхождения слова "item" (элемент), или слова "list" (спи­сок), или же "value" (значение). Все эти имена исключительно неконкретны и могут дос­тавить немалые неприятности. Если вы с помощью средства Find in Path найдете такие Переменные, вы можете щелкнуть на каждой из них и придумать гораздо лучшее имя.

В JBuilder с помощью средства Find in Path можно провести глобальный поиск или замену. Это может оказаться очень полезным, если вы хотите заменить все вхождения неудачно названной переменной на более качественное имя.

Имеется и еще одно средство JBuilder, которое может пригодиться Виктории. При исследовании исходного кода она обнаружила, что существует много объявле­ний переменной сан в различных классах и в различных областях видимости одно­го класса. Иногда может быть непонятно, о какой переменной идет речь. Опять же, это пример отвратительного стиля программирования. Но Виктория застряла в этом коде и пытается разобраться в нем. Для этого она может щелкнуть правой кнопкой мыши на непонятной переменной и выбрать пункт Find Definition (Найти определение) во всплывающем меню JBuilder. Она тут же перейдет к объявлению этой переменной.

Лекарство есть

Виктория уже воспользовалась множеством мощных средств JBuilder для иссле­дования доставшегося ей кода. Но даже и при такой могучей поддержке очень труд­но преодолеть плохой стиль программирования.

Предположим, что Виктория нашла пять переменных, которые являются хоро­шими кандидатами на место искомой. Теперь ей надо просмотреть код, использую­щий каждую из этих переменных, чтобы выбрать из них нужную. После того как она найдет ее, ей предложат заняться другим проектом или, может быть, наступит дол­гожданный рождественский отпуск. Через две недели она вернется к этому коду и обнаружит, что забыла, хранится ли информация о книгах в переменной cAil или в переменной САггау. Или, может быть, это было cList? Все, что можно сделать — это снова начать просмотр кода и трудный поиск.

Здесь мы вернулись к задаче Хэншэна. Решение очевидно. Необходимо назвать переменную как-нибудь вроде booklist или, может быть, aBookList, чтобы было понятно, что это массив, содержащий список книг Виктории решила эту проблему с помощью массы сложных технологий. Но лучшее решение не требует высоких тех­нологий: просто правильно называйте переменные.

Мораль здесь в том, что при поспешном выборе имени переменной вы не эконо­мите время В конце концов, эта спешка приведет вас к потере гораздо большего ко­личества времени, нежели то, которое бы вы первоначально потратили на выбор ее корректного имени.

Рядом с объявлением переменной следует также поместить комментарий, опи­сывающий ее применение в программе. Например, "Список книг, автоматически инициализируемый при запуске программы" или, скажем, "Для инициализации этой переменной вызовите fIllBookList ()". Тема комментирования кода обсужда­ется в следующей главе.

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

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

Эпилог

Кое-кто из читателей, возможно, пожелает узнать, чем же завершилась эпопея Виктории. А все было так. Виктория, в конце концов, нашла, в какой переменной хранится список. Конечно, это была не переменная cAli, a cList. Поэтому она из­менила ее имя на booklist.

Странно, но после проверки всех изменений на следующий день она обнаружи­ла, что эта переменная опять стала называться cList. Она с помощью системы кон­троля версий определила имя того, кто провел это изменение Это был некто по имени Дэйв. Она послала Дэйву электронное письмо, объяснив, почему она изме­нила имя переменной на bookList, и попросила его быть более благоразумным. В ответ он написал, что это он автор кода, и он считает ее имя переменной слишком "броским", и он хочет, чтобы оно было cList. У него есть другой код, зависящий от этой переменной, и он не хочет изменять тот другой код просто из-за ее прихоти. Занавес.

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

Имена переменных и методы доступа

Вы, видимо, знаете, что в Java вы обычно не должны обращаться непосредствен­но к элементу данных другого объекта. Например, объект CList Из программы Вик­тории нельзя вызывать напрямую из другого исходного файла. Вместо этого к дан­ным объекта следует обращаться с помощью методов выборки и установки (get… И Set…). Эти методы доступа являются просто оболочками переменной:

Public ArrayList getBookList()

{

Return bookList;

)

Вы, наверное, заметили, что имя getBookList легко читается и понимается. Сравните это имя с именем getAAll(). Последнее имя было бы сгенерировано из одного из имен переменных, используемых автором программы, с которой при­шлось возиться Виктории. Метод с именем вроде getAAll() неуклюж, трудно чита­ется, трудно понимается и, пожалуй, даже выглядит неприятно.

Качественные соглашения об именовании помогут вам создавать хорошие мето­ды доступа к данным. Если имена методов выборки и установки в программе выгля­дят несколько нелепо, то часто это является признаком того, что что-то не так.

Аргументы методов: плохие, так себе, и хорошие соглашения об именовании

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

String parsestring(String name, String data, int value)

Попробуйте-κa угадать, что может делать такой метод. Если у вас сходное со мной мышление, то вряд ли вы далеко продвинетесь. Этот метод трудно читать. Даже если его реализация занимает три-четыре строки, и даже если он очень быстр и эффективен, этот метод все тавно трудно читать! Его трудно читать не из-за каче­ства кода в теле этого метода, а из-за используемого им соглашения об именовании.

А теперь посмотрите на другую запись объявления того же метода parsestring:

String findLastName(String userName, String delimiter, int maxChars)

Этот метод понять уже гораздо легче. Он может не ответить на все ваши вопросы, но он, по крайней мере, дает вам понятие о том, для чего он написан. Так и не по­нятно, что означает Maχchars, И наверняка есть сомнения по поводу ограничителя (delimiter). Но все-таки эта запись значительно лучше. Этот код далеко не вели­колепен, однако он вполне приемлем. Глядя на него, вы можете предположить, что это метод для выборки фамилии (last name) из строки, содержащей имя и фамилию. Например, вы передаете в параметре "Линус Торвальдс" и получаете "Торвальдс"

А теперь взгляните на такой вариант того же самого метода:

String getLastNameFromUserName(String userName,

String UserNameDelimiter, int InaxCharsInLastName)

FtyptOtett AppieU

________

String IiserName, String UserNameDeIimiter, int MaxCharslnLastName

рис. 20.5. параметры метода get lastname from username в окне parameterinsight(примерный перевод имен параметров: имяПользователя, ограничительИме — ниПольэователя, максСимвВИмени).

Я считаю, что этот код лучше вто­рого примера, потому что он конкрет­нее. И в самом деле, ваше понимание одного или более идентификаторов этого метода может измениться после прочте­ния этого третьего объявления. Оно менее непротиворечиво и поэтому легче для понимания.

примечаниеПосмотрите на рис. 20.5. На нем показано окно Parameterlnsight, с помощью ко­торого разработчик может найти параметры метода GetLastNameFromUserName. Если вы потратите время на создание качественных имен аргументов для своих ме­тодов, и если вы пользуетесь ParameterInsight, то справочные файлы или документа­ция могут вообще не понадобиться. Ваш код становится самодокументированным, и вы можете получить всю необходимую информацию, просто напечатав открываю­щую скобку и нажав Ctrl+Shift+пробел для вызова ParameterInsight.

Назначение и использование этой функции можно понять, просто про­читав ее объявление. Я не предлагаю вам вовсе не комментировать свой код; просто если вы не вставите комментарии, то вы хотя бы можете обеспечить приличные имена переменных.

Почему программисты применяют плохие соглашения об именовании?

Почему программисты (в том числе и я) зачастую создают плохие имена пере­менных, даже если они могут придумать и лучшие?

Эта проблема тройственна:

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

■ Неверные приоритеты у программистов. Неважно, насколько вы спешите, важ­но то, что доведение объявлений переменных, по крайней мере, до второй степени из вышеприведенных трех просто-таки жизненно важно. Это важнее соблюдения сроков, ухода с работы на 15 минут раньше или возвращения к более интересным частям проблемы, над которой вы сейчас работаете. Поче­му оно важнее всего остального? Потому что в итоге хорошие соглашения об именовании помогают нам завершать проекты в срок, приходить домой с ра­боты рано и освобождать нас от рутинных дел, дабы мы могли сконцентриро­ваться на интересных частях наших программ. Другими словами, мы только думаем, что экономим время, записывая объявление вроде первого из выше­приведенных. На самом деле мы тратим лишнее время — причем не только свое время, но и время того, кто читает наш код!

■ Некоторые программисты не могут найти подходящие слова. Да, действительно, программистов берут на работу не из-за их навыков в изящной словесности. Большинство программистов являются специалистами в логике и работе с аб­стракциями и символами, и многие из них хорошо решают задачи. Если у них нет, по крайней мере, некоторых из этих умений, они попросту не смогут программировать. Но чтобы написать работающий код, совсем не обязатель­но ловко обращаться со словами. Честно говоря, часто бывает труднее подо­брать для своих идентификаторов хорошие имена, нежели заставить коррект­но выполняться свой код. К сожалению, хорошие соглашения об именовании отчасти являются результатом врожденного умения, с которым мы рождаемся либо приобретаем в результате многих лет тяжкого труда.

Если это проблемы, то каковы их решения? На этот вопрос ответить трудно, но вот мои указания:

■ Не расслабляйтесь, когда дело доходит до создания имен переменных. Труди­тесь над этой важной частью своей программы исключительно серьезным об­разом. Во время программирования иногда можно и расслабиться. Но нельзя расслабляться в неудачное время. Если обычный компетентный программист может неверно понять назначение переменной, то дайте ей точное имя!

■ Поймите, что не так уж много дел являются насколько важными, как коррект­ное объявление ваших программ. В итоге это сэкономит ваше время, сделает работу приятной и освободит вас для решения более интересных проблем. Правильно расставьте свои приоритеты. Есть совсем не много вещей, более

Важных, нежели правильное название идентификаторов в программе!

■ Вы можете не быть Шекспиром, но вы можете пройти дальше первой стадии. Не используйте слишком неточные переменные. Не называйте что-либо list (список), Когда на самом деле это booklist (списокКниг). Не называйте пе­ременную Паше (имя), Если на самом деле это FirstName (фамилия). Будьте максимально точны, но и не волнуйтесь, если не сможете достигнуть идеала.

■ Выделите время на доводку кода, написанного в спешке. Эту работу можно выполнять, когда вы слишком устали от работы над сложной проблемой, или когда у вас появился небольшой промежуток времени, который можно запол­нить легко разбиваемой на части задачей, или, например, когда вы сидите на нудном совещании.

Короче говоря, искусство правильного выбора имен переменных требует тяже­лой работы, терпения, правильной расстановки приоритетов и большой толики творчества. Возможно, эта задача не так проста, как кажется на первый взгляд. Са­мое главное здесь — осознать важность этой темы и начать воспитывать в себе при­вычку делать все правильно. Если вы можете понять важность этой задачи, вы нач­нете придавать ей все большее и большее значение.

Всегда ли можно использовать неточные имена переменных?

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

Может быть десяток возможных имен, и, возможно, три-четыре из них плохие, три хорошие, и еще три просто замечательные. Выбор любого из них лучше, чем ис­пользование неточного варианта наподобие Num, value Или Item. Но выбор наилуч­шего — это искусство, а не наука.

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

Рассмотрим следующий метод:

Void SetFirstName(String value)

{

This. fIrstName — value;

}

Некоторые скажут, что объявление этого метода нарушает правило выбора точ­ных имен переменных. И действительно, переменная Value (значение) не имеет конкретного смысла. Это имя настолько неточно, насколько вообще можно себе представить.

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

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

■ Назначение метода очевидно, и поэтому врад ли возникнет непонимание. Этот метод, очевидно, является методом установки, который укладывается в хоро­шо известную схему языка Java о методах выборки и установки. Более того, имя этого метода очень ясно и понятно. Любому, кроме, быть может, самого начинающего новичка, должно быть очевидно, что назначение этого метода состоит в присваивании значения переменной Value Полю данных метода с именем FirstName. Здесь трудно запутаться.

■ В методе объявлена только одна переменная. Если бы метод имел то же самое имя и то же самое назначение, но два параметра, то потребовалась бы боль­шая точность. Например, если бы существовало два параметра — string Value И String data То не было бы сразу понятно, как они должны обра­батываться. В этом случае нужны более точные имена, скажем, string AFirstName И String aMilitaryRank (фамилия И воинскоеЗвание).

И последнее, что нужно здесь сказать: Точность имен переменных нужна для по­мощи программисту, а не для того чтобы раздражать его. Освоение искусства созда­ния хороших имен переменных требует определенного труда. В случае, подобным нашему, нет необходимости в точности, поэтому сойдут и абстрактные или неточ­ные имена, которые легко придумать, и даже можно автоматизировать их создание. (На самом деле, когда вы будете читать о средстве BeanIsight, вы узнаете, что JBuilder автоматически создает имена переменных вроде приведенных здесь.)

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

Резюме

Если вы будете давать своим переменным хорошие имена, то, вполне возможно, сможете завершить свою работу гораздо раньше более подготовленных программис­тов, которые не обращают внимания на такие "мелкие", по их мнению, детали. Каж­дый может снабдить свой код комментариями и придумать, по крайней мере, дос­таточно осмысленные имена переменных. C помощью этой "секретной техники программирования" вы можете заткнуть за пояс тех, кто не придает значения этим вопросам просто-таки мирового значения.

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

В следующей главе речь пойдет о комментировании кода и использовании Javadoc. После этого будет рассказано о разбиении кода на отдельные методы и объекты. Эти приемы могут существенно упростить ваш код.

В главе 30, "Тестирование модулей с помощью JUnit", вы прочитаете о техноло­гиях "хорошей практики программирования", таких как экстремальное программи­рование и тестирование модулей. Материал, относящийся к теме данной главы, со­держится также и в главе 31, "Корректировка связей и UML".

Марджи и Чарли Калверт

Глава 21

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *