Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

4966

.pdf
Скачиваний:
3
Добавлен:
13.11.2022
Размер:
854.74 Кб
Скачать

31

2.1.1. Технологии объектно-ориентированного анализа

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

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

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

32

Найденные указанным способом сущности следует выписать в виде перечня (нумерованного списка). Аналогичным образом следует поступить со свойствами сущностей (параметров) и операциями (функциями). Выделенные сущности следует рассортировать по связям: сущность–свойства–операция. Каждая отдельная полученная связь «сущность–свойства–операция» будет являться объектом. Именем объекта будет являться наименование сущности. Пример объектной декомпозиции решения задачи «Идентификация клиента» из информационной системы «Автоматизация кассового обслуживания клиентов банка» приведён в Приложении А.

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

Для создания классов применяется один из методов классификации объектов предметной области:

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

2)концептуальная кластеризация (формируются концептуальные описания классов, а затем классифицируются сущности в соответствии с этим описанием);

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

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

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

33

Для класса «внутренние документы» подклассом могут являться «приказы». Для класса «входящие документы» подклассом могут являться «факсы» и «электронные письма».

Наиболее сложной для понимания и применения является теория прототипов, так как формализации подлежат объекты, которые «которые не имеют ни чётких свойств, ни чёткого определения» [2]. Значимыми признаками принадлежности к классу в этом случае будут являться свойства объекта, определяемые при взаимодействии с другими объектами (свойства взаимодействия). Например, к классу «средство оплаты» можно отнести объекты, удовлетворяющие требованиям некоторого эквивалента тому, за что оплата производится, как то: наличная оплата, безналичная оплата, бартер, взаимозачёт, и т.д.

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

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

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

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

34

Контрольные вопросы и задания

1.Что является результатом формального описания предметной области?

2.Что является результатом объектной декомпозиции?

3.Чем объясняется детерминированная реакция объектов на события?

4.Какие требования к языку программирования предъявляют правила описания состава классов?

5.В чём заключается сложность формального описания предметной области ?

6.В чём заключается метод неформального описания предметной области?

7.В чём выражается специфика итерационной модели проектирования на этапе анализа информационной системы?

8.В чём заключается метод классической категоризации?

9.В чём заключается метод концептуальной кластеризации?

10.В чём заключается метод классификации на основании теории прототипов?

11.Приведите примеры классификации объектов.

12.В чём заключается смысл полиморфизма?

13.В чём заключается сходство и различие способов классификации?

2.2. Программная реализация объектно-ориентированной технологии

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

2.2.1. Объектно-ориентированные дополнения к процедурным языкам программирования и абстрактные типы данных

Все процедурные языки программирования являются строго типизированными. Это означает, что в качестве операндов стандартных встроенных операций языков программирования используются только базовые неизменяемые типы языка, например: целый int; вещественный float и т.д. Соблюдение правил жёсткой типизации всех операций и функций является основным условием их выполнения. При выполнении вызова функций в качестве параметров могут быть использованы только базовые типы переменных языка программирования. В том

35

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

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

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

1)Ф_И_О – массив символьных переменных;

2)№_группы – массив символьных переменных;

3)№_студ_билета – массив символьных переменных.

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

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

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

36

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

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

Пример перегрузки базовых операторов «+» и «*» для случая абстрактных типов данных в качестве операндов (написан на псевдо-языке программирования) приведён на рисунке 6.

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

Тип_результата_сложения Функция_перегрузки_знака+(слагаемое_матрица1, слагаемое_матрица2){описание способа сложения матриц 1 и 2 и возврат результата}

*************************************************************

Тип_результата_умножения Функция_перегрузки_знака* (множитель_число_А, множитель _матрица_В){описание способа перемножения числа А и матрицы_В и возврат результата}

Рисунок 6 – Пример перегрузки базовых операторов «+» и «*» для случая абстрактных типов данных в качестве операндов

37

Пример перегрузки базового оператора «+» на языке С++ для случая сложения комплексных чисел приведён на рисунке 7. В данном примере следует обратить внимание на типы формальных параметров: complex a и complex b функции перегрузки operator+(). Именно этот факт является определяющим для «контекста» вызова данной функции, что однозначно направит развитие событий по сценарию, описанному внутри функции перегрузки операции «+» :

complex operator+(complex a,complex b).

Втом случае, если операндами оператора «+» будут являться переменные базового типа (например int), то контекст вызова оператора перегрузки будет иным, и, следовательно, развитие событий пойдёт по стандартному сценарию, описанному для базовых типов данных.

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

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

 

 

 

38

 

 

typedef struct complex {float re,im};

//объявление состава структуры

 

 

 

//для комплексного числа

complex operator+(complex a,complex b) //интерфейс функции пере-

 

 

 

//грузки оператора «+»

{ a.re=a.re + b.re;

//описание правил сложения

a.im=a.im + b.im;

//комплексных чисел

return a;

}

//по элементам

//-----------------------

 

реализация в программе ------------------------------

void main()

 

 

{ complex a,b;

//объявление комплексных переменных

a.re=1.0;

 

//инициализация комплексных переменных

a.im=-1.0;

 

 

b.re=2.0;

 

 

 

b.im=1.0;

 

 

 

a=a+b;}

//выполнение сложения при котором выполняется

//перегрузка оператора «+» в контексте комплексных чисел, //т.е. при наличии формальных параметров а и в //имеющих тип «структура complex»

Рисунок 7 – Пример перегрузки базового оператора «+» для случая сложения комплексных чисел

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

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

39

2.2.2. Инкапсуляция классов

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

Следовательно, для реализации совокупности данных и функций в виде связок: «данные об объекте» + «функции объекта» + «описание реакции объекта на события» требуется некий новый механизм. Такой механизм имеет место в объ- ектно-ориентированных языках ( в т.ч. и в языке С++) и носит название «инкапсуляция». Иначе «инкапсуляция» – это объявление новых абстрактных типов данных, в состав которых входят атрибуты, функции и методы. Под методами следует понимать описание реакции объекта данного абстрактного типа на возможные события.

Абстрактные типы данных, имеющие одинаковые составные члены (атрибуты в виде переменных и методы в виде функций), объединяются в группы однородных типов (классы). Таким образом описать класс – это означает создать некий абстрактный тип данных, содержащий общие (для группы однородных объектов) элементы. Именно процесс описания такого класса называется «инкапсуляцией» (раскрытием содержимого класса) и, по сути, является аналогом объявления любой переменной. Инкапсуляций класса называют также интерфейс класса. Пример объявления класса (на языке С++) приведён на рисунке 8.

 

40

 

 

Int x;

//объявление переменной х базового типа «int»

class ABC{int y; ABC();int function(int);}; // объявление абстрактного типа

// «АВС»

//class – ключевое слово, означает начало процесса инкапсуляции;

//АВС – наименование класса, y – атрибут класса;

//ABC()– метод класса, отвечает за реакцию объектов данного // типа на события;

//int function(int) – функция класса, расширяет возможности класса.

Рисунок 8 – Пример объявления класса

2.2.3.Интерфейс класса и правила доступа к элементам класса

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

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

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

1)закрытые элементы – зона видимости ограничена интерфейсом класса;

2)открытые элементы – зона видимости ограничена программным модулем.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]