Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Клуб профессиональных программистов :: Выпуск #15




Философия ООП

Введение

Эта статья является переработкой и расширением лекции с одноимённым названием, читаемой студентам старших курсов специальности «Программное обеспечение вычислительной техники и автоматизированных систем» в рамках темы «Технологии программирования». Поэтому предполагается, что читатель хорошо знаком со структурным подходом в программировании и ориентируется в основных понятиях ООП.

До сих пор широко распространена методика преподавания программирования, предполагающая сначала освоение учащимися структурного подхода и лишь затем переход к изучению других парадигм программирования: функциональной, логической, объектно-ориентированной. Такая методика сложилась исторически; она имеет определённые преимущества и недостатки перед другими методиками. Одной из заметных объективных проблем является трудность для учащихся переходить от ставшей привычной структурной парадигмы программирования к другим, особенно к объектно-ориентированной. Если в функциональной и логической парадигмах используются специфические языки программирования, более или менее строго требующие изменение мышления программиста, то все распространённые рабочие языки ООП в своей основе имеют языковые конструкции других парадигм, в первую очередь структурной. Языковые конструкции ООП подобны надстройке над старыми языковыми конструкциями — это обстоятельство позволяет писать на объектно-ориентированных языках, используя старые подходы к программированию. У начинающего объектного программиста велик соблазн разработать программу в более привычных для него структурных понятиях. Критериями самооценки своей работы в основном являются корректность, устойчивость и быстродействие программы. В результате у учащегося формируется недопонимание ООП, возникают трудности с восприятием новых идей в ООП, закладывается основание будущих проблем с проектированием крупных программных систем, проблем его профессионального роста.

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

1 Категория компьютерной программы

Один из ключевых стереотипов мышления программиста — смысл понятия компьютерной программы, ответ на вопрос «Что такое программа?». На практике программисты часто не утруждают себя раскрытием содержания этой категории, оно кажется очевидным. Однако, как мы покажем ниже, существуют принципиально различные подходы к определению программы. Непонимание существования таких различий приводит и к недоразумениям, и к ошибкам проектирования программного обеспечения. В первой части нашей статьи мы отметим основные точки зрения на понятие программы и покажем, в чём состоит принципиальная разница между программированием в структурной и объектно-ориентированной парадигмах.

Исторически первым центральным понятием программирования был алгоритм — строгая последовательность операций, в процессе выполнения которых входные данные могут быть преобразованы в результат. Программа в сознании программиста мыслилась как реализация некоторого алгоритма. Такая точка зрения на программу была наиболее популярной до конца 1980-х годов.

После того, как появились компьютеры, хранящие программу в своей памяти, и после того, как была поставлена задача разработки языков программирования высокого уровня, появилась возможность применить в программировании теории формальной логики, например, лямбда-исчисление Чёрча и исчисление предикатов. Так последовательно появились языки для программирования с использованием функционального и логического подходов. Функциональный подход требует записи программы в виде композиции функций, при использовании логического подхода программист записывает множество фактов и правил логического вывода. Принципиальное отличие функциональных и логических программ от программ, реализующих алгоритмы, заключается в том, что эти программы описывают. Программы, реализующие алгоритмы, предписывают компьютеру выполнить некоторые действия, и потому называются императивными. Они «объясняют» компьютеру, как осуществлять вычисления, при этом то, что вычисляется, составляет входные данные и результат. Функциональные и логические программы описывают какие-либо специальные логические системы, обычно построенные в рамках каких-либо предметных областей, и потому называются декларативными. Они «объясняют» компьютеру, что является предметом вычислений, при этом компьютер заранее «знает», как выполнять вычисления. Императивные программы прямо сводятся к последовательности машинных инструкций и исполняются компьютером. Декларативные программы снабжаются особой программой-интерпретатором, которая умеет выполнять операцию редукции над элементами программы, тем самым осуществляя вычисления: пытаясь свести исходные описания к некоторому логически корректному в рамках описанной логической системы результату.

С периода массового распространения персональных компьютеров в 1980-х годах, когда работу со сложной вычислительной техникой стали осваивать широкие слои служащих в самых различных областях человеческой деятельности, всё острее вставала потребность отыскать какое-то другое центральное понятие программирования. Ранее компьютер использовался в основном как инструмент решения вычислительных задач, компьютер был дорогим и сложным устройством, с которым работали только специалисты по вычислительной технике, мало внимания уделялось вопросам человеко-машинного взаимодействия. Со временем прикладные функции компьютера расширились, он превратился в универсальное информационное устройство, умеющее не только вычислять, но и наглядно вводить, преобразовывать, сохранять, искать и визуализировать самую разнообразную информацию, устройство, с которым может работать каждый человек. Компьютер перестал восприниматься в качестве простого вычислителя, он превратился в среду решения различных и в первую очередь невычислительных прикладных задач. Вместе с изменением роли компьютеров в жизни и деятельности людей стало меняться и содержание категории компьютерной программы. Задачи организации простого и удобного человеко-машинного взаимодействия, разработка операционных оболочек и систем нового поколения с графическим интерфейсом, создание многомашинных вычислительных комплексов и АСУ породили ряд трудностей в программировании. Старые стереотипы мышления уже не годились. В процессе разрешения возникших трудностей в 1990-х годах произошёл массовый переход к ООП.

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

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

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

Можно найти заметное сходство объектов и их методов в информационной модели с предложенными Минским фреймами и их демонами, используемыми для описания знаний. Информационные модели описывают наши знания в разных предметных областях. Эти знания воплощены в особенностях структуры и поведения моделируемых систем. Информационные модели имеют такую же рекурсивную структуру, как и фреймовые сети. Это позволяет модель некоторой системы конструировать из моделей её подсистем вплоть до элементарных объектов.

В течение 1990-х годов изменилось мышление многих программистов, появилось новое видение проблем и, соответственно, принципиально новые постановки задач в программировании. Конкретный алгоритм представляет собой процесс решения какой-нибудь конкретной задачи. Будучи записанным в виде программы, он закрепляет и точку зрения на проблему, и постановку задачи решения проблемы, и выбранный метод решения. После написания программы её пользователь (в том числе и программист, использующий библиотеку подпрограмм) не может ничего сделать кроме передачи компьютеру входных данных и получения результата вычислений. В этом случае говорят, что алгоритм управляет данными. При работе с информационной моделью некоторой проблемной области пользователь ограничен лишь той точкой зрения, которой придерживался составитель модели. Как и в логических программах, постановку задач пользователь волен выбирать по своему усмотрению. Однако в отличие от логических программ пользователь информационной модели волен выбирать также и методы решения поставленных задач. Обычно работа по конструированию решений своих задач в рамках информационной модели происходит в процессе диалога с машиной. Например, в текстовом процессоре можно в произвольном порядке выполнять все доступные ему функции обработки документа: вставку и замену текста, блоковые операции, вёрстку, стилевое оформление, форматирование таблиц и т. д. И, например, в текстовом процессоре MS Word все выполненные пользователем операции могут быть сохранены в макросе — они запишутся как программа, выполнение которой можно будет впоследствии повторить. С точки зрения пользователя выполняется некоторая работа, заключающаяся в манипуляциях частями информационной модели для получения определённого результата (например, подготовки какого-либо документа). Все манипуляции производятся пользователем на понятом для него языке — языке предметной области. В то же время с точки зрения компьютерной программы все эти действия представляют собой алгоритм решения задачи пользователем. Этот алгоритм образуется динамически, прямо в процессе диалога с пользователем, он заранее не заложен в программу. Наверняка такой алгоритм не будет эффективным, будет содержать различные лишние действия, все этапы раздумий, сомнений и колебаний пользователя в процессе выработки решения, однако всё равно он будет оставаться алгоритмом — одним из возможных способов получения желаемого пользователем результата. Новые компьютерные программы состоят не из готовых алгоритмов, а из возможностей их конструирования пользователем или другим программистом. В этом случае говорят, что данные управляют алгоритмом.

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

Было бы неправильно утверждать, что описанный выше новый подход к программированию возможен исключительно в рамках ООП. Отдельные элементы этого подхода возможны и при использовании других парадигм программирования. В конце концов всё равно любая программа для современных компьютеров сводится к чёткой последовательности выполнения машинных инструкций, к некоторому заранее неизвестному алгоритму. Однако определённо то, что понимание нового подхода к программированию широко распространилось именно с развитием ООП. Основные понятия этой парадигмы определили новый способ мышления программиста. Использование объектно-ориентированного подхода позволило справиться с рядом проблем индустрии разработки программного обеспечения. Ранее многие программы создавались «с нуля», повторное использование библиотек подпрограмм было затруднено однозначностью записанных в них алгоритмов, иной раз используемых лишь однократно. Такой подход был дорогостоящим, многие ранее сделанные наработки не могли быть применены в новых проектах. Методология ООП позволила создавать достаточно универсальные библиотеки классов объектов, чтобы их можно было многократно и различными способами использовать при решении многих задач. Это привело к снижению стоимости разработок, ускорению выхода новых программных продуктов, созданию более сложных устойчивых программных систем и бурному развитию отрасли.

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

Продолжение следует

30 июля 2006 года
Dimka


А теперь прощаемся с Вами до следующего выпуска.

                                        С уважением, команда Клуба.




В избранное