Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Штерн В. - Основы C++. Методы программной инженерии - 2003

.pdf
Скачиваний:
238
Добавлен:
13.08.2013
Размер:
28.32 Mб
Скачать

ЧЛОУМЬ I

ведение в программирование

на C++

Прования. Но что это означает? Для чего используется объектно-ориен­ тированный язык? Чем он лучше традиционного, не объектно-ориентированного?

ервая часть этой книги посвящена основам программирования на С+ + .

Как известно, С+Н объектно-ориентированный язык программи­

На что нужно обращать внимание при программировании, чтобы реализовать преимущества объектно-ориентированного подхода (ООП)? Часто такой подход воспринимается как нечто само собой разумеющееся, что снижает эффективность его использования.

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

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

Вглаве 2 содержится краткое введение в язык C+ + , включая описания объек­ тов. Оно дает представление о предмете в общих чертах. Детали читатели найдут

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

Вдругих главах части I представлены базовые не объектно-ориентированные средства языка. Особое внимание уделяется написанию повторно используемого и удобного в сопровождении программного кода. Для каждой конструкции C+ + поясняется, как ее следует и как не следует применять. Хотя об объектах речи еще не идет, эти главы уже достаточно сложны, особенно глава 6, рассказываю­

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

£Г^^^^1

о.бъектнО'Ориентированный подход: что это такое?

Темы данной главы

•^ Истоки кризиса программного обеспечения | / Выход первый: избавиться от программистов

«^ Выход второй: усовершенствование методов управления

^Выход третий: разработка сложного и подробного языка

«^ Объектно-ориентированный подход: что он дает и какой ценой?

^Характеристики языка программирования С++

^Итоги

Объектно-ориентированный подход захватывает все области разработки программного обеспечения. Он открывает новые горизонты и дает новые преимущества. Многие разработчики воспринимают эти преимущества как нечто само собой разумеющееся, считают их важными и существенными. Но

что это такое на самом деле? Достигаются ли они автоматически, лишь потому, что в программе применяются объекты, а не функции?

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

Тем же, у кого относительно мало опыта, лучше познакомиться с обсуждением кризиса ПО и способов выхода из него. Это поможет лучше понять, в каком кон­ тексте следует воспринимать предлагаемые в данной книге методы программиро­ вания. Читатели узнают, какие приемы программирования на C++ повышают качество программы, а какие наоборот и почему.

Учитывая обилие некачественного программного кода на C+ + , это очень важно. Многие программисты полагают, что одно лишь применение C + + и его классов дает все связанные с ними преимущества. Это не так. К сожалению, в большинстве книг по C + + поддерживается данное некорректное утверждение и подобное восприятие C+ + , а все внимание концентрируется на синтаксисе языка. Авторы предпочитают не обсу>кдать качество программного кода на C+ + , но если разработчики не знают, каковы цели C + + , они станут писать объектноориентированные программы по-старому. Подобные программы будут не лучше, чем традиционные программы на С, PL/l (или другом подобном языке), а их труд­ но сопровождать.

• 1

Часть ! ^ ВшвА^итв в щ>€У1-:-^:^-^^-тп^::^шмтв на С4-+

Истоки кризиса программного обеспечения

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

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

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

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

Сравним все это с индустрией разработки ПО. О стандартах здесь речи нет.

Конечно, профессиональные организации

стараются сделать все возможное

и выпускают различные стандарты — от

спецификаций тестирования ПО до

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

Все продукты — ручной сборки. Готовых, стандартных компонентов нет. Нет

иуниверсального общепринятого соглашения по таким продуктам и компонентам.

Всудебном деле правительства США против Microsoft обвинение и защита долго

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

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

Глава 1 • Объектно-ориентировонный подход: что это такое?

Программисты

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

Лишь немногие программные системы настолько просты, что спецификацию для них может разработать один человек, реализовать их по данной спецификации и использовать для задуманной цели, а также сопровождать, внося изменения при появлении новых требований или обнаружении ошибок. Подобные простые систе­ мы достаточно ограничены по своему применению и живут относительно недолго. При необходимости их можно просто выбросить и начать все сначала. Инвестиции (время/деньги) невелики, и программы нетрудно переписать заново.

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

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

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

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

Шаг 2

Операция N

щл

Операция 1

 

Шаг1

 

 

ШагМ

^

программисты

Рис. 1.1. Разбиение системы на компоненты

Часть i ^ Введение в прогрор/тироваишв но C-f-i-

ошибок такие системы нельзя просто заменить или выбросить — слишком много средств в них вложено.

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

Здесь также уместно вспомнить о Проблеме 2000 г. Многих удивлял тот факт, что для представления года программисты использовали только две цифры. "В каком мире они живут,— интересовалась публика.— Неужели не понимают, какие последствия повлечет изменение даты с 1999 на 2000 г.?" Да, это и впрямь удивительно, но удивляет вовсе не недальновидность программистов, а срок жизни систем, созданных в 70-е и 80-е годы. Программисты понимали проблему 2000-го не хуже любого эксперта по Y2K (или даже лучше), но они и думать не могли, что кто-то будет использовать их программы через 20—30 лет.

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

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

Сложность системных задач (проблемной области), будь то инженерная задача, деловые операции, Интернет-приложение или готовое ПО для массового рынка, затрудняет описание системы и реализуемых ею функций для конечного пользова­ теля. Потенциальные пользователи системы (или специалисты ло маркетингу) не всегда в состоянии выразить свои требования в форме, понятной разработчикам ПО. Требования часто исходят от пользователей разных категорий и противоречат друг другу. Выявление и согласование всех расхождений — непростая задача. Кроме того, потребности пользователей и маркетологов со временем меняются, а иногда это происходит уже на этапе формулирования требований, и тогда в ходе обсуждения деталей, относящихся к работе системы, ро>едаются новые идеи. Вот почему программисты говорят, что пользователи (и специалисты по маркетингу) не знают, чего хотят. Инструментальных средств дая работы с предъявляемыми к системе требованиями очень мало, а потому на выходе нередко получаются целые тома текста с чертежами. Этот текст часто плохо структурирован, и разо­ браться в нем нелегко. Многие положения весьма туманны, неполны, противоре­ чивы и не поддаются однозначной интерпретации.

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

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

Глава 1 • Обьектно-ориентароеанный подход: что это такое?

 

ФУНКЦИОНАЛЬНОСТЬ

 

Создание ПО из отдельных имеющихся компо­

 

 

 

 

 

 

 

 

нентов только добавляет проблем: это требует вре­

 

с^ ^ '^^ ^

 

 

мени и порождает новые ошибки. Тестирование

 

 

 

 

таких систем затруднительно, оно ненадежно и тре­

 

 

 

 

бует "ручных" операций.

 

 

 

 

 

Когда я приехал в США, мой босс Джон Конвей

 

 

 

 

пояснил ситуацию следующим образом. Он нарисо­

 

 

 

 

вал треугольник, вершины которого представляют

AS'

о"

 

 

такие характеристики проекта, как сроки,

бюджет

 

 

 

 

 

 

 

 

и функциональность системы (рис. 1.2).

"Мы не

Qi

 

 

 

можем добиться всех трех целей,— сказал он.—

 

 

 

Если реализовать все функции системы согласно

^

Проект реализован в срок,

#

%

бюджет соблюден, но реализованы

бюджету, то работу невозможно будет завершить

 

не все задуманные функции

 

вовремя, потребуется перенос сроков. Если 'же

Рис. 1.2. Шагичгский

треугольник

 

реализовать функции в соответствии со сроками,

 

программных

проектов

 

то, скорее всего, бюджет придется перерасходовать

 

 

 

 

понадобятся дополнительные ресурсы. Когда соблю­

 

даются сроки и бюджет (что случается нечасто, но возможно), то придется пожерт­

 

вовать некоторыми функциями и воплотить только часть обещанного".

 

 

С этой проблемой уже давно сталкивается индустрия ПО. Впервые о кризисе

 

ПО

заговорили в

1968 г. В последующие годы отрасль разработала несколько

 

подходов к решению проблемы. Ниже мы вкратце рассмотрим их.

 

Выход первый: избавиться от программистов

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

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

Аналогично программисты нередко не понимали целей пользователей, их пред­ положений и ограничений. В результате заказчики ПО получали не совсем то, что они хотели.

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

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

врезультате.

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

Схема взаймов ейст^вия разработпчика и пользователя

t

Часть I« Введение в програ1У1Ш1ирование на С-

 

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

Программист

 

 

 

Пользователь

Рис. 1.3.

Схема

взаимодействия

 

пользователя

и

'разработчика

Программисты

Рис. 1.4

Фактически схема, приведенная на рис. 1.3, справедлива только для небольших программ. Для более крупных программных проектов картина будет выглядеть так, как показано на рис. 1.4. Проблемы взаимопонимания межлу пользователями и разработчиками действитель­ но важны, но не менее важно и взаимопони­ мание между самими разработчиками. Если что-то будет понято не так, то, кем бы ни были

Пользователи разработчики — профессиональными програм­ мистами, инженерами или менеджерами,—

неизбежны ошибки.

Даже рис. 1.4 дает упрош,енную картину. Здесь показано лишь несколько пользователей, специфицируюш,их требования и оцениваюш.их

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

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

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

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

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

Глава 1 • Объектно-ориентированный подход: что это такое?

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

Выход второй; совершенствование методов управления

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

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

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

Чтобы содействовать взаимодействию между пользователями и разработчика­ ми, применяются следуюш,ие два метода:

Метод ''водопада" (waterfall) — разделение процесса разработки на отдельные стадии)

Быстрое прототипирование —(частичная реализация системы для получения отзывов пользователей)

Метод ^^водопада''

Есть несколько вариантов такого подхода к управлению программными проек­ тами. Все они включают в себя разбиение процесса на последовательные стадии. Типичная последовательность стадий такова: определение требований, анализ системы, проектирование архитектуры, детальное проектирование, реализация, тестирование модулей, интеграционное тестирование, приемочное тестирование и сопровождение. Обычно каждую стадию реализует отдельная команда разработ­ чиков. После опытной эксплуатации и анализа полезности системы составляется новый набор требований (или поправки) и последовательность стадий может повторяться.

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

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

Соседние файлы в предмете Программирование на C++