Объектные модели данных

Объект – уникально определяемая сущность, которая содержит атрибуты, описывающие состояния объекта реального мира и связанные с ними действия (правила поведения). Во многом объект и сущность РБД совпадает по свойствам, однако сущность моделирует только состояние, а объект инкапсулирует и правила поведения.

Среди атрибутов объекта выделяется ссылочный атрибут: он содержит значение/коллекцию значений, которое само является объектом. Иначе говоря, ссылочный атрибут концептуально аналогичен внешнему ключу в РБД или указателям в ЯП.

Каждому объекту в момент создания присваивается идентификатор объекта OID. Он обладает следующими свойствами:

1. Генерируется системой

2. Уникально обозначает этот объект

3. Его нельзя изменить пока объект продолжает существовать

4. После создания объекта его идентификатор нельзя использовать повторно в дальнейшем при любых условиях.

5. Не зависит от значений атрибутов объекта, т.е. 2 объекта могут и иметь одинаковое состояние, но они всегда обладают разными OID.

6. В идеале – OID скрыто от пользователей.

За счет OID целостность сущностей гарантируется автоматически.

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

Сообщения – средство взаимодействия объектов. Содержательно сообщения – запрос одного объекта (отправителя) к другому (получателю), где второму объекту предлагается выполнить один из его методов.

Классы – группировка одинаковых объектов.

Наследование – один класс определяется как частный случай (подкласс) более общего класса (суперкласс). Подкласс наследует все свойства суперкласса + доп. определяет свои собственные атрибуты и методы. Все экземпляры под класса являются экземплярами суперкласса. Принцип подстановки: экземпляр под класса всегда может пользоваться любым методом/атрибутом суперкласса или в любой конструкции, где используется суперкласс. Понятие под-, суперкласса и наследования существует также в расширенной РБД модели. Однако в чисто объектной модели наследование относится и к состоянию и к поведению.

Перегрузка позволяет повторно использовать имя метода в одном или нескольких методах класса. Частный случай перегрузки – перекрытие. Оно позволяет заново определить имя свойства в некотором подклассе.

Динамическое связывание позволяет отложить линковку до выполнения.

Объектные модели

Объектная модель поволяет решить некоторые проблемы связанные с некоторыми реляционными базами.

Проблемы:


1. Поддержка нескольких версий

Управление версиями- это процесс сопровождения эволюциями объекта.

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

Для управления версиями выделяются три типа версий: 1) временная версия- считается нестабильной, может быть удалена или обновлена, хранится в закрытом рабочем пространстве разработчика проекта.

2) Рабочая версия - считается более стабильной, не может быть обновлена, но может быть удалена ее создателем, так же хранится в закрытом рабочем пространстве разработчика.

3) Выпущенная версия (релиз)-считается стабильной, не может быть обновлена или удалена, хранится в открытой базе и помещается туда в следствии извлечения рабочей версии из закрытого пространства разработчика.

2. Поддержка продолжительных транзакций

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

Вырианты решения проблем: 1) вводится протокол управления параллельным выполнением с временными метками.

Для каждого элемента данных в базе хранятся тройки величин соответствующих каждой смене значения элемента. Мы храним собственное значение элемента версии, мы храним последнюю отметку открытия версии, временную отметку записи версии.

В этом случае нескольким транзакциям разрешается читать и записывать разные версии одного и того же элемента данных.

Версии могут быть удалены сразу после полного завершения всей транзакции.

1) Определяется временная отметка самой старой транзакции в системе, все то ниже этой транзакции удалятется.

2) Вводятся усовершенствованные модели транзакциий. (полная транзакция раскладывается в древовидную структуру сумм транзакций которые выполняются в параллельном режиме.

3) Использование точек сохранения и эммуляция вложенных транзакций. (Точкой сохранения называется некоторой точкой плоской транзакции, которая используется как точка промежуточного перезапуска.

4) Механизм хроник (саги) субд гарантирует что либо все входящие в хронику транзакций будут завершены, либо будут запущены компенсирующие транзакции.

3. Поддержка эволюции проекта т.е. Имеются гибкие средства динамического определения и изменения схемы базы.

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

В целом методы модификации базы основываются на наличии или искуственном введении в объекты системы частично частичной упорядоченности (упорядоченности типа #) это невозможно в реляционных базах.

Недостаток: практически объектная база пишется в ручную.

В объектной базе имеются аналогии с основными приемами работы в реляционной базе.

Нормализация в объектной базе означает - каждый атребут объекта, должен зависеть от идентификатора объекта.

Связи в объектной базе предствалены с помощью ссылочных атребутов.

Ссылочная целостность.

Варианты управления: 1) пользователю запрещается явно удалять объекты, система сама удаляет объекты которые становятся недоступными.

2) пользователю разрешается удалять объекты когда они становятся ненужными, тогда система автоматически обнаруживает недействительные ссылки и присваивает недействительную ссылку NULL.

3) пользователю разрешается изменять и удалять объекты, а система использует обратные атребуты.

ОБЩАЯ ХАРАКТЕРИСТИКА ОБЪЕКТНО РЕЛЯЦИОННОЙ МОДЕЛИ ДАННЫХ

Общая идея ОР модели состоит в дополнении Р модели объектно ориентированными возможностями, а именно добавляется расширяемая пользователем система типов данных, добавляется инкапсуляция, наследование и полиморфизм, добавляется использование сложных объектов, и добавляется идентификация объектов.

Приемущества: повторное и совместное использование стандартных компонентов.

Сервер субд дополняется стандартными функциями которые ненужно писать в виде исполняемого кода в составе отдельных приложений.

Пример поддерки линейного программирования, когда функции исполняются центролизованно.

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

Недостатки: Искажение объектной идеологии.

РАСШИРЕННЫЙ СТАНДАРТ SQL 3. ОСНОВА ДЛЯ ПОСТРОЕНИЯ ОБЪЕКТНО РЕЛЯЦИОННЫХ БД

Включает: конструкторы типов, строка целиком может сохраняться в виде переменных или передаваться как параметр или возвращаться в результата вызова функции.

Разрешаются определяемые пользователем типы, процедуры, функции, операторы.

Как правило процедуры или функции пишутся вне СУБД, и вызываются в SQL с помощью оперотора CALL.

Конструкторы для типов коллекции: создается единственная таблица в которой имеется несколько уровней вложенности.

Поддержка больших объектов. Большой объект - поле таблицы которое содержитпрои значительное количество данных.

В стандарте SQL содержится три топа больших объектов:

1) большой двоичный объект

2) большой символьный объект

В стандарте SQL 3 допускается выполнение некоторых операций с объектами: например оператор конкатенации - возвращает символьную строку образованную соединением символьных строк в указанном порядке.

Есть функции извлечения символьной подстроки:

Функция перекрытия строк.

Функция свертки преобразования регистра.

Функция вычисления длины строки.

МОДЕЛЬ ХРАНИЛИЩА ДАННЫХ

Хранилище данных- это предметно ориентированный, интегрированный, привязанный ко времени и не изменяемый набор данных, предназначенный для поддержки принятия решений.

Хранилище данных имеет много общего с реляционной моделью.

1) Хранилище данных организуется не вокруг областей деятельности, а вокруг (предметов, товаров и др.).

2) Данные не обновляются, а только пополняются.

3) Реляционная база проектируется с целью обеспечения интенсивной обработки небольшого количества транзакций, хранилище данных проектируется для обработки единичных произвольных запросов.

4) Базовым объектом модели хранилища является привязанный ко времени факт.

5) Основная операция это агрегирование и основная проблема максимальная скорость доступа к факту.

Хранилище данных.

Базы данных в концепции хранилища описываются с использованием метода «моделирование размерностей».

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

Каждая таблица размерностей имеет не составной(простой) первичный ключ, который точно соответствует одному из компонентов составного ключа в таблице фактов

Схема звезда - логическая структура в центре которой находится таблица фактов, окруженная содержащими ссылочные данные таблица размерностей, при этом таблицы размерностей, как правило, нормализованы. (посмотреть схему звезды)

