Глава 7
Объектно-ориентированное
программирование
Как вы знаете, работа первых компьютеров сводилась к вычислениям по заданным формулам различной сложности. Число переменных и массивов в программе было невелико, так что программист мог легко удерживать в памяти все взаимосвязи между ними и детали алгоритма.
С каждым годом производительность компьютеров росла, и человек «поручал» им всё более и более трудоёмкие задачи. Компьютеры следующих поколений стали использоваться для создания сложных информационных систем (например, банковских) и моделирования процессов, происходящих в реальном мире. Новые задачи требовали более сложных алгоритмов, объём программ вырос до сотен тысяч и даже миллионов строк, число переменных и массивов измерялось в тысячах.
Программисты столкнулись с проблемой сложности, которая превысила возможности человеческого разума. Один человек уже не способен написать надёжно работающую серьезную программу, так как не может «охватить взглядом» все её детали. Поэтому в разработке большинства современных программ принимает участие множество специалистов. При этом возникает новая проблема: нужно разделить работу между ними так, чтобы каждый мог работать независимо от других, а потом готовую программу можно было бы собрать вместе из готовых блоков, как из кубиков.
Как отмечал известный нидерландский программист Эдсгер Дейкстра, человечество ещё в древности придумало способ управления сложными системами: «разделяй и властвуй». Это означает, что исходную систему нужно разбить на подсистемы (выполнить декомпозицию) так, чтобы работу каждой из них можно было рассматривать и совершенствовать независимо от других.
Для этого в классическом (процедурном) программировании используют метод проектирования «сверху вниз»: сложная задача разбивается на части (подзадачи и соответствующие им алгоритмы), которые затем снова разбиваются на более мелкие подзадачи и т. д. (рис. 7.1). Однако при этом задачу «реального мира» приходится переформулировывать, представляя все данные в виде переменных, массивов, списков и других структур данных. При моделировании больших систем объём этих данных увеличивается, они становятся плохо управляемыми, и это приводит к большому числу ошибок. Так как любой алгоритм может обратиться к любым глобальным (общедоступным) данным, повышается риск случайного недопустимого изменения каких-то значений.
В конце 60-х годов XX века появилась новая идея — применить в разработке программ тот подход, который использует человек в повседневной жизни. Люди воспринимают мир как множество объектов — предметов, животных, людей — это отмечал ещё в XVII веке французский математик и философ Рене Декарт. Все объекты имеют внутреннее устройство и состояние, свойства (внешние характеристики) и поведение. Чтобы справиться со сложностью окружающего мира, люди часто не вникают в детали внутреннего устройства и игнорируют многие свойства объектов, ограничиваясь лишь теми, которые необходимы для решения их практических задач. Такой приём называется абстракцией.
Абстракция — это выделение существенных характеристик объекта, отличающих его от других объектов.
Для разных задач существенные свойства одного и того же объекта могут быть совершенно разными. Например, услышав слово «кошка», многие подумают о пушистом усатом животном, которое мурлыкает, когда его гладят. В то же время ветеринарный врач представляет скелет, ткани и внутренние органы кошки, которую ему нужно лечить. В каждом из этих случаев применение абстракции даёт свою модель одного и того же объекта, поскольку различны цели моделирования.
Как применить принцип абстракции в программировании? Поскольку формулировка задач, решаемых на компьютерах, всё более приближается к формулировкам реальных жизненных задач, возникла такая идея: представить программу в виде множества объектов (моделей), каждый из которых обладает своими свойствами и поведением, но его внутреннее устройство скрыто от других объектов. Тогда решение задачи сводится к моделированию взаимодействия этих объектов. Построенная таким образом модель задачи называется объектной. Здесь тоже идёт проектирование «сверху вниз», только не по алгоритмам (как в процедурном программировании), а по объектам. Если нарисовать схему такой декомпозиции, она будет представлять собой граф, так как каждый объект может обмениваться данными со всеми другими (рис. 7.2).
Здесь А, Б, В и Г — объекты «верхнего уровня»; Бг, Б2 и Б3 — под объекты объекта Б и т. д.
Для решения задачи «на верхнем уровне» достаточно определить, что делает тот или иной объект, не заботясь о том, как именно он это делает. Таким образом, для преодоления сложности мы используем абстракцию, т. е. сознательно отбрасываем второстепенные детали.
Если построена объектная модель задачи (выделены объекты и определены правила обмена данными между ними), можно поручить разработку каждого из объектов отдельному программисту (или группе), которые должны написать соответствующую часть программы, т. е. определить, как именно объект выполняет свои функции. При этом конкретному разработчику не обязательно держать в голове полную информацию обо всех объектах, нужно лишь строго соблюдать соглашения о способе обмена данными (интерфейсе) «своего» объекта с другими.
Программирование, основанное на моделировании задачи реального мира как множества взаимодействующих объектов, принято называть объектно-ориентированным программированием (ООП). Более строгое определение мы дадим немного позже.
© Вопросы и задания
1. Почему со временем неизбежно изменяются методы программирования?
2. Что такое декомпозиция, зачем она применяется?
3. Что такое процедурное программирование? Какой вид декомпозиции в нём используется?
4. Какие проблемы в программировании привели к появлению ООП?
5. Как выполняется декомпозиция алгоритмов в процедурных языках программирования?
6. Что такое абстракция? Зачем она используется в обычной жизни?
7. Объясните, как связана абстракция с моделированием.
8. Какие преимущества даёт объектный подход в программировании?
9. Какой вид декомпозиции используется в ООП?
10. Что такое интерфейс? Приведите примеры объектов, у которых одинаковый интерфейс и разное устройство.
Подготовьте сообщение
а) «Проблемы процедурного программирования»
б) «Глобальные переменные: за и против»
в) «ООП: достоинства и недостатки»