Совершенный код. Совершенный код. Мастер-класс. Стив Макконнелл. Руководство по стилю программирования и конструированию по
Скачать 5.88 Mb.
|
ГЛАВА 3 Семь раз отмерь, один раз отрежь: предварительные условия 57 Если не проведено адекватное проектирование архитектуры, во время конст# руирования вы можете решать верную проблему неверным способом. По мере написания кода для неверной архитектуры цена изменений архитектуры воз# растает, так что перед началом программирования вы должны проверить и правильность архитектуры. Выбор подхода к конструированию должен определяться принятым подходом к предварительным условиям конструирования. 58 ЧАСТЬ I Основы разработки ПО http://cc2e.com/0489 Г Л А В А 4 Основные решения, которые приходится принимать при конструировании Содержание 4.1. Выбор языка программирования 4.2. Конвенции программирования 4.3. Волны развития технологий 4.4. Выбор основных методик конструирования Связанные темы Предварительные условия: глава 3 Определение типа ПО, над которым вы работаете: раздел 3.2 Влияние размера программы на ее конструирование: глава 27 Управление конструированием: глава 28 Проектирование ПО: главы 5–9 Как только вы убедились, что адекватный фундамент для конструирования про# граммы создан, фокусом подготовки становятся решения, более специфичные для конструирования. В главе 3 мы обсудили программные эквиваленты чертежей и разрешений на конструирование. Как правило, у программистов нет особого кон# троля над этими подготовительными действиями, поэтому главной темой главы 3 была оценка того, с чем приходится работать в начале конструирования. Эта глава посвящена тем аспектам подготовки, за которые прямо или косвенно отве# чают отдельные программисты и технические руководители проекта. Мы рассмот# рим выбор специфических инструментов и непосредственную подготовку к ра# боте над приложением. Если вы думаете, что уже достаточно знаете о подготовке к конструированию, можете сразу перейти к главе 5. ГЛАВА 4 Основные решения, которые приходится принимать при конструировании 59 4.1. Выбор языка программирования Избавляя разум от всей ненужной работы, хорошая нотация позволяет со% средоточиться на более сложных проблемах и в конечном счете повышает интеллект человечества. До появления арабской нотации умножение было весьма сложным, а деление даже целых чисел требовало усилий ведущих ма% тематиков. Возможно, ничто в современном мире не смогло бы удивить гре% ческого математика сильнее, чем то, что большинство европейцев умеют делить крупные числа. Это показалось бы ему абсолютно невозможным… Легкость выполнения операций над десятичными дробями — почти сверхъ% естественный результат постепенного обнаружения отличной нотации. Альфред Норт Уайтхед (Alfred North Whitehead) Язык программирования, на котором будет реализована система, заслуживает большого внимания, так как вы будете погружены в него с начала конструирова# ния программы до самого конца. Исследования показали, что выбор языка программирования несколькими спо# собами влияет на производительность труда программистов и качество создава# емого ими кода. Если язык хорошо знаком программистам, они работают более производительно. Данные, полученные при помощи модели оценки Cocomo II, показывают, что про# граммисты, использующие язык, с которым они работали три года или более, при# мерно на 30% более продуктивны, чем программисты, обладающие аналогичным опытом, но для которых язык является новым (Boehm et al., 2000). В более раннем исследовании, проведенном в IBM, было обнаружено, что программисты, облада# ющие богатым опытом использования языка программирования, были более чем втрое производительнее программистов, имеющих минимальный опыт (Walston and Felix, 1977). (Различия результатов двух исследований объясняются тем, что в мо# дели Cocomo II более тщательно изолируется влияние отдельных факторов.) Программмисты, использующие языки высокого уровня, достигают бо# лее высокой производительности и создают более качественный код, чем программисты, работающие с языками низкого уровня. Утверждается, что при работе с такими языками, как C++, Java, Smalltalk и Visual Basic, производи# тельность труда программистов, а также надежность, простота и понятность про# грамм в 5–15 раз выше, чем при использовании низкоуровневых языков, таких как ассемблер и C (Brooks, 1987; Jones, 1998; Boehm, 2000). Избавившись от необ# ходимости проводить праздничную церемонию каждый раз, когда оператор язы# ка C делает то, что было задумано, вы сэкономите время. Более того, высокоуров# невые языки выразительнее низкоуровневых. Каждая строка кода выполняет боль# ший объем работы. В табл. 4#1 указано типичное отношение функциональности команд некоторых языков к функциональности операторов языка C. Показатель, превышающий 1, означает, что строка кода на указанном языке выполняет боль# ше работы, чем строка кода на C. 60 ЧАСТЬ I Основы разработки ПО Табл. 4-1. Сравнение функциональности операторов высокоуровневых языков с функциональностью операторов C Язык Функциональность операторов в сравнении с языком C C 1 C++ 2,5 Fortran 95 2 Java 2,5 Perl 6 Python 6 Smalltalk 6 Microsoft Visual Basic 4,5 Источники: «Estimating Software Costs» (Jones, 1998), «Software Cost Estimation with Cocomo II» (Boehm, 2000) и «An Empirical Comparison of Seven Programming Languages» (Prechelt, 2000). Некоторые языки лучше выражают концепции программирования, чем другие. Здесь уместно провести параллель между естественными языками — скажем, ан# глийским — и языками программирования, такими как Java и C++. Изучая есте# ственные языки, лингвисты Сапир и Уорф (Sapir and Whorf) высказали предполо# жение, что способность к размышлению над определенными идеями связана с выразительной силой языка. Согласно гипотезе Сапира#Уорфа способность чело# века к обдумыванию определенных мыслей зависит от знания слов, при помощи которых можно выразить эту мысль. Если вы не знаете слов, то не сможете выра# зить мысль и, возможно, даже сформулировать ее (Whorf, 1956). Программисты испытывают аналогичное влияние языков программирования. «Слова», которые язык предоставляет программисту для выражения мыслей, не# сомненно, влияют на способ их выражения, а возможно, даже определяют, какие мысли можно выразить на данном языке. За доказательствами влияния, оказываемого языками программирования на мыш# ление программистов, далеко ходить не надо. Типичная история такова: «Мы пи# сали новую систему на C++, но большинство наших программистов не имели особого опыта работы на C++. Раньше они использовали Fortran. Они писали код, который компилировался на C++, но на самом деле это был замаскированный Fortran. В итоге они заставили C++ эмулировать недостатки языка Fortran (такие как операторы goto и глобальные данные) и проигнорировали богатый набор объектно#ориентированных возможностей C++». Данный феномен наблюдается в отрасли уже много лет (Hanson, 1984; Yourdon, 1986a). Описания языков История разработки некоторых языков и их общие возможности довольно инте# ресны. Ниже приведены описания языков, наиболее популярных в настоящее время. Ada Высокоуровневый язык общего назначения, основанный на языке Pascal. Разра# ботанный под патронажем Минобороны США, он особенно хорошо подходит для ГЛАВА 4 Основные решения, которые приходится принимать при конструировании 61 создания встроенных систем и систем, работающих в реальном времени. В языке Ada особое внимание уделяется абстракции данных и сокрытию информации, а также проводится различие между открытыми и закрытыми частями каждого класса и пакета. Название «Ada» было присвоено языку в честь Ады Лавлейс (Ada Lovelace) — женщины#математика, которую считают первым программистом в мире. Сегодня язык Ada используется преимущественно для разработки военных, космических и авиационных систем. Ассемблер Низкоуровневый язык, каждая команда которого соответствует одной команде компьютера. Вследствие этого ассемблер специфичен для отдельных процессо# ров — например, для конкретных процессоров Intel или Motorola. Ассемблер счи# тается языком второго поколения. Большинство программистов избегают его и используют, только если к быстродействию или компактности кода программы предъявляются повышенные требования. C Среднеуровневый язык общего назначения, первоначально тесно связанный с ОС UNIX. Некоторые свойства (структурированные данные, структурированная управ# ляющая логика, машинная независимость и богатый набор операторов) делают его похожим на высокоуровневый язык. Язык C также называют «портируемым языком ассемблера», поскольку он не строго типизирован, поощряет применение указателей и адресов и поддерживает некоторые низкоуровневые возможности, такие как побитовые операции. Язык C, разработанный в 1970#х компанией Bell Labs, предназаначался для сис# тем DEC PDP#11. На C были написаны ОС, компилятор C и приложения UNIX для систем DEC PDP#11. В 1988 г. для систематизации C был издан стандарт ANSI, ко# торый в 1999 г. был пересмотрен. В 1980#х и 1990#х гг. язык C был стандартом «де#факто» в области разработки программ для микрокомпьютеров и рабочих стан# ций. C++ Этот объектно#ориентированный язык был разработан на базе C в компании Bell Labs в 1980#х. Совместимый с языком C, он поддерживает классы, полиморфизм, обработку исключений, шаблоны и обеспечивает более надежную проверку ти# пов, чем C. Кроме того, он предоставляет разработчикам богатую и эффективную стандартную библиотеку. C# Эта комбинация объектно#ориентированного языка общего назначения и среды программирования разработана в Microsoft. C# имеет синтаксис, похожий на син# таксис C, C++ и Java, и включает богатый инструментарий, помогающий разраба# тывать приложения на платформах Microsoft. 62 ЧАСТЬ I Основы разработки ПО Cobol Напоминает английский язык и был разработан в 1959–1961 гг. для нужд Мин# обороны США. Cobol служит преимущественно для разработки бизнес#приложе# ний и до сих пор является одним из самых популярных языков, уступая лишь Visual Basic (Feiman and Driver, 2002). По мере развития языка в нем была реализована поддержка дополнительных математических функций и ряда объектно#ориенти# рованных возможностей. Аббревиатура «Cobol» расшифровывается как «COmmon Business#Oriented Language» (универсальный язык, ориентированный на коммер# ческие задачи). Fortran В этом первом высокоуровневом языке программирования были представлены концепции переменных и высокоуровневых циклов. Название расшифровывает# ся как «FORmula TRANslation» (транслятор формул). Разработанный в 1950#х, Fortran претерпел несколько значительных ревизий: так, в 1977 г. была разработана вер# сия Fortran 77, в которой была реализована поддержка блочных операторов if#then# else и манипуляций над символьными строками. В Fortran 90 были включены сред# ства работы с пользовательскими типами данных, указателями, классами, а также богатый набор функций для работы с массивами. Fortran применяется преимуще# ственно для разработки научных и инженерных приложений. Java Синтаксис этого объектно#ориентированного языка, разработанного Sun Micro# systems, Inc., напоминает C и C++. Java — платформенно#независимый язык: ис# ходный код Java сначала преобразуется в байт#код, который может выполняться на любой платформе в среде, известной как «виртуальная машина». Java широко используется для создания Web#приложений. JavaScript Этот интерпретируемый язык сценариев мало чем связан с Java. Чаще всего его используют для создания кода, выполняющегося на клиентской стороне, напри# мер, для разработки несложных функций и интерактивных приложений для Web# страниц. Perl Этот язык обработки строк основан на C и нескольких утилитах ОС UNIX. Perl часто используется для решения задач системного администрирования, таких как со# здание сценариев сборки программ, а также для генерации и обработки отчетов. Кроме того, на нем создают Web#приложения, такие как Slashdot. Аббревиатура «Perl» расшифровывается как «Practical Extraction and Report Language» (практи# ческий язык извлечений и отчетов). PHP Этот язык с открытым исходным кодом предназначен для разработки сценариев и имеет простой синтаксис, похожий на синтаксис языков Perl, JavaScript, C и оболочки Bourne Shell. PHP поддерживается всеми основными ОС и служит для ГЛАВА 4 Основные решения, которые приходится принимать при конструировании 63 создания интерактивных функций, выполняющихся на стороне сервера. PHP#код может быть встроен в Web#страницы для получения доступа к БД и отображения содержащейся в ней информации. Аббревиатура «PHP» первоначально расшиф# ровывалась как «Personal Home Page», но теперь означает «PHP: Hypertext Processor». Python Этот интерпретируемый интерактивный объектно#ориентированный язык под# держивает множество сред. Чаще всего его используют для написания сценариев и небольших Web#приложений, однако он поддерживает и некоторые средства, помогающие создавать более крупные программы. SQL SQL (Structured Query Language, язык структурированных запросов) «де#факто» яв# ляется стандартным языком выполнения запросов, обновлений реляционнных БД и управления ими. В отличие от других языков, описанных в этом разделе, SQL является «декларативным языком», т. е. определяет не последовательность, а резуль# тат выполнения некоторых операций. Visual Basic Basic (Beginner’s All#purpose Symbolic Instruction Code, универсальная система сим# волического кодирования для начинающих) — это высокоуровневый язык, первая версия которого была разработана в Дартмутском колледже в 1960#х. Visual Basic — это высокоуровневая объектно#ориентированная версия Basic, предназначенная для визуального программирования. Изначально Visual Basic был разработан в Microsoft для создания приложений Microsoft Windows. Позднее в нем была реали# зована поддержка настройки Microsoft Office и других приложений для настольных ПК, создания Web#приложений и других программ. По оценкам экспертов в самом начале первого десятилетия XXI века Visual Basic являлся самым популярным язы# ком среди профессиональных разработчиков (Feiman and Driver, 2002). 4.2. Конвенции программирования В высококачественном приложении должна быть очевидна связь между концептуальной целостностью архитектуры и ее низкоуровневой реализацией. Реализация должна соот# ветствовать высокоуровневой архитектуре и обладать внут# ренней согласованностью. В этом и заключается смысл принципов конструиро# вания, определяющих конвенции именования переменных, классов, методов, а также форматирования кода и оформления комментариев. При разработке сложной программы архитектурные принципы вносят в программу структурный баланс, а принципы конструирования — низкоуровневую гармонию, при наличии которой каждый класс воспринимается как неотъемлемая часть об# щего плана. Любая крупная программа требует применения контролирующей структуры, унифицирующей аспекты языка программирования. Красота крупной структуры частично заключается в том, как в ее отдельных компонентах выраже# ны особенности архитектуры. Без унификации ваша программа будет смесью Перекрестная ссылка Подроб- нее о силе конвенций см. раз- делы 11.3–11.5. 64 ЧАСТЬ I Основы разработки ПО небрежных вариаций стиля, заставляющих прилагать дополнительные усилия только для того, чтобы понять различия в стиле кодирования, которых вполне можно было избежать. Одно из условий успешного программирования — устра# нение ненужных вариаций, позволяющее сосредоточиться на действительно не# обходимых вариациях. См. об этом подраздел «Главный технический императив разработки ПО: управление сложностью» раздела 5.2. Что, если у вас есть отличный план создания картины, но одну ее часть вы реши# те писать в классическом стиле, другую в импрессионистском, а третью в кубист# ском? Как бы упорно вы ни следовали своему грандиозному плану, картина не будет концептуально целостной. Она будет похожа на коллаж. Программа тоже должна обладать низкоуровневой целостностью. Перед началом конструирования сформулируйте конвенции программи# рования. Детали конвенций кодирования относятся к такому низкому уровню, что после написания программы их почти невозможно изменить. В оставшейся части книги я еще не раз затрону конвенции кодирования. 4.3. Волны развития технологий Я видел, как взошла звезда ПК, в то время как звезда мэйнфреймов опустилась за горизонт. Я видел, как консольные программы были вытеснены программами с GUI. Я также видел, как традиционные программы уступили главную роль Web# приложениям. Могу предположить, что, когда вы будете читать эту книгу, будут бурно развиваться некоторые новые технологии, а Web#программирование в его современном (2004) виде начнет отходить на второй план. В соответствии с эти# ми технологическими циклами, или волнами, изменяются и методики програм# мирования. В зрелых технологических средах — таких как среда Web#программирования в середине 2000#х — нам доступны все достоинства богатой инфраструктуры раз# работки ПО. Такие среды предоставляют широкий выбор языков программиро# вания, мощные средства поиска ошибок, эффективные инструменты отладки и надежные автоматизированные средства оптимизации производительности при# ложений. Компиляторы почти не содержат ошибок. Инструменты хорошо опи# саны в документации производителей, в книгах и статьях сторонних фирм и на многочисленных Web#сайтах. Инструменты интегрированы, благодаря чему вы можете разрабатывать UI, модули работы с БД, составления отчетов и бизнес#ло# гики в одной среде. Решения проблем можно легко найти в ответах на «часто за# даваемые вопросы». Кроме того, доступны разнообразные услуги консультантов и программы тренинга. В ранних средах — таких как Web#программирование в середине 1990#х — ситу# ация противоположная. Языков программирования мало, при этом они часто полны ошибок и плохо документированы. Вместо написания нового кода программис# ты тратят массу времени только на то, чтобы разобраться в особенностях языка. Бесчисленные часы уходят на борьбу с ошибками в языках, ОС и других инстру# ментах. Инструменты программирования часто примитивны. Отладчиков может не быть вообще, а об оптимизаторах компиляторов программистам приходится |