Таблицы фактов, как правило, имеют огромный размер по сравнению с таблицами размерностей, большая часть в таблице фактов это числовые данные и результаты сложения чисел.

В хранилищах данных практически никогда не происходит к единичным записям, базовая операция для них это агрегирование.

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

Применимость концепции хранилища данных находится в прямой зависимости от удачного структурирования таблицы размерностей.

Схема звезда позволяет ускорить выполнение запросов путем денормализации, т. к. выделяет сущности, к которым часто осуществляется доступ, но денормализацию не следует применять, если дополнительные данные требуются не очень часто.

Схема снежинка - вариант схемы звезда, в которой каждая размерность может иметь своих собственные размерности.

Приимущество хранилищ данных:

1. Эффективность - единообразие структуры обеспечивает более эффективный доступ к данным, независимо от средств доступа.

2. Все размерности в равной степени обеспечивают доступ к таблице фактов, следовательно проект обладает большей способность поддерживать произвольные запросы пользователя.

3. Расширяемость - типичные изменения:

1. Добавление новых фактов, это можно делать при условии, что они имеют такую же степень детализации, как и таблица фактов.

2. Добавление новых размерностей - возможно при условии, что имеется единственное значение данной размерностей, определенное для каждой существующей записи в таблице фактов.

3. Добавление новых атрибутов.

4. Разбиение существующих размерностей на записи с меньшим уровнем детализации, н начиная с определенного момента времени.

Модель данных OLAP

Таблица в реляционной СУБД представляет многомерные данных только в 2-х измерения, теория многомерных кубов использует, которые удобно представлять в виде пространства с размерностью n, каждая сторона такого куба может быть интерпретирована как двумерная таблица.

В каждой ячейке куба находится отдельный факт, а совокупность координат этой ячейки представляет собой полный массив данных об этом факте.

1. Многомерные БД очень компактны, они обеспечивают простые средства просмотра и манипулирования элементам и данных.

2. Куб легко расширяется, можно каждую ячейку куба развернуть в подкуб.

3. Существует мощнейший мат аппарат для работы с многомерными кубами, это матрицы.

1. С ростом числа размерностей кол-во ячеек в кубе возрастает экспоненциально, время обработки многомерного запроса увеличивается.

2. Как правило такие структуры представляют собой сильно разреженные матрицы. Много NULL.

Для создания эффективной многомерной базы возможно несклолько путей:

1. Выявить иерархическую структуру в данных.

2. Выявить другие порядки типа решетка типичных размерностей.

3. Разбиение гиперкуба на много маленьких кубов с заполненными ячейками.

Таким образом независимо от структуры хранения эффективность определяется метаданными, тоесть ожидаемыми вариантами размещения данных.

Модель слабоструктурированных данных

Слабостр. - называются данные, которые обладают определенной структурой, но эта структура оказывается непостоянна, недостаточно изученной или неполной. Как правило, такие данные не м. б. описаны с помощью одной неизменной схемы.

Если в СУБД должны храниться слабоструктурированные данные, то субд должна формировать схему на основе этих данных.

Большенство подходов к управлению такими данными использует языки запросов, обеспечивающие прохождение по древовидному, размеченному графу. Соответственно выполнение запросов становиться не деклоративными, а традиционными.

Варианты записи слабоструктурированных данных:

1. Модель обмена объектными данными OEM. Модель представления множенных объектов, определяется сама через себя. Позволяется отобразить данные с нерегулярной структурой и неопределенным типом. Представляется собой размеченный, ориентированный граф, в узлах которого находятся особые объекты (объекты OEM), для каждого объекта задаются уникальный идентификатор, описательная текстовая метка, тип, значение. Объекты подразделяются на элементарные и составные. Элементарные - это листья, они на графи отображаются без исходящих ребер. все остальные называются составными, при чем один и тот же объект может иметь произвольное число родительских объектов. Тип конкретного объекта определен как множество ИД объекта. Работать с конструкциями подобного типа тяжело, т. к. невозможно выделить пустую структуру графа.

2. Язык XML - мета язык, язык для описания других языков. Система определения структурированных типов документов и языков разметки, представляющих экземпляры документов данного типа. Достоинтсва:

1. Может применяться для разметки любых документов, в том числе текстовых и мультимедийных.

2. Позволяется наглядно описать структуру данных. Можно использовать для описания гетерогенных (разнородны) БД.

3. Позволяет хранить содержимое документа и отдельно (независимо) способ его представления.

Реляционная алгебра и реляционное исчисление

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

Существует альтернативный вариант для описания запроса который называется логические исчисления.

Существует два варианта реляционной логики - это исчисление кортежей, и исчисление доменов.

Исчисление кортежей - переменной является кортеж(строчка) тела отношения.

Для формирования условий выборки из набора отношений используются так называемые правильно построенные формулы (well formed formula) - это условия накладываемые на кортежные переменные.

Пример: СЛУЖАЩИЙ СЛ_НОМ= НАЧАЛЬНИК НАЧ_НОМ

Для построения WFF используются логические связки и правила мат логики.

Механизм работы: Система перебирает все имеющиеся в бд комбинации кортежей, например для каждого кортежа проект, просматривается облать определений кортежей служащих и выделяет те сочетания кортежей для которых WFF верно.

Таким образом это эквивалентно тому, что система по умолчанию выполняет операцию join.

Исчисление доменов: Основное формальное отличие исчисления доменов от исчисления кортежей - это наличие дополнительного множества предикатов, позволяющих выделить условие членства.

Сопостовление Реляционной алгебры и Реляционного исчисления.

Формально между ними есть отличия, однако с точки зрения исполняющей системы реляционная алгебра и реляционные исчисления логически эквивалентны. Каждое выражение реляционной алгебры может быть однозначно преобразованно в выражение реляционного исчисления и наоборот.

Примеры: Субд которые работают на линукс это INGRES (Integratie graphics retrielale System)(хз че написано у нее подчерк кривой).

И язык табличная форма Query by Example

Резюме

Недостатки модели TCP/IP

Несмотря на огромную популярность, у модели TCP/IP и ее протоколов имеется ряд недостатков:

· отсутствие разграничений концептуальных понятий интерфейса, протокола и уровневого сервиса, что достаточно четко сделано в модели ISO/OSI. Вследствие этого модель TCP/IP не может применяться при разработке новых сетей;

· с помощью модели TCP/IP нельзя описать никакой другой стек протоколов, кроме TCP/IP;

· в модели не различаются физический и канальный уровни, в то время как они абсолютно разные и в корректной модели это должно учитываться;

· наиболее тщательно продуманы и проработаны протоколы IP и TCP. Многие из других протоколов стека разрабатывались студентами (студентам к размышлению!) и свободно распространялись, вследствие чего широко укоренились в практике и теперь их трудно заменить на что-либо новое, предлагаемое по коммерческой схеме.

В качестве резюме отметим, что модель ISO/OSI является полезной для теоретических исследований и разработок новых сетей, хотя протоколы OSI не получили широкого распространения. Для TCP/IP можно сделать обратное утверждение: стек не может рассматриваться в качестве полноценной модели, тогда как сами протоколы хорошо апробированы и чрезвычайно популярны.

Рассматривая эталонную модель с точки зрения новых требований, которые информационные потоки предъявляют к процессу переноса в инфо-коммуникационной сети, следует выделить две проблемы.

Во-первых, на транспортном и канальном уровнях реализуются два независимых механизма переноса. Такое разбиение задачи транспортировки информации было в свое время продиктовано необходимостью объединения множества сетей, использующих разные технологии доступа к каналу связи. Однако, наличие двух несогласованных механизмов передачи создает проблему обеспечения качества обслуживания при переносе информации. Добиться согласованного поведения транспортного и канального уровней (через сетевой уровень) невозможно, исходя их принципа автономности уровней в модели ISO/OSI. Однако современные концепции развития сетей на мультисервисной основе (в частности концепция NGN) предусматривают стратегии согласованного поведения транспортного и канального уровней в обход сетевого уровня, что формально нарушает принцип автономности и выходит за рамки эталонной модели.

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



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

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

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

