OOP, OOD и ООА
Унаследовав от многих предшественников, объектный подход, к сожалению, перенял и запутанную терминологию. Программист в Smalltalk пользуется термином метод, в C++ - термином виртуальная функция, в CLOS - обобщенная функция.
Рис. 2-5. Топология больших приложений в объектных и объектно-ориентированных языках.
В Object Pascal используется термин приведение типов, а в языке Ada то же самое называется преобразование типов. Чтобы уменьшить путаницу, следует определить, что является объектно-ориентированным, а что - нет. Определение наиболее употребительных терминов и понятий вы найдете в глоссарии в конце книги.
Термин объектно-ориентированный, по мнению Бхаскара, "затаскан до потери смысла, как "материнство", "яблочный пирог" и "структурное программирование"" [7]. Можно согласиться, что понятие объекта является центральным во всем, что относится к объектно-ориентированной методологии. В главе 1 мы определили объект как осязаемую сущность, которая четко проявляет свое поведение. Стефик и Бобров определяют объекты как "сущности, объединяющие процедуры и данные, так как они производят вычисления и сохраняют свое локальное состояние" [8]. Определение объекта как сущности в какой-то мере отвечает на вопрос, но все же главным в понятии объекта является объединение идей абстракции данных и алгоритмов. Джонс уточняет это понятие следующим образом: "В объектном подходе акцент переносится на конкретные характеристики физической или абстрактной системы, являющейся предметом программного моделирования... Объекты обладают целостностью, которая не должна - а, в действительности, не может - быть нарушена. Объект может только менять состояние, вести себя, управляться или становиться в определенное отношение к другим объектам. Иначе говоря, свойства, которые характеризуют объект и его поведение, остаются неизменными. Например, лифт характеризуется теми неизменными свойствами, что он может двигаться вверх и вниз, оставаясь в пределах шахты...
Любая модель должна учитывать эти свойства лифта, так как они входят в его определение" [32].
Основные положения объектной модели Йонесава и Токоро свидетельствуют: "термин "объект" появился практически независимо в различных областях, связанных с компьютерами, и почти одновременно в начале 70-х годов для обозначения того, что может иметь различные проявления, оставаясь целостным. Для того, чтобы уменьшить сложность программных систем, объектами назывались компоненты системы или фрагменты представляемых знании" [9]. По мнению Леви, объектно-ориентированный подход был связан со следующими событиями: "прогресс в области архитектуры ЭВМ; развитие языков программирования, таких как Simula, Smalltalk, CLU, Ada; развитие методологии программирования, включая принципы модульности и скрытия данных" [10]. К этому еще следует добавить три момента, оказавшие влияние на становление объектного подхода: развитие теории баз данных; исследования в области искусственного интеллекта; достижения философии и теории познания. Понятие "объект" впервые было использовано более 20 лет назад при конструировании компьютеров с descriptor-based и capability-based архитектурами [11]. В этих работах делались попытки отойти от традиционной архитектуры фон Неймана и преодолеть барьер между высоким уровнем программной абстракции и низким уровнем ЭВМ [12]. По мнению сторонников этих подходов, тогда были созданы более качественные средства, обеспечивающие: лучшее выявление ошибок, большую эффективность реализации программ, сокращение набора инструкций, упрощение компиляции, снижение объема требуемой памяти. Ряд компьютеров имеет объектно-ориентированную архитектуру: Burroughs 5000, Plessey 250, Cambridge CAP [13], SWARD [14], Intel 432 [15], Caltech's СОМ [16], IBM System/38 [17], Rational R1000, BiiN 40 и 60. С объектно-ориентированной архитектурой тесно связаны объектно-ориентированные операционные системы (ОС). Дейкстра, работая над мультипрограммной системой THE, впервые ввел понятие машины с уровнями состояния в качестве средства построения системы [18]. Среди первых объектно-ориентированных ОС следует отметить: Plessey/System 250 (для мультипроцессора Plessey 250), Hydra (для CMU C.mmp), CALTSS (для CDC 6400), CAP (для компьютера Cambridge CAP), UCLA Secure UNIX (для PDP 11/45 и 11/70), StarOS (для CMU Cm*), Medusa (также для CMU Cm*) и iMAX (для Intel 432) [19]. Следующее поколение операционных систем, таких, как Microsoft Cairo и Taligent Pink, будет, по всей видимости, объектно-ориентированным. Наиболее значительный вклад в объектный подход внесен объектными и объектно-ориентированными языками программирования. Впервые понятия классов и объектов введены в языке Simula 67. Система Flex и последовавшие за ней диалекты Smalltalk-72, -74, -76 и, наконец, -80, взяв за основу методы Simula, довели их до логического завершения, выполняя все действия на основе классов. В 1970-х годах создан ряд языков, реализующих идею абстракции данных: Alphard, CLU, Euclid, Gypsy, Mesa и Modula. Затем методы, используемые в языках Simula и Smalltalk, были использованы в традиционных языках высокого уровня. Внесение объектно-ориентированного подхода в С привело к возникновению языков C++ и Objective С. На основе языка Pascal возникли Object Pascal, Eiffel и Ada. Появились диалекты LISP, такие, как Flavors, LOOPS и CLOS (Common LISP Object System), с возможностями языков Simula и Smalltalk. Более подробно особенности этих языков изложены в приложении. Первым, кто указал на необходимость построения систем в виде структурированных абстракций, был Дейкстра. Позднее Парнас ввел идею скрытия информации [20], а в 70-х годах ряд исследователей, главным образом Лисков и Жиль [21], Гуттаг [22], и Шоу [23], разработал механизмы абстрактных типов данных. Хоар дополнил эти подходы теорией типов и подклассов [24]. Развивавшиеся достаточно независимо технологии построения баз данных также оказали влияние на объектный подход [25], в первую очередь благодаря так называемой модели "сущность-отношение" (ER, entity-relationship) [26]. В моделях ER, впервые предложенных Ченом [27], моделирование происходит в терминах сущностей, их атрибутов и взаимоотношений. Разработчики способов представления данных в области искусственного интеллекта также внесли свой вклад в понимание объектно-ориентированных абстракций. В 1975 г. Мински выдвинул теорию фреймов для представления реальных объектов в системах распознавания образов и естественных языков [28]. Фреймы стали использоваться в качестве архитектурной основы в различных интеллектуальных системах. Объектный подход известен еще издавна. Грекам принадлежит идея о том, что мир можно рассматривать в терминах как объектов, так и событий. А в XVII веке Декарт отмечал, что люди обычно имеют объектно-ориентированный взгляд на мир [29]. В XX веке эту тему развивала Рэнд в своей философии объективистской эпистемологии [30]. Позднее Мински предложил модель человеческого мышления, в которой разум человека рассматривается как общность различно мыслящих агентов [31]. Он доказывает, что только совместное действие таких агентов приводит к осмысленному поведению человека. |
Объектно-ориентированное программирование. Что же такое объектно-ориентированное программирование (object-oriented programming, OOP)? Мы определяем его следующим образом:
Объектно-ориентированное программирование - это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.
В данном определении можно выделить три части: 1) OOP использует в качестве базовых элементов объекты, а не алгоритмы (иерархия "быть частью", которая была определена в главе 1); 2) каждый объект является экземпляром какого-либо определенного класса; 3) классы организованы иерархически (см. понятие об иерархии "is а" там же). Программа будет объектно-ориентированной только при соблюдении всех трех указанных требований. В частности, программирование, не основанное на иерархических отношениях, не относится к OOP, а называется программированием на основе абстрактных типов данных.
В соответствии с этим определением не все языки программирования являются объектно-ориентированными. Страуструп определил так: "если термин объектно-ориентированный язык вообще что-либо означает, то он должен означать язык, имеющий средства хорошей поддержки объектно-ориентированного стиля программирования... Обеспечение такого стиля в свою очередь означает, что в языке удобно пользоваться этим стилем. Если написание программ в стиле OOP требует специальных усилий или оно невозможно совсем, то этот язык не отвечает требованиям OOP" [33]. Теоретически возможна имитация объектно-ориентированного программирования на обычных языках, таких, как Pascal и даже COBOL или ассемблер, но это крайне затруднительно. Карделли и Вегнер говорят, что: "язык программирования является объектно-ориентированным тогда и только тогда, когда выполняются следующие условия:
Поддерживаются объекты, то есть абстракции данных, имеющие интерфейс в виде именованных операций и собственные данные, с ограничением доступа к ним.
Объекты относятся к соответствующим типам (классам).
Типы (классы) могут наследовать атрибуты супертипов (суперклассов)" [34].
Поддержка наследования в таких языках означает возможность установления отношения "is-a" ("есть", "это есть", " - это"), например, красная роза - это цветок, а цветок - это растение. Языки, не имеющие таких механизмов, нельзя отнести к объектно-ориентированным. Карделли и Вегнер назвали такие языки объектными, но не объектно-ориентированными. Согласно этому определению объектно-ориентированными языками являются Smalltalk, Object Pascal, C++ и CLOS, a Ada - объектный язык. Но, поскольку объекты и классы являются элементами обеих групп языков, желательно использовать и в тех, и в других методы объектно-ориентированного проектирования.
Объектно-ориентированное проектирование. Программирование прежде всего подразумевает правильное и эффективное использование механизмов конкретных языков программирования. Проектирование, напротив, основное внимание уделяет правильному и эффективному структурированию сложных систем. Мы определяем объектно-ориентированное проектирование следующим образом:
Объектно-ориентированное проектирование - это методология проектирования, соединяющая в себе процесс объектной декомпозиции и приемы представления логической и физической, а также статической и динамической моделей проектируемой системы.
В данном определении содержатся две важные части: объектно-ориентированное проектирование 1) основывается на объектно-ориентированной декомпозиции; 2) использует многообразие приемов представления моделей, отражающих логическую (классы и объекты) и физическую (модули и процессы) структуру системы, а также ее статические и динамические аспекты.
Именно объектно-ориентированная декомпозиция отличает объектно-ориентированное проектирование от структурного; в первом случае логическая структура системы отражается абстракциями в виде классов и объектов, во втором - алгоритмами. Иногда мы будем использовать аббревиатуру OOD, object-oriented design, для обозначения метода объектно-ориентированного проектирования, изложенного в этой книге.
Объектно-ориентированный анализ. На объектную модель повлияла более ранняя модель жизненного цикла программного обеспечения. Традиционная техника структурного анализа, описанная в работах Де Марко [35], Иордана [36], Гейна и Сарсона [37], а с уточнениями для режимов реального времени у Варда и Меллора [38] и Хотли и Пирбхая [39], основана на потоках данных в системе. Объектно-ориентированный анализ (или OOA, object-oriented analysis) направлен на создание моделей реальной действительности на основе объектно-ориентированного мировоззрения.
Объектно-ориентированный анализ - это методология, при которой требования к системе воспринимаются с точки зрения классов и объектов, выявленных в предметной области.
Как соотносятся ООА, OOD и OOP? На результатах ООА формируются модели, на которых основывается OOD; OOD в свою очередь создает фундамент для окончательной реализации системы с использованием методологии OOP.
2.2. Составные части объектного подхода