Объектно-ориентированное программирование

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

1.5.2. Как избежать бесконечной регрессии

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

В языках, где директивный и объектно-ориентированный подходы уживаются вместе(таких, какC++, Object Pascal иObjective-C), реальные действия выполняются методами, написанными на основном(не объектно-ориентированном) языке. В чисто  объектно- ориентированных языках(таких, какSmalltalk иJava) это выполняется с помощью «примитивных» или «встроенных» операций, которые обеспечиваются исполнительной системой более низкого уровня.

1.6. Барьер сложности

 

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

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

1.6.1. Нелинейное увеличение сложности

По мере того как программные проекты становились все сложнее, было замечено интересное явление. Задача, для решения которой одному программисту требовалось два месяца, не решалась двумя программистами за месяц. Согласно замечательной фразе Фреда Брукса,  «рождение ребенка занимает девять месяцев независимо от того, сколько женщин занято этим» [Brooks 1975].

Причиной такого нелинейного поведения является сложность. В частности, взаимосвязи между программными компонентами стали сложнее, и разработчики вынуждены были постоянно обмениваться между собой значительными объемами информации. Брукс также сказал:

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

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

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

 

1.6.2. Механизмы абстрагирования

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

Главный из них — это абстрагирование, то есть способность отделить логический смысл фрагмента программы от проблемы его реализации. В некотором смысле  объектно-