Анализ программной структуры позволяет рассмотреть иерархию сетевого программного обеспечения. Элементами этой структуры являются программные модули, в которых реализованы объекты и логические модули сети.

Иерархия программного обеспечения (ПО) может быть представлена в следующем виде:

· прикладное ПО;

· промежуточное ПО;

· базовое ПО.

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

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

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

Компоненты распределенного приложения могут неоднократно использоваться другими приложениями. В этом случае они становятся объектами промежуточного ПО и поддерживают услуги, связанные с интеллектуальными возможностями сети.

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

Базовое ПО предназначено для обеспечения объектам прикладного ПО и промежуточного ПО возможности выполнения и взаимодействия с другими объектами, посредством обеспечения среды взаимодействия с коммуникационными функциями сети и логическими интерфейсами пользователей. Организация этой среды осуществляется унифицированными программными комплексами, которые называются сетевыми операционными системами . От того какие концепции управления ресурсами положены в основу сетевой ОС, зависит эффективность работы не только объектов прикладного и промежуточного ПО но и сети в целом. Стандартами сетевых ОС де-факто на сегодняшний день стали системы UNIX и сетевые версии Windows. Логические компоненты коммуникационных функций, реализуемых программно, обеспечивающие поддержание связи между удаленными объектами, также относятся к функциям базового ПО.

К базовому ПО относятся и объекты обработки и хранения данных, реализуемые в таких программных комплексах, как СУБД (системы управления базами данных), базовое ПО сервера обработки транзакций и др.

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

Различают следующие типы объектных интерфейсов (программных интерфейсов):

· прикладной протокол (Application Protocol, АР) – логический интерфейс между прикладными объектами;

· интерфейс прикладных программ (Application Program Interface, API) – логический интерфейс между прикладными объектами и объектами промежуточного ПО, которые поддерживают прикладные объекты;

· протокол промежуточного ПО (Managing Protocol, МР) – логический интерфейс между объектами промежуточного ПО;

· интерфейс базовых программ (Base Program Interface, ВРІ) – логический интерфейс между объектами промежуточного и базового ПО, которые поддерживают объекты промежуточного ПО;

· интерфейс человек-компьютер (User-Computer Interface, UCI) – логический интерфейс между пользователем и, главным образом, объектами базового ПО, однако он может включать в себя также логический интерфейс с объектами промежуточного ПО и даже объектами приложений.

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

Теперь у нас есть все необходимые понятия, чтобы описать процесс построения объектной модели. Этот процесс включает в себя следующие этапы:

· определение объектов и классов;

· подготовка словаря данных;

· определение зависимостей между объектами;

· определение атрибутов объектов и связей;

· организация и упрощение классов при использовании наследования;

· дальнейшее исследование и усовершенствование модели.

2.2.1. Определение классов. Анализ внешних требований к проектируемой ПС позволяет определить объекты и классы объектов, связанные с прикладной проблемой, которую должна решать эта система. Все классы должны быть осмыслены в рассматриваемой прикладной области; классов, связанных с компьютерной реализацией, как например список, стек и т.п. на этом этапе вводить не следует.

Начать нужно с выделения возможных классов из письменной постановки прикладной задачи (технического задания и другой документации, предоставленной заказчиком). Следует иметь в виду, что это очень сложный и ответственный этап разработки, так как от него во многом зависит дальнейшая судьба проекта.

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

· избыточные классы: если два или несколько классов выражают одинаковую информацию, следует сохранить только один из них;

· нерелевантные (не имеющие прямого отношения к проблеме) классы : для каждого имени возможного класса оценивается, насколько он необходим в будущей системе (оценить это часто бывает весьма непросто); нерелевантные классы исключаются;



· нечетко определенные (с точки зрения проблемы) классы (см. п. 2.3.1);

· атрибуты : некоторым существительным больше соответствуют не классы, а атрибуты; такие существительные, как правило, описывают свойства объектов (например, имя, возраст, вес, адрес и т.п.);

· операции : некоторым существительным больше соответствуют не классы, а имена операций (например, телефонный_вызов вряд ли означает какой-либо класс);

· роли : некоторые существительные определяют имена ролей в объектной модели (например, владелец, водитель, начальник, служащий; все эти имена связаны с ролями в различных зависимостях объектов класса человек);

· реализационные конструкции : именам, больше связанным с программированием и компьютерной аппаратурой, не следует на данном этапе сопоставлять классов, так как они не отражают особенностей проектируемой ПС; примеры таких имен: подпрограмма, процесс, алгоритм, прерывание и т.п.

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

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

2.2.3. Определение зависимостей. На следующем этапе построения объектной модели определяются зависимости между классами. Прежде всего из классов исключаются атрибуты, являющиеся явными ссылками на другие классы; такие атрибуты заменяются зависимостями. Смысл такой замены в том, что зависимости представляют собой абстракцию того же уровня, что и классы, и потому не оказывают непосредственного влияния на будущую реализацию (ссылка на класс лишь один из способов реализации зависимостей).

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

Затем следует убрать ненужные или неправильные зависимости, используя следующие критерии:

· зависимости между исключенными классами должны быть исключены, либо переформулированы в терминах оставшихся классов (см. п. 2.3.3);

· нерелевантные зависимости и зависимости, связанные с реализацией, должны быть исключены (см. п. 2.3.3);

· действия: зависимость должна описывать структурные свойства прикладной области, а не малосущественные события (см. п. 2.3.3);

· тренарные зависимости: большую часть зависимостей между тремя или большим числом классов можно разложить на несколько бинарных зависимостей, используя в случае необходимости квалификаторы (см. п. 2.3.3); в некоторых (редких) случаях такое разложение осуществить не удается; например, тренарная зависимость "Профессор читает курс в аудитории 628" не может быть разложена на бинарные без потери информации;

· производные зависимости: нужно исключать зависимости, которые можно выразить через другие зависимости, так как они избыточны (см. п. 2.3.3); при исключении избыточных (производных) зависимостей нужно быть особенно осторожным, так как не все дублирующие одна другую зависимости между классами избыточны; в некоторых случаях другие зависимости позволяют установить только существование еще одной производной зависимости, но не позволяют установить кратность этой зависимости; например, в случае, представленном на рис. 2.36, фирма имеет много служащих и владеет многими компьютерами; каждому служащему предоставлено для персонального использования несколько компьютеров, кроме того, имеются компьютеры общего пользования; кратность зависимости предоставлен_для_использования не может быть выведена из зависимостей служит и владеет; хотя производные зависимости и не добавляют новой информации, они часто бывают удобны; в этих случаях их можно указывать на диаграмме, пометив косой чертой.

Рис. 2.36. Неизбыточные зависимости

Удалив избыточные зависимости, нужно уточнить семантику оставшихся зависимостей следующим образом:

· неверно названные зависимости: их следует переименовать, чтобы смысл их стал понятен (см. п. 2.3.3);

· имена ролей: нужно добавить имена ролей там, где это необходимо; имя роли описывает роль, которую играет соответствующий класс в данной зависимости с точки зрения другого класса, участвующего в этой зависимости; если имя роли ясно из имени класса, его можно не указывать (см. п. 2.3.3);

· квалификаторы: добавляя квалификаторы там, где это необходимо, мы вносим элементы контекста, что позволяет добиться однозначной идентификации объектов; квалификаторы позволяют также упростить некоторые зависимости, понизив их кратность;

· кратность: необходимо добавить обозначения кратности зависимостей; при этом следует помнить, что кратность зависимостей может меняться в процессе дальнейшего анализа требований к системе;

· неучтенные зависимости должны быть выявлены и добавлены в модель.

2.2.4. Уточнение атрибутов. На следующем этапе уточняется система атрибутов: корректируются атрибуты классов, вводятся, в случае необходимости, новые атрибуты. Атрибуты выражают свойства объектов рассматриваемого класса, либо определяют их текущее состояние.

Атрибуты обычно соответствуют существительным; например цвет_автомобиля (свойство объекта), позиция_курсора (состояние объекта). Атрибуты, как правило, слабо влияют на структуру объектной модели.

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

Наряду с атрибутами объектов необходимо ввести и атрибуты зависимостей между классами (связей между объектами).

При уточнении атрибутов руководствуются следующими критериями:

· Замена атрибутов на объекты . Если наличие некоторой сущности важнее, чем ее значение, то это объект, если важнее значение, то это атрибут: например, начальник - это объект (неважно, кто именно начальник, главное, чтобы кто-то им был), зарплата - это атрибут (ее значение весьма существенно); город - всегда объект, хотя в некоторых случаях может показаться, что это атрибут (например, город как часть адреса фирмы); в тех случаях, когда нужно, чтобы город был атрибутом, следует определить зависимость (скажем, находится) между классами фирма и город.

· Квалификаторы . Если значение атрибута зависит от конкретного контекста, его следует сделать квалификатором (см. п. 2.3.4).

· Имена . Именам обычно лучше соответствуют квалификаторы, чем атрибуты объектов; во всех случаях, когда имя позволяет сделать выбор из объектов некоторого множества, его следует сделать квалификатором (см. п. 2.3.4).

· Идентификаторы . Идентификаторы объектов связаны с их реализацией. На ранних стадиях проектирования их не следует рассматривать в качестве атрибутов.

· Атрибуты связей . Если некоторое свойство характеризует не объект сам по себе, а его связь с другим объектом (объектами), то это атрибут связи, а не атрибут объекта.

· Внутренние значения . Атрибуты, определяющие лишь внутреннее состояние объекта, незаметное вне объекта, следует исключить из рассмотрения.

· Несущественные детали . Атрибуты, не влияющие на выполнение большей части операций, рекомендуется опустить.

2.2.5. Организация системы классов, используя наследование. Далее необходимо постараться найти суперклассы для введенных классов. Это полезно, так как проясняет структуру модели и облегчает последующую реализацию. Пример рассмотрен в п. 2.3.5.

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

Здесь мы рассмотрим приемы бескомпьютерного поиска и исправления ошибок в объектной модели. В их основе лежат внешние признаки, по которым можно находить ошибки в модели; эти признаки могут быть объединены в следующие группы.

Признаки пропущенного объекта (класса):

· несимметричности связей и обобщений (наследований); для исправления ошибки необходимо добавить пропущенные классы;

· несоответствие атрибутов и операций у класса; для исправления ошибки необходимо расщепить класс на несколько других классов, так чтобы атрибуты и операции новых классов соответствовали друг другу;

· обнаружена операция, не имеющая удовлетворительного целевого класса; для исправления ошибки необходимо добавить пропущенный целевой класс;

· обнаружено несколько зависимостей с одинаковыми именами и назначением; для исправления ошибки необходимо сделать обобщение и добавить пропущенный суперкласс.

Признаки ненужного (лишнего) класса:

· нехватка атрибутов, операций и зависимостей у некоторого класса; для исправления ошибки необходимо подумать, не следует ли исключить такой класс.

Признаки пропущенных зависимостей:

· отсутствуют пути доступа к операциям; для исправления ошибки необходимо добавить новые зависимости, обеспечивающие возможности обслуживания соответствующих запросов.

Признаки ненужных (лишних) зависимостей:

· избыточная информация в зависимостях; для исправления ошибки необходимо исключить зависимости, не добавляющие новой информации, или пометить их как производные зависимости;

· не хватает операций, пересекающих зависимость; для исправления ошибки необходимо подумать, не следует ли исключить такую зависимость.

Признаки неправильного размещения зависимостей:

· имена ролей слишком широки или слишком узки для их классов; для исправления ошибки необходимо переместить зависимость вверх или вниз по иерархии классов.

Признаки неправильного размещения атрибутов:

· нет необходимости доступа к объекту по значениям одного из его атрибутов; для исправления ошибки необходимо рассмотреть, нужно ли ввести квалифицированную зависимость.

Примеры практического применения описанных признаков см. в п. 2.3.6.

Пример объектной модели

Рассмотрим процесс построения объектной модели для системы банковского обслуживания в процессе анализа требований и предварительного проектирования этой системы. Для построения объектной модели рассматриваемой системы нам необходимо выполнить все этапы, перечисленные в п 2.2.

2.3.1. Определение объектов и классов. В п. 1.3 сформулирована задача и приведена схема сети банковского обслуживания (рис. 1.3). Анализируя эту постановку задачи, можно выделить возможные классы, сопоставив их существительным, упомянутым в ее предварительной формулировке; получится следующий список возможных имен классов (в алфавитном порядке):

Исследуем этот список, исключая из него имена классов в соответствии с рекомендациями п. 2.2.1:

· избыточные классы : ясно, что клиент и пользователь означают одно и то же понятие; для банковской системы более естественно оставить класс клиент;

· нерелевантные классы : таким классом является класс цена (он не имеет непосредственного отношения к работе банковской сети);

· нечетко определенные классы : такими классами являются служба_ведения_записей и проверка безопасности (эти службы входят в состав проводки), система (в нашем случае непонятно, что это такое), банковская_сеть (вся ПС будет обслуживать банковскую сеть);

· атрибуты : данные проводки, данные счета, деньги (имеются в виду реальные деньги, выдаваемые клиенту кассиром или банкоматом, либо принимаемые кассиром), квитанция (выдается клиенту вместе с деньгами) более естественно иметь в качестве атрибутов;

· реализационные конструкции выражают такие имена как программное_обеспечение и доступ; их тоже следует исключить из списка имен возможных классов.

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

2.3.2. Подготовка словаря данных. Приведем часть словаря данных, содержащую определения классов, используемых в проекте.

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

Банк - финансовая организация, которая содержит счета своих клиентов и выпускает карточки, санкционирующие доступ к счетам через сеть ATM (банкоматов).

Карточка - пластиковая карточка, врученная банком своему клиенту, которая санкционирует доступ к счетам через сеть ATM (банкоматов). Каждая карточка содержит код банка и номер карточки, закодированные в соответствии с национальными стандартами на банковские карточки. Код_банка однозначно идентифицирует банк внутри консорциума. Номер_карточки определяет счета, к которым карточка имеет доступ. Карточка не обязательно обеспечивает доступ ко всем счетам клиента. Каждой карточкой может владеть только один клиент, но у нее может существовать несколько копий, так что необходимо рассмотреть возможность одновременного использования одной и той же карточки с разных ATM (банкоматов).

Кассир - служащий банка, который имеет право осуществлять проводки с кассовых_ терминалов, а также принимать и выдавать деньги и чеки клиентам. Проводки, деньги и чеки, с которыми работает каждый кассир, должны протоколироваться и правильно учитываться.

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

Клиент - держатель одного или нескольких счетов в банке. Клиент может состоять из одного или нескольких лиц, или организаций. То же самое лицо, держащее счет и в другом банке рассматривается как другой клиент.

Компьютер_банка - компьютер, принадлежащий банку, который взаимодействует с сетью ATM (банкоматов) и собственными кассовыми_терминалами банка. Банк может иметь свою внутреннюю компьютерную сеть для обработки счетов, но здесь мы рассматриваем только тот компьютер_банка, который взаимодействует с сетью ATM.

Консорциум - объединение банков, которое обеспечивает работу сети ATM (банкоматов). Сеть передает в консорциум проводки банков.

Проводка - единичный интегрированный запрос на выполнение некоторой последовательности операций над счетами одного клиента. Было сделано предположение, что ATM (банкоматы) только выдают деньги, однако для них не следует исключать возможности печати чеков или приема денег и чеков. Хотелось бы также обеспечить гибкость системы, которая в дальнейшем обеспечит возможность одновременной обработки счетов разных клиентов, хотя пока этого не требуется. Различные операции должны быть правильно сбалансированы.

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

Центральный_компьютер - компьютер, принадлежащий консорциуму, который распределяет проводки и их результаты между ATM (банкоматами) и компьютерами_банков. Центральный_компьютер проверяет коды банков, но не выполняет проводок.

2.3.3. Определение зависимостей. Следуя рекомендациям п. 2.2.3, выделяем явные и неявные глагольные обороты из предварительной постановки задачи и рассматриваем их как имена возможных зависимостей. Из постановки задачи о банковской сети (см. п. 1.3) можно извлечь следующие обороты:

Глагольные обороты (явные и неявные):

Банковская сеть включает кассиров и ATM"ы

Консорциум распределяет результаты проводок по ATM

Банк владеет компьютером банка

Компьютер банка поддерживает счета

Банк владеет кассовыми терминалами

Кассовый терминал взаимодействует с компьютером банка

Кассир вводит проводку над счетом

ATM"ы взаимодействуют с центральным компьютером во время проводки

Центральный компьютер взаимодействует с компьютером банка

ATM принимает карточку

ATM общается с пользователем

ATM выдает наличные деньги

ATM печатает квитанции

Система регулирует коллективный доступ

Банк предоставляет программное обеспечение

Консорциум состоит из банков

Консорциум владеет центральным компьютером

Система обеспечивает протоколирование

Система обеспечивает безопасность

Клиенты имеют карточки

Карточка обеспечивает доступ к счету

В банке служат кассиры

Затем исключаем ненужные или неправильные зависимости, используя критерии, сформулированные в п. 2.2.3:

· зависимости между исключенными классами: исключаются следующие зависимости: Банковская сеть включает кассиров и ATM"ы (класс банковская_сеть исключен), ATM печатает квитанции (класс квитанция исключен), ATM выдает наличные деньги (класс деньги исключен), Система обеспечивает протоколирование проводок (класс служба_ведения_записей исключен), Система обеспечивает безопасность ведения счетов (класс служба_безопасности исключен), Банки предоставляют программное обеспечение (класс программное_обеспечение исключен);

· нерелевантные зависимости и зависимости, связанные с реализацией: зависимость "Система регулирует коллективный доступ" исключается как связанная с реализацией;

· действия описываются такими зависимостями как "ATM принимает карточку" и "ATM общается с пользователем"; мы исключаем эти зависимости;

· тренарные зависимости: зависимость "Кассир вводит проводку над счетом" раскладывается на две бинарные зависимости "Кассир вводит проводку" и "Проводка относится к счету". Зависимость "ATM"ы взаимодействуют с центральным компьютером во время проводки" раскладывается на "ATM"ы взаимодействуют с центральным компьютером" и "Проводка начинается с ATM";

· производные зависимости: зависимость "Консорциум распределяет ATM"ы" является следствием зависимостей "Консорциум владеет центральным компьютером" и "ATM"ы взаимодействуют с центральным компьютером".

Удалив избыточные зависимости, получим следующий список зависимостей:

Банк владеет компьютером банка

Компьютер банка поддерживает счета

Банк владеет кассовыми терминалами

Кассовый терминал взаимодействует с компьютером банка

Кассир вводит проводку

Проводка относится к счету

ATM"ы взаимодействуют с центральным компьютером

Проводка начинается с ATM

Центральный компьютер взаимодействует с компьютером банка

Консорциум состоит из банков

Консорциум владеет центральным компьютером

Клиенты имеют карточки

Карточка обеспечивает доступ к счету

В банке служат кассиры

Уточним семантику оставшихся зависимостей следующим образом:

· переименуем неверно названные зависимости, чтобы смысл их стал более понятен; так зависимость Компьютер_банка поддерживает счета удобнее заменить зависимостью Банк держит счета.

· имена ролей можно не использовать, так как они ясны из имен классов, участвующих в зависимости, как например, для зависимости ATM"ы взаимодействуют с центральным компьютером;

· неучтенные зависимости: Проводка начинается с кассового_терминала, Клиенты имеют счета, Проводка регистрируется карточкой следует добавить в модель.

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

Рис. 2.37. Первая версия объектной диаграммы для банковской сети

2.3.4. Уточнение атрибутов. Применяя критерии, сформулированные в п. 2.2.4, получим:

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

После внесения перечисленных изменений диаграмма примет вид, представленный на рис. 2.38.

2.3.5. Организация системы классов с использованием наследования. В рассматриваемом примере естественно определить суперклассы для объектов, определяющих различные терминалы: кассовый_терминал и ATM (банкомат), и для объектов, определяющих проводки: проводка_кассира и удаленная_проводка (с банкомата).

Внеся соответствующие изменения, получим объектную диаграмму, представленную на рис. 2.39.

Рис. 2.38. Объектная диаграмма для банковской сети после уточнения атрибутов и добавления квалификаторов

Рис. 2.39. Объектная диаграмма для банковской с учетом наследования

2.3.6. Дальнейшее усовершенствование модели. Карточка выступает в двух сущностях: как регистрационная единица в банке (сберкнижка), обеспечивающая клиенту доступ к его счетам, и как структура данных, с которой работает ATM. Поэтому удобно расщепить класс карточка на два класса: регистрация_карточки и карточка; первый из этих классов обеспечивает клиенту доступ к его счетам в банке, а второй определяет структуру данных, с которой работает ATM.

Класс проводка удобно представить как агрегацию классов изменение, так как проводка - это согласованная последовательность внесения изменений в счета и другие банковские документы; при работе с банковскими документами рассматривается три вида изменений: снятие, помещение и запрос.

Класс банк естественно объединить с классом компьютер_банка, а класс консорциум - с классом центральный_компьютер.

Рис. 2.40. Окончательный вид объектной диаграммы для банковской сети

После внесения перечисленных изменений объектная диаграмма примет вид, представленный на рис. 2.40. На этом построение объектной модели этапа предварительного проектирования заканчивается. Дальнейшие уточнения объектной модели будут производиться на следующих фазах ЖЦ системы.

Выделение подсистем

2.4.1. Понятие подсистемы. Итак, ПС представляет собой множество взаимозависимых объектов. Каждый объект характеризуется набором атрибутов, значения которых определяют состояние объекта, и набором операций, которые можно применять к этому объекту. При разработке ПС удобно считать, что все атрибуты объектов являются закрытыми (т.е. они не доступны вне объекта, и для того, чтобы в некотором объекте узнать значение атрибута другого объекта, или изменить его, необходимо воспользоваться одной из открытых операций этого объекта, если, конечно, такая операция определена). Операции объектов могут быть как открытыми, так и закрытыми.

Таким образом, каждый объект имеет строго определенный интерфейс , т.е. набор открытых операций, которые можно применять к этому объекту. Все объекты одного класса имеют одинаковый интерфейс. Интерфейс класса (а, следовательно, и каждого объекта этого класса) задается списком сигнатур его открытых (общедоступных) операций (и реализующих их методов); сигнатуры закрытых операций в интерфейс объектов соответствующего класса не входят.

Объектная модель системы задает множество взаимозависимых объектов, составляющих систему, и, следовательно, определяет набор интерфейсов, доступных внутри системы. Все возможности по обработке данных внутри системы (т.е. в каждом объекте, входящем в состав системы) определяются этим набором интерфейсов, который определяет внутреннее окружение (или среду) системы .

Наряду с внутренним окружением системы можно определить ее внешнее окружение . Оно определяется функциями (операциями), реализованными в составе системного программного обеспечения (т.е. операционной системы, системы программирования, различных редакторов, СУБД и т.п.), а также в других прикладных системах и библиотеках, используемых совместно с системой. Объекты и операции, составляющие внешнее окружение системы, тоже могут быть доступны внутри системы. Чтобы не упустить этого из виду, можно было бы добавить в объектную модель еще один объект, интерфейс которого представлял бы возможности внешнего окружения, используемые в системе (такой интерфейс обычно представляет лишь часть возможностей внешнего окружения). Но это было бы не совсем точно, так как внешнее окружение реализуется не одним, а несколькими объектами. С другой стороны внутри системы нет резона рассматривать структуру ее внешнего окружения. Выход из указанного противоречия во введении в рассмотрение еще одной сущности - подсистемы.

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

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

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

Объектную модель системы банковского обслуживания и ее системного (внешнего) окружения тоже можно изобразить в виде объектной диаграммы (правда, в состав этой объектной диаграммы будут входить не объекты, а только подсистемы; каждая подсистема изображается на диаграмме в виде прямоугольника с двойными вертикальными сторонами). Зависимости между подсистемами, изображенные на этой объектной диаграмме (рис. 2.42), отражают взаимодействие проектируемой системы банковского обслуживания и соответствующих подсистем в процессе работы системы. Тем самым определяются требования проектируемой системы к ее системному окружению.

Рис. 2.41. Объектная диаграмма банковской сети, в которой указан интерфейс с системным окружением

Рис. 2.42. Объектная диаграмма банковской сети и ее системного окружения

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

2.4.2. Интерфейсы и окружения. Объекты и подсистемы, составляющие подсистему более высокого уровня, будем называть компонентами последней. Как уже было отмечено, для каждого компонента, входящего в состав объектной модели подсистемы, определен его интерфейс , т.е. набор открытых (общедоступных) операций, которые можно применять к этому компоненту (объекту или подсистеме).

Интерфейс объекта определяется интерфейсом соответствующего класса и задается списком сигнатур его открытых операций (методов). Интерфейс подсистемы определяется через итерфейсы составляющих ее объектов и подсистем следующим образом: операция может быть включена в интерфейс подсистемы, если в составе этой подсистемы имеется объект (подсистема), интефейс которого содержит эту операцию. Интерфейсы описываются на языке описания интерфейсов IDL (Interface Definition Language) .

Все возможности по обработке данных внутри подсистемы (т.е. в каждом компоненте, входящем в ее состав) определяются набором интерфейсов ее компонентов, который определяет внутреннее окружение подсистемы .

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

Поясним введенные понятия на примере системы банковского обслуживания. В ее составе можно выделить подсистему банк (на самом деле в системе будет несколько экземпляров подсистемы банк - по одной для каждого банка, входящего в консорциум). При этом объектная модель системы примет вид, изображенный на рис. 2.43.

Рис. 2.43. Объектная диаграмма банковской сети после выделения подсистемы банк

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

Парадигмы программирования

Объе́ктно-ориенти́рованное программи́рование (ООП) - методология программирования, основанная на представлении программы в виде совокупности объектов , каждый из которых является экземпляром определённого класса , а классы образуют иерархию наследования .

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

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

Наиболее заметные отличия в проявлении показателей качества между языками разных видов:

  • В мейнстримных языках декларируемые принципы нацелены на повышение изначально низкого для императивного программирования коэффициента повторного использования кода . В полиморфно типизированных применение концепций ООП, напротив, означает очевидное его снижение из-за перехода от параметрического полиморфизма к ad-hoc-полиморфизму . В динамически типизированных языках (Smalltalk , Python , Ruby) эти принципы используются для логической организации программы, и их влияние на коэффициент повторного использования трудно спрогнозировать - он сильно зависит от дисциплины программиста. Например, в CLOS мультиметоды одновременно являются функциями первого класса , что позволяет рассматривать их одновременно и как связанно квантифицированные , и как обобщённые (истинно полиморфные).
  • Традиционные ОО-языки используют номинативную типизацию , то есть допустимость соиспользования объектов разных классов только при условии явного указания родственных отношений между классами. Для полиморфно типизированных языков характерна структурная типизация , то есть согласование классов между собой тем же механизмом, что и согласование числа 5 с типом int . Динамически типизированные языки также занимают здесь промежуточную позицию.

Обобщённое обоснование динамической диспетчеризации (включая множественную) в середине 1990-х годов построил Джузеппе Кастанья .

История

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

Взаимодействие объектов происходит посредством . Результатом дальнейшего развития ООП, по-видимому, будет агентно-ориентированое программирование , где агенты - независимые части кода на уровне выполнения. Взаимодействие агентов происходит посредством изменения среды , в которой они находятся.

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

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

Взгляд на программирование «под новым углом» (отличным от процедурного) предложили Алан Кэй и Дэн Ингаллс в языке Smalltalk . Здесь понятие класса стало основообразующей идеей для всех остальных конструкций языка (то есть класс в Смолтоке является примитивом, посредством которого описаны более сложные конструкции). Именно он стал первым широко распространённым объектно-ориентированным языком программирования .

В настоящее время количество прикладных языков программирования (список языков), реализующих объектно-ориентированную парадигму, является наибольшим по отношению к другим парадигмам. Наиболее распространённые в промышленности языки (С++, Delphi, C#, Java и др.) воплощают объектную модель Симулы. Примерами языков, опирающихся на модель Смолтока, являются Objective-C, Python, Ruby.

Определение ООП и его основные концепции

В центре ООП находится понятие объекта. Объект - это сущность, которой можно посылать сообщения и которая может на них реагировать, используя свои данные. Объект - это экземпляр класса. Данные объекта скрыты от остальной программы. Сокрытие данных называется инкапсуляцией .

Наличие инкапсуляции достаточно для объектности языка программирования, но ещё не означает его объектной ориентированности - для этого требуется наличие наследования .

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

Сложности определения

ООП имеет уже более чем сорокалетнюю историю, но, несмотря на это, до сих пор не существует чёткого общепринятого определения данной технологии . Основные принципы, заложенные в первые объектные языки и системы, подверглись существенному изменению (или искажению) и дополнению при многочисленных реализациях последующего времени. Кроме того, примерно с середины 1980-х годов термин «объектно-ориентированный» стал модным , в результате с ним произошло то же самое, что несколько раньше с термином «структурный» (ставшим модным после распространения технологии структурного программирования) - его стали искусственно «прикреплять» к любым новым разработкам, чтобы обеспечить им привлекательность. Бьёрн Страуструп в 1988 году писал, что обоснование «объектной ориентированности» чего-либо, в большинстве случаев, сводится к некорректному силлогизму : «X - это хорошо. Объектная ориентированность - это хорошо. Следовательно , X является объектно-ориентированным».

Роджер Кинг аргументированно настаивал, что его кот является объектно-ориентированным. Кроме прочих своих достоинств, кот демонстрирует характерное поведение, реагирует на сообщения, наделён унаследованными реакциями и управляет своим, вполне независимым, внутренним состоянием.

Однако общность механизма обмена сообщениями имеет и другую сторону - «полноценная» передача сообщений требует дополнительных накладных расходов, что не всегда приемлемо. Поэтому во многих современных объектно-ориентированных языках программирования используется концепция «отправка сообщения как вызов метода» - объекты имеют доступные извне методы, вызовами которых и обеспечивается взаимодействие объектов. Данный подход реализован в огромном количестве языков программирования, в том числе C++ , Object Pascal , Java , Oberon-2 . Однако, это приводит к тому, что сообщения уже не являются самостоятельными объектами, и, как следствие, не имеют атрибутов, что сужает возможности программирования. Некоторые языки используют гибридное представление, демонстрируя преимущества одновременно обоих подходов - например, CLOS , Python .

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

Особенности реализации

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

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

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

Взаимодействие объектов в абсолютном большинстве случаев обеспечивается вызовом ими методов друг друга.

Инкапсуляция обеспечивается следующими средствами:

Контроль доступа Поскольку методы класса могут быть как чисто внутренними, обеспечивающими логику функционирования объекта, так и внешними, с помощью которых взаимодействуют объекты, необходимо обеспечить скрытость первых при доступности извне вторых. Для этого в языки вводятся специальные синтаксические конструкции, явно задающие область видимости каждого члена класса. Традиционно это модификаторы public, protected и private, обозначающие, соответственно, открытые члены класса, члены класса, доступные внутри класса и из классов-потомков, и скрытые, доступные только внутри класса. Конкретная номенклатура модификаторов и их точный смысл различаются в разных языках. Методы доступа Поля класса в общем случае не должны быть доступны извне, поскольку такой доступ позволил бы произвольным образом менять внутреннее состояние объектов. Поэтому поля обычно объявляются скрытыми (либо язык в принципе не позволяет обращаться к полям класса извне), а для доступа к находящимся в полях данным используются специальные методы, называемые методами доступа. Такие методы либо возвращают значение того или иного поля, либо производят запись в это поле нового значения. При записи метод доступа может проконтролировать допустимость записываемого значения и, при необходимости, произвести другие манипуляции с данными объекта, чтобы они остались корректными (внутренне согласованными). Методы доступа называют ещё аксессорами (от англ. access - доступ), а по отдельности - геттерами (англ. get - чтение) и сеттерами (англ. set - запись) . Свойства объекта Псевдополя, доступные для чтения и/или записи. Свойства внешне выглядят как поля и используются аналогично доступным полям (с некоторыми исключениями), однако фактически при обращении к ним происходит вызов методов доступа. Таким образом, свойства можно рассматривать как «умные» поля данных, сопровождающие доступ к внутренним данным объекта какими-либо дополнительными действиями (например, когда изменение координаты объекта сопровождается его перерисовкой на новом месте). Свойства, по сути, не более чем синтаксический сахар , поскольку никаких новых возможностей они не добавляют, а лишь скрывают вызов методов доступа. Конкретная языковая реализация свойств может быть разной. Например, в объявление свойства непосредственно содержит код методов доступа, который вызывается только при работе со свойствами, то есть не требует отдельных методов доступа, доступных для непосредственного вызова. В Delphi объявление свойства содержит лишь имена методов доступа, которые должны вызываться при обращении к полю. Сами методы доступа представляют собой обычные методы с некоторыми дополнительными требованиями к сигнатуре .

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

Проектирование программ в целом

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

Объектно-ориентированное проектирование ориентируется на описание структуры проектируемой системы (приоритетно по отношению к описанию её поведения, в отличие от функционального программирования), то есть, фактически, в ответе на два основных вопроса:

  • Из каких частей состоит система ;
  • В чём состоит ответственность каждой из её частей .

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

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

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

Различные ООП-методологии

Компонентное программирование - следующий этап развития ООП; прототип- и класс-ориентированное программирование - разные подходы к созданию программы, которые могут комбинироваться, имеющие свои преимущества и недостатки.

Компонентное программирование

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

Прототипное программирование

Прототипное программирование , сохранив часть черт ООП, отказалось от базовых понятий - класса и наследования.

  • Прототип - это объект-образец, по образу и подобию которого создаются другие объекты. Объекты-копии могут сохранять связь с родительским объектом, автоматически наследуя изменения в прототипе; эта особенность определяется в рамках конкретного языка .
  • Вместо механизма описания классов и порождения экземпляров, язык предоставляет механизм создания объекта (путём задания набора полей и методов, которые объект должен иметь) и механизм клонирования объектов.
  • Каждый вновь созданный объект является «экземпляром без класса». Каждый объект может стать прототипом - быть использован для создания нового объекта с помощью операции клонирования . После клонирования новый объект может быть изменён, в частности, дополнен новыми полями и методами.
  • Клонированный объект либо становится полной копией прототипа, хранящей все значения его полей и дублирующей его методы, либо сохраняет ссылку на прототип, не включая в себя клонированных полей и методов до тех пор, пока они не будут изменены. В последнем случае среда исполнения обеспечивает механизм делегирования - если при обращении к объекту он сам не содержит нужного метода или поля данных, вызов передаётся прототипу, от него, при необходимости - дальше по цепочке.

Класс-ориентированное программирование

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

Производительность объектных программ

Гради Буч указывает на следующие причины, приводящие к снижению производительности программ из-за использования объектно-ориентированных средств:

Динамическое связывание методов Обеспечение полиморфного поведения объектов приводит к необходимости связывать методы, вызываемые программой (то есть определять, какой конкретно метод будет вызываться) не на этапе компиляции, а в процессе исполнения программы, на что тратится дополнительное время. При этом реально динамическое связывание требуется не более чем для 20 % вызовов, но некоторые ООП-языки используют его постоянно. Значительная глубина абстракции ООП-разработка часто приводит к созданию «многослойных» приложений, где выполнение объектом требуемого действия сводится к множеству обращений к объектам более низкого уровня. В таком приложении происходит очень много вызовов методов и возвратов из методов, что, естественно, сказывается на производительности. Наследование «размывает» код Код, относящийся к «конечным» классам иерархии наследования, которые обычно и используются программой непосредственно, находится не только в самих этих классах, но и в их классах-предках. Относящиеся к одному классу методы фактически описываются в разных классах. Это приводит к двум неприятным моментам:

  • Снижается скорость трансляции, так как компоновщику приходится подгружать описания всех классов иерархии.
  • Снижается производительность программы в системе со страничной памятью - поскольку методы одного класса физически находятся в разных местах кода, далеко друг от друга, при работе фрагментов программы, активно обращающихся к унаследованным методам, система вынуждена производить частые переключения страниц.
Инкапсуляция снижает скорость доступа к данным Запрет на прямой доступ к полям класса извне приводит к необходимости создания и использования методов доступа. И написание, и компиляция, и исполнение методов доступа сопряжены с дополнительными расходами. Динамическое создание и уничтожение объектов Динамически создаваемые объекты, как правило, размещаются в куче , что менее эффективно, чем размещение их на стеке и, тем более, статическое выделение памяти под них на этапе компиляции.

Несмотря на отмеченные недостатки, Буч утверждает, что выгоды от использования ООП более весомы. Кроме того, повышение производительности за счёт лучшей организации ООП-кода, по его словам, в некоторых случаях компенсирует дополнительные накладные расходы на организацию функционирования программы. Можно также заметить, что многие эффекты снижения производительности могут сглаживаться или даже полностью устраняться за счёт качественной оптимизации кода компилятором. Например, упомянутое выше снижение скорости доступа к полям класса из-за использования методов доступа устраняется, если компилятор вместо вызова метода доступа использует инлайн-подстановку (современные компиляторы делают это вполне уверенно).

Критика ООП

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

Критические высказывания в адрес ООП:

  • Было показано отсутствие значимой разницы в продуктивности разработки программного обеспечения между ООП и процедурным подходом .
  • Кристофер Дэйт указывает на невозможность сравнения ООП и других технологий во многом из-за отсутствия строгого и общепризнанного определения ООП .
  • Александр Степанов в одном из своих интервью указывал, что ООП «методологически неправильно» и что «…ООП практически такая же мистификация , как и искусственный интеллект …» .
  • Фредерик Брукс указывает, что наиболее сложной частью создания программного обеспечения является «…спецификация, дизайн и тестирование концептуальных конструкций, а отнюдь не работа по выражению этих концептуальных конструкций…». ООП (наряду с такими технологиями как искусственный интеллект, верификация программ , автоматическое программирование , графическое программирование , экспертные системы и др.), по его мнению, не является «серебряной пулей», которая могла бы на порядок величины снизить сложность разработки программных систем. Согласно Бруксу, «…ООП позволяет сократить только привнесённую сложность в выражение дизайна. Дизайн остаётся сложным по своей природе…» .
  • Эдсгер Дейкстра указывал: «…то, о чём общество в большинстве случаев просит - это эликсир от всех болезней. Естественно, „эликсир“ имеет очень впечатляющие названия, иначе будет очень трудно что-то продать: „Структурный анализ и Дизайн“, „Программная инженерия“, „Модели зрелости“, „Управляющие информационные системы“ (Management Information Systems), „Интегрированные среды поддержки проектов“, „Объектная ориентированность“, „Реинжиниринг бизнес-процессов “…» .
  • Никлаус Вирт считает, что ООП - не более чем тривиальная надстройка над структурным программированием [ ] , и преувеличение её значимости, выражающееся, в том числе, во включении в языки программирования всё новых модных «объектно-ориентированных» средств, вредит качеству разрабатываемого программного обеспечения.
  • Патрик Киллелиа в своей книге «Тюнинг веб-сервера» писал: «…ООП предоставляет вам множество способов замедлить работу ваших программ…».
  • Известная обзорная статья проблем современного ООП-программирования перечисляет некоторые типичные проблемы ООП [ ] .
  • В программистском фольклоре получила широкое распространение критика объектно-ориентированного подхода в сравнении с функциональным подходом с использованием метафоры «Королевства Существительных » из эссе Стива Йегги .

Если попытаться классифицировать критические высказывания в адрес ООП, можно выделить несколько аспектов критики данного подхода к программированию.

Критика рекламы ООП Критикуется явно высказываемое или подразумеваемое в работах некоторых пропагандистов ООП, а также в рекламных материалах «объектно-ориентированных» средств разработки представление об объектном программировании как о некоем всемогущем подходе, который магическим образом устраняет сложность программирования. Как замечали многие, в том числе упомянутые выше Брукс и Дейкстра, «серебряной пули не существует» - независимо от того, какой парадигмы программирования придерживается разработчик, создание нетривиальной сложной программной системы всегда сопряжено со значительными затратами интеллектуальных ресурсов и времени. Из наиболее квалифицированных специалистов в области ООП никто, как правило, не отрицает справедливость критики этого типа. Оспаривание эффективности разработки методами ООП Критики оспаривают тезис о том, что разработка объектно-ориентированных программ требует меньше ресурсов или приводит к созданию более качественного ПО. Проводится сравнение затрат на разработку разными методами, на основании которого делается вывод об отсутствии у ООП преимуществ в данном направлении. Учитывая крайнюю сложность объективного сравнения различных разработок, подобные сопоставления, как минимум, спорны. С другой стороны, получается, что ровно так же спорны и утверждения об эффективности ООП. Производительность объектно-ориентированных программ Указывается на то, что целый ряд «врождённых особенностей» ООП-технологии делает построенные на её основе программы технически менее эффективными, по сравнению с аналогичными необъектными программами. Не отрицая действительно имеющихся дополнительных накладных расходов на организацию работы ООП-программ (см. раздел «Производительность» выше), нужно, однако, отметить, что значение снижения производительности часто преувеличивается критиками. В современных условиях, когда технические возможности компьютеров чрезвычайно велики и постоянно растут, для большинства прикладных программ техническая эффективность оказывается менее существенна, чем функциональность, скорость разработки и сопровождаемость. Лишь для некоторого, очень ограниченного класса программ (ПО встроенных систем, драйверы устройств, низкоуровневая часть системного ПО, научное ПО) производительность остаётся критическим фактором. Критика отдельных технологических решений в ООП-языках и библиотеках Эта критика многочисленна, но затрагивает она не ООП как таковое, а приемлемость и применимость в конкретных случаях тех или иных реализаций её механизмов. Одним из излюбленных объектов критики является язык C++, входящий в число наиболее распространённых промышленных ООП-языков.

Объектно-ориентированные языки

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

Как правило, объектно-ориентированный язык (ООЯ) содержит следующий набор элементов:

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

Некоторые языки добавляют к указанному минимальному набору те или иные дополнительные средства. В их числе:

  • Конструкторы, деструкторы, финализаторы;
  • Свойства (аксессоры);
  • Индексаторы;
  • Средства управления видимостью компонентов классов (интерфейсы или модификаторы доступа, такие как public, private, protected, feature и др.).

Одни языки отвечают принципам ООП в полной мере - в них все основные элементы являются объектами, имеющими состояние и связанные методы. Примеры подобных языков - Smalltalk , Eiffel . Существуют гибридные языки, совмещающие объектную подсистему в целостном виде с подсистемами других парадигм как «два и более языка в одном», позволяющие совмещать в одной программе объектные модели с иными, и размывающие грань между объектно-ориентированной и другими парадигмами за счёт нестандартных возможностей, балансирующих между ООП и другими парадигмами (таких как множественная диспетчеризация , параметрические классы, возможность манипулировать методами классов как самостоятельными объектами, и др.). Примеры таких языков: CLOS , Dylan , OCaml , Python , Ruby , Objective-C . Однако, наиболее распространены языки, включающие средства эмуляции объектной модели поверх более традиционной императивной семантики. Алан Кэй назвал такие языки «склеиванием возможностей» (англ. agglutination of features ) в противовес «чистоте стиля» (англ. crystalization of style ) языков, воплощающих некую парадигму непосредственно . Примеры таких языков -

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

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

Основные положения объектной модели

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

. (object-oriented analysis, ООА) направлен на создание моделей реальной действительности на основе объектно-ориентированного мировоззрения.

Объектно-ориентированный анализ - это методология, при которой требования к системе воспринимаются с точки зрения классов и объектов, выявленных в предметной области.

. (object-oriented design, ООД)

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

Объектно-ориентированное проектирование - это методология проектирования, соединяющая в себе процесс объектной декомпозиции и приемы представления логической и физической, а также статической и динамической моделей проектируемой системы.

В данном определении содержатся две важные части: объектно-ориентированное проектирование

1) основывается на объектно-ориентированной декомпозиции;

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

Именно объектно-ориентированная декомпозиция отличает объектно-ориентированное проектирование от структурного, в первом случае логическая структура системы отражается абстракциями в виде классов и объектов, во втором - алгоритмами.

. (object-oriented programming, OOП)

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

В данном определении можно выделить три части:

1) OOП использует в качестве базовых элементов объекты, а не алгоритмы;

2) каждый объект является экземпляром какого-либо определенногокласса;

3) классы организованы иерархически .

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

Выделяют пять основных разновидностей стилей программирования, которые перечислены ниже вместе с присущими им видами абстракций:

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

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

    абстрагирование;

    инкапсуляция;

    модульность;

    иерархия.

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

    типизация;

    параллелизм;

    сохраняемость.

Называя их дополнительными, имеется в виду, что они полезны в объектной модели, но не обязательны.

Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя.

Абстракция основывается на понятиях клиента и сервера.

Клиентом называется любой объект, использующий ресурсы другого объекта (называемогосервером ).

Мы будем характеризовать поведение объекта услугами, которые он оказывает другим объектам, и операциями, которые он выполняет над другими объектами. Такой подход концентрирует внимание на внешних проявлениях объекта и приводит к идее контрактной модели программирования, когда внешнее проявление объекта рассматривается с точки зрения его контракта с другими объектами, в соответствии с этим должно быть выполнено и его внутреннее устройство (часто во взаимодействии с другими объектами). Контракт фиксирует все обязательства, которые объект-сервер имеет перед объектом-клиентом. Другими словами, этот контракт определяетответственность объекта, то есть то поведение, за которое он отвечает.

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

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

Абстракция и инкапсуляция дополняют друг друга: абстрагирование направлено на наблюдаемое поведение объекта, а инкапсуляция занимается внутренним устройством. Чаще всего инкапсуляция выполняется посредством скрытия информации, то есть маскировкой всех внутренних деталей, не влияющих на внешнее поведение. Обычно скрываются и внутренняя структура объекта, и реализация его методов. Практически это означает наличие двух частей в классе: интерфейса и реализации. Интерфейс отражает внешнее поведение объекта, описывая абстракцию поведения всех объектов данного класса. Внутренняяреализация описывает представление этой абстракции и механизмы достижения желаемого поведения объекта. Принцип разделения интерфейса и реализации соответствует сути вещей: в интерфейсной части собрано все, что касается взаимодействия данного объекта с любыми другими объектами; реализация скрывает от других объектов все детали, не имеющие отношения к процессу взаимодействия объектов.

Модульность - это свойство системы, которая была разложена на внутренне связные, но слабо связанные между собой модули.

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

Свести воедино столь разноречивые требования довольно трудно, но главное – это уяснить, что вычленение классов и объектов в проекте и организация модульной структуры есть независимые действия. Процесс вычленения классов и объектов составляет часть процесса логического проектирования системы, а деление на модули - этап физического проектирования. Разумеется, иногда невозможно завершить логическое проектирование системы, не завершив физическое проектирование, и наоборот. Два этих процесса выполняются итеративно.

Иерархия - это упорядочение абстракций, расположение их по уровням.

Основными видами иерархических структур применительно к сложным системам являются структура классов (иерархия "is-a") и структура объектов (иерархия "part of").

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

Если иерархия "is а" определяет отношение "обобщение/специализация", то отношение "part of" (часть) вводит иерархию агрегации. В иерархии "part of" класс находится на более высоком уровне абстракции, чем любой из использовавшихся при его реализации.

Типизация - это способ защититься от использования объектов одного класса вместо другого, или по крайней мере управлять таким использованием.

Параллелизм - это свойство, отличающее активные объекты от пассивных.

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