ПОЧУВСТВУЙ КЛАСС Bertrand Meyer TOUCH OF CLASS Learning to Programm Well with Objects and Contracts Бертран Мейер ПОЧУВСТВУЙ КЛАСС Учимся программировать хорошо с объектами и контрактами Перевод с английского под редакцией к.т.н. В.А. Биллига Национальный Открытый БИНОМ. Университет «ИНТУИТ» Лаборатория знаний www.intuit.ru www.lbz.ru Москва 2011 УДК 004.42(07) ББК 32.973.26-018я7 М45 Мейер Б. М45 Почувствуй класс / Мейер Б.; пер. с англ. под ред. В.А. Биллига.—М.: Национальный Открытый Университет «ИНТУИТ»: БИНОМ. Лаборатория знаний, 2011. —775 с.: ил., табл. ISBN 978-5-9963-0573-5 В книге обобщен многолетний опыт обучения программированию в ETH, Цюрих. В ней удачно сочетаются три грани, характерные для профессионального программирования, – наука, искусство и инженерия. Она в первую очередь ориентирована на студентов, обучающихся в обла- сти информационных технологий, и их преподавателей, но представляет несомненный интерес для всех программистов, создающих программный продукт высокого качества. В книге излагаются основы объектно-ориентированного программирования (ООП). Осо- бое внимание уделяется корректности программ за счет введения контрактов – предусловий, по- стусловий методов класса, инвариантов классов. Глубоко и подробно рассматриваются такие меха- низмы ООП, как наследование и универсальность. Изучаются алгоритмы и структуры данных – массивы, кортежи, списки, хэш-таблицы, различные виды распределителей, деревья. Подробно рассматриваются рекурсивные алгоритмы и рекурсивные структуры данных. Даются основы лямбда-исчисления и вводятся агенты, поддерживающие функциональный тип данных. Язык Eiffel используется как рабочий язык программирования. Книга содержит предисловие и шесть частей. Шестая часть содержит пять приложений, в которых дается сравнительный анализ языков программирования – Java, C#, C++, C. УДК 004.42(07) ББК 32.973.26-018я7 Полное или частичное воспроизведение или размножение каким-либо способом, в том числе и публикация в Сети, настоящего издания допускается только с письменного разрешения Национального Открытого Университета «ИНТУИТ». По вопросам приобретения обращаться: «БИНОМ. Лаборатория знаний» Телефон (499) 157-1902, (499) 157-5272, e-mail: [email protected], http://www.Lbz.ru © Springer Verlag, 2009 © Мейер Б., 2011 © Русский перевод. Национальный Открытый ISBN 978-5-9963-0573-5 Университет «ИНТУИТ», 2011 Об авторе Бертран Мейер, став преемником Николаса Вирта, с 2003 года возглавляет знаменитую кафе- дру Software Engineering в ETH, Цюрих, – в одном из старейших университетов Европы. Он автор языка Eiffel, основатель и научный руководитель фирмы Eiffel Software (www.eiffel.com). Бертран Мейер внес неоценимый вклад в развитие теории, практики и технологии объ- ектно-ориентированного программирования. За свою книгу Object-Oriented Software Construction, которая по праву считается библией ОО-программирования, он получил пре- мию JOLT. За заслуги в этой области стал первым лауреатом престижной премии Дала-Ни- гарда (авторов первого ОО языка – Симулы). Технология «проектирования по контракту» (Design by Contract), предложенная Бертра- ном Мейером и в полной мере реализованная в языке Eiffel и в среде разработки EiffelStudio, оказала серьезное влияние на повышение общего качества программных продуктов в совре- менной индустрии ПО. Бертран Мейер – автор многочисленных научных работ, серии книг (три его книги пере- ведены на русский язык), организатор конференций, редактор журнала по ООП, лауреат премий ACM, Mills и других. Давняя дружба связывает его с Российским программистским сообществом. В молодые годы он проходил стажировку в Академгородке у А.П. Ершова, является почетным доктором Санкт-Петербургского государственного университета ИТМО. В предлагаемой читателю книге обобщен опыт восьмилетнего обучения программирова- нию в ETH. Как сформулировал автор, цель этой книги – не просто дать основы инженерии программ и получить опыт создания работающих программ, но показать красоту принци- пов, методов, алгоритмов, структур данных и других определяющих дисциплину инструментов. И, может быть, самая главная цель – привить чувство, заставляющее вас де- лать не просто хорошее ПО, а выдающееся, и стремление создавать программы высочай- шего качества. Оглавление Доступные ресурсы 13 Предисловие редактора перевода 15 Так учат в ETH 15 Предисловие автора к русскому изданию 18 Предисловия 20 Предисловие для студентов 21 Программное обеспечение (ПО, software) повсюду 21 Любительская и профессиональная разработка ПО 22 Предшествующий опыт 22 Современная технология ПО 23 Объектно-ориентированное конструирование ПО 24 Формальные методы 24 Учимся, создавая 24 От потребителя к поставщику 25 Абстракция 26 Цель: качество 26 Предисловие для преподавателей 28 Вызовы первого курса 28 Извне – Внутрь: Обращенный учебный план 31 Выборы технологий 34 Насколько формально? 40 Другие подходы 41 Покрытие тем 42 Благодарности 44 Литература 47 Заметки для преподавателей: что читать студентам? 48 Оглавление 7 Часть I Основы 51 1 Индустрия чистых идей 51 1.1. Их машины и наши 51 1.2. Общие установки 53 1.3. Ключевые концепции, изученные в этой главе 59 2 Работа с объектами 62 2.1. Текст класса 62 2.2. Объекты и вызовы 64 2.3. Что такое объект? 70 2.4. Методы с аргументами 74 2.5. Ключевые концепции, изученные в этой главе 76 3 Основы структуры программ 79 3.1. Операторы (instructions) и выражения 79 3.2. Синтаксис и семантика 80 3.3. Языки программирования, естественные языки 81 3.4. Грамматика, категории, образцы 82 3.5. Вложенность и структура синтаксиса 83 3.6. Абстрактные синтаксические деревья 84 3.7. Лексемы и лексическая структура 86 3.8. Ключевые концепции, изученные в этой главе 88 4 Интерфейс класса 90 4.1. Интерфейсы 90 4.2. Классы 92 4.3. Использование класса 93 4.4. Запросы 97 4.5. Команды 101 4.6. Контракты 102 4.7. Ключевые концепции, изученные в этой главе 108 5 Немного логики 111 5.1. Булевские операции 112 5.2. Импликация 120 5.3. Полустрогие булевские операции 124 5.4. Исчисление предикатов 128 5.5. Дальнейшее чтение 133 5.6. Ключевые концепции, изучаемые в этой главе 133 6 Создание объектов и выполняемых систем 138 6.1. Общие установки 138 6.2. Сущности и объекты 140 6.3. VOID-ссылки 141 6.4. Создание простых объектов 147 6.5. Процедуры создания 151 6.6. Корректность оператора создания 155 8 Почувствуй класс 6.7. Управление памятью и сборка мусора 157 6.8. Выполнение системы 158 6.9. Приложение: Избавление от void-вызовов 164 6.10. Ключевые концепции, изучаемые в этой главе 165 7 Структуры управления 167 7.1 Структуры для решения задач 167 7.2. Понятие алгоритма 168 7.3. Основы структур управления 172 7.4. Последовательность (составной оператор) 174 7.5. Циклы 178 7.6. Условные операторы 196 7.7. Низкий уровень: операторы перехода 203 7.8. Исключение GOTO и структурное программирование 206 7.9. Вариации базисных структур управления 211 7.10. Введение в обработку исключений 218 7.11. Приложение: Пример удаления GOTO 223 7.12. Дальнейшее чтение 225 7.13. Ключевые концепции, изучаемые в этой главе 226 8 Подпрограммы, функциональная абстракция, скрытие информации 229 8.1. Выводимость «снизу вверх» и «сверху вниз» 229 8.2. Подпрограммы как методы (routines as features) 230 8.3. Инкапсуляция (скрытие) функциональной абстракции 231 8.4. Анатомия объявления метода 232 8.5. Скрытие информации 234 8.6. Процедуры против функций 236 8.7. Функциональная абстракция 236 8.8. Использование методов 237 8.9. Приложение: Доказательство неразрешимости проблемы остановки 238 8.10. Дальнейшее чтение 240 8.11. Ключевые концепции, изученные в этой главе 240 9 Переменные, присваивание и ссылки 242 9.1. Присваивание 243 9.2. Атрибуты 250 9.3. Виды компонентов класса (features) 256 9.4. Сущности и переменные 260 9.5. Ссылочное присваивание 262 9.6. Программирование со ссылками 265 9.7. Ключевые концепции, изучаемые в этой главе 276 Часть II Как все устроено 279 10 Немного об аппаратуре 279 10.1. Кодирование данных 280 10.2. О памяти 287 Оглавление 9 10.3. Команды компьютера 292 10.4. Закон Мура и эволюция компьютеров 294 10.5. Дальнейшее чтение 294 10.6. Ключевые концепции, изученные в этой главе 295 11 Описание синтаксиса 298 11.1. Роль БНФ 298 11.2. Продукции 302 11.3. Использование БНФ 306 11.4. Описание абстрактного синтаксиса 309 11.5. Превращение грамматики в анализатор 311 11.6. Лексический уровень и регулярные автоматы 311 11.7. Дальнейшее чтение 318 11.8. Ключевые концепции, изучаемые в этой главе 318 12 Языки программирования и инструментарий 320 12.1. Стили языков программирования 321 12.2. Компиляция против интерпретации 329 12.3. Основы компиляции 334 12.4. Верификация и проверка правильности 340 12.5. Текстовые редакторы на этапах проектирования и программирования 340 12.6. Управление конфигурацией 342 12.7. Репозиторий проекта «в целом» 349 12.8. Просмотр и документирование 349 12.9. Метрики 350 12.10. Интегрированная среда разработки 350 12.11. IDE: EiffelStudio 351 12.12. Ключевые концепции, введенные в этой главе 356 Часть III Алгоритмы и структуры данных 358 13 Фундаментальные структуры данных, универсальность и сложность алгоритмов 358 13.1. Статическая типизация и универсальность 359 13.2. Контейнерные операции 365 13.3. Оценка алгоритмической сложности 370 13.4. Массивы 373 13.5. Кортежи 381 13.6. Списки 383 13.7. Связные списки 391 13.8. Другие варианты списков 398 13.9. Хеш-таблицы 401 13.10. Распределители 407 13.11. Стеки 409 13.12. Очереди 416 13.13. Итерирование структуры данных 418 13.14. Другие структуры 420 13.15. Дальнейшее чтение 420 10 Почувствуй класс 13.16. Ключевые концепции этой главы 421 14 Рекурсия и деревья 423 14.1. Основные примеры 424 14.2. Ханойская башня 429 14.3. Рекурсия как стратегия решения задач 433 14.4. Бинарные деревья 434 14.5. Перебор с возвратами и альфа-бета 446 14.6. От циклов к рекурсии 455 14.7. Понимание рекурсии 457 14.8. Контракты рекурсивных программ 466 14.9. Реализация рекурсивных программ 468 14.10. Ключевые концепции, рассмотренные в этой главе 479 15 Проектирование и инженерия алгоритма: топологическая сортировка 484 15.1. Постановка задачи 484 15.2. Основы топологической сортировки 487 15.3. Практические соображения 495 15.4. Базисный алгоритм 502 15.5. Уроки 515 15.6. Ключевые концепции этой главы 518 15.7. Приложение. Терминологические замечания об отношениях порядка 519 Часть IV Объектно-ориентированные приемы программирования 522 16 Наследование 522 16.1. Такси и транспортные средства 524 16.2. Полиморфизм 528 16.3. Динамическое связывание 532 16.4. Типизация и наследование 533 16.5. Отложенные классы и компоненты 535 16.6. Переопределение 540 16.7. За пределами скрытия информации 543 16.8. Беглый взгляд на реализацию 544 16.9. Что происходит с контрактами? 549 16.10. Общая структура наследования 554 16.11. Множественное наследование 555 16.12. Универсальность плюс наследование 561 16.13. Обнаружение фактического типа 565 16.14. Обращение структуры: посетители и агенты 571 16.15. Дальнейшее чтение 578 16.16. Ключевые концепции этой главы 578 17 Операции как объекты: агенты и лямбда-исчисление 583 17.1. За пределами двойственности 583