скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыРеферат: Программирование ориентированное на объекты

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

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

Пример1.

      TYPE POINT = RECORD X,Y: INTEGER END;

           Point = RECORD Y,X: INTEGER END;

       VAR   A: ARRAY[1..2] OF WORD;

             P: POINTER TO POINT;

             p: POINTER TO Point;

             X,Y: INTEGER;

     BEGIN X:=1; Y:=5;

           P:=ADR(A);                         (*1*)

              P^.X:=X; P^.Y:=Y;               (*2*)

           p:=ADDRESS(P);                     (*3*)

              X:=p^.X; Y:=p^.Y                (*4*)

Этот пример реализует "трансформацию" объекта-точки с де­кар­то­вы­ми координататами (1,5) в объект-точку с координатами (5,1). В про­грамме задан элемент хранения А размером в два слова, "маска" POINT, "привязанная" к указателю Р, и "маска" Point, связанная с ограниченным указателем р. Операция (1) связана с "наложением" мас­­ки POINT на элемент хранения А и записью "через трафарет" зна­­­че­ний координат точки в область памяти А. Операция (3) свя­за­на с на­ложением на ту же область памяти маски (трафарета) Point и чте­ни­ем координат точки через новый трафарет. Таким образом, один и тот же объект, размещенный в А, интерпретируется в этом примере двояко: как точка с координатами (1,5) и симметричная ей точ­ка с ко­ординатами (5,1). Заметим, что реально никакого пре­об­ра­зования координат не происходит, - все определяетсся струк­ту­рой трафарета - маски, через которуюю мы смотрим на объект. (Расссматривая этот пример, ответьте на вопрос, почему для записи операторов (2) и (4) не используется присоединение?)

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

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

    VAR C: ARRAY [1..100] OF CARDINAL;

        P: POINTER TO ARRAY [1..200] OF CHAR;

        CH: ARRAY [1..200] OF CHAR;

    BEGIN                                                                                                                                                                  

      P := ADR(C); FOR I:=1 TO 200 DO CH[I]:=P^[I] END;...

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

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

Процедурный тип (или сигнатура, см. pазд. II) определяет мно­же­ст­во возможных действий, видов активности. Например,

          TYPE Действие = PROCEDURE (Станок);

определяет сигнатуру для класса Станок. Пусть множество дей­ст­вий над Станком ограничивается двумя:

               PROCEDURE Включить (С: Станок);

               PROCEDURE Выключить (С: Станок); .

Декларация VAR D: Действие определяет объект класса Действие. Та­кой объект может хранить потенциально возможное действие над Станком (т.е. "помнить", что нужно сделать) и (в подходящее вре­мя) акти­визироваться (самоинтерпретироваться) по отношению к стан­ку:

               VAR D: Действие; C: Станок;

               BEGIN...

                    D:=Включить;...

                    D(C);... D:= Выключить;... D(C); .

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

V. СОЗДАНИЕ / УНИЧТОЖЕНИЕ ОБЪЕКТОВ

"Время жизни" объекта. - Классы памяти. - Управление ди­нами­чес­кой памятью. - Фрагментация. - Проблемы "висячих" ссылок и мусора. - Автоматическая память. - Локальная среда. - Активации объекта.

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

Создание объекта следует интерпретировать как выделение па­мя­ти под его элемент хранения. Такая интерпретация подразумевает раз­­де­ле­ние всего рабочего пространства памяти ЭВМ на две ка­те­го­рии, два класса - статическую память и динамическую. Первый класс памяти, как следует из этого контекста, полностью на­хо­дит­ся под упpав­ле­ни­ем тpанслятоpа и pаспpеделяется под статические объ­екты, су­ще­ству­ю­щие в системе постоянно. Например, декларация

              VAR A: POINTER TO CARDINAL;

                  B: CARDINAL;

сообщает транслятору о необходимости "зарезервировать" в клас­се ста­тической памяти два слова под элемент хранения объекта с именем А и одно слово под элемент хранения объекта с именем В.

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

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

Управление динамической памятью для пасссивных объектов (в даль­нейшем просто динамической памятью) реализуется на основе двух ос­новных процедур (обычно импортируемых из системного модуля):

       PROCEDURE ALLOCATE (VAR A: ADDRESS; N: CARDINAL);       

       PROCEDURE DEALLOCATE (VAR A: ADDRESS; N: CARDINAL); .

Здесь А - свободный указатель, который укажет на выделенную об­­ласть памяти (элемент хранения размером N байт) при вызове ALLOCATE и получит значение NIL (т.е. никуда не будет указывать) при освобождении этой области "из-под" А путем вызова DEALLOCATE.

 Использование ограниченных указателей делает во многих от­но­ше­ни­ях целесообразным использование специальных вызовов: NEW(P) и  DISPOSE(P), где VAR P: POINTER TO <Объект>. (NEW и DISPOSE - псе­в­до­процедуры, их вызовы транслируются в вызовы ALLOCATE и DE­AL­LO­CA­TE соответственно). Использование NEW и DISPOSE позволяет из­бежать многих семантических ошибок, связанных с различными значениями N в последовательности вызовов ALLOCATE...DEALLOCATE, определяющей соз­дание/уничтожение одного и того же объекта.

В целом последовательность вызовов  NEW...DISPOSE (или соот­вет­ст­­венно ALLOCATE...DEALLOCATE), в общем случае полностью оп­ре­­де­ля­е­мая логикой программиста, порождает ряд проблем, свя­зан­ных с ор­га­­низацией и распределением свободного пространства ди­на­мической па­мяти. Одной из таких проблем является проблема фраг­ментации. Эф­фект фрагментации заключается в том, что рабочая область ди­на­ми­чес­кой памяти "дро­бится" на части - фрагменты раз­лич­ной длины. Какие-то из них "за­няты" - используются про­г­рам­ми­стом под элементы хранения его объ­ектов, какие-то "свободны", при­чем характер че­ре­до­вания сво­бод­ных и занятых фрагментов в общем случае может быть со­вершенно произвольным. Любой запрос программиста на создание но­во­го объекта приводит к тому, что сис­тема управления динамической па­мятью "подбирает" ему фраг­мент, подходящий по размерам. Правила та­кого подбора могут быть различны, но общая закономерность одна: та­кой фрагмент должен иметь размер, не меньший, чем запрашиваемый про­граммистом. Если подходящий фрагмент имеет больший размер, чем требуется, в при­клад­ную программу будет отдана его часть, котоpая те­­пеpь будет pас­сматpиваться системой как занятый фpагмент, а ос­та­­ток ос­та­нет­ся в свободной зоне в качестве свободного фpагмента. При этом проблема фрагментации заключается в том, что эффект "дро­бле­ния" может привести к тому, что в свободной зоне будет на­хо­дить­ся мно­жество "маленьких" разрозненных свободных фрагментов, в со­во­куп­ности составляющих достаточный объем. Тем не менее, не­с­мо­тря на такой объем, запрос программиста на новый элемент памяти мо­жет получить отказ по причине отсутствия целого подходящего эле­мен­та. Ниже приведен фрагмент программы и схема распределения ди­­на­мической памяти, иллюстрирующие эффект фрагментации. При этом для простоты предполагается, что общий объем ди­на­ми­чес­кой памяти составляет 20 байт.

        TYPE Треугольник = POINTER TO Фигура_1

             Фигура_1 = RECORD

                  Сторона_1, Сторона_2, Сторона_3:CARDINAL

             END;

             Четырехугольник = POINTER TO Фигура_2;

              Фигура_2 = RECORD

                  Сторона_1, Сторона_2, Сторона_3, Сторона_4:

                                                    CARDINAL

               ЕND

        VAR T1, T2: Треугольник; М1, М2: Четырехугольник;

        BEGIN   NEW(T1);... NEW(M1);... NEW(T2);...

                DISPOSE(T1);... DISPOSE(T2); NEW(M2);...                

           ┌───────────────────┐ ─┐

           │       WORD        │  │

           ├───────────────────┤  │

           │                   │   >  Свободный фрагмент, ранее

           ├───────────────────┤  │     использованный под

           │                   │  │          объект Т1^

           ├───────────────────┤ ─┘─┐

           │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│    │

           ├───────────────────┤    │

           │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│    │

           ├───────────────────┤     > Фрагмент, занятый

           │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│    │    под объект М1^

           ├───────────────────┤    │

           │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│    │

Страницы: 1, 2, 3, 4, 5, 6, 7


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.