Лекция 10 (Лекции (2009) (Саша Федорова))

2019-09-19СтудИзба

Описание файла

Файл "Лекция 10" внутри архива находится в папке "Лекции (2009) (Саша Федорова)". Документ из архива "Лекции (2009) (Саша Федорова)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "Лекция 10"

Текст из документа "Лекция 10"

11


Лекция 10.

В прошлый раз мы рассмотрели модульную структуру Modula-2, Delphi, Oberon.

В Delphi и в Turbo Pascal схема та же самая, только UNIT и Implementation.

Однако отсутствует стадия потенциальной видимости: для использования модуля обязательно надо писать

uses M1;

Существует единая конструкция модуля, но структура пространства имен та же самая.

MODULE M1;

TYPE T * =

Единственная форма импорта в Оберон:

IMPORT M1;

(означает подкачку соответствующей таблицы имен)

В результате процесс трансляции крайне прост.

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

Существует два подхода к проектированию древовидной иерархии модулей:

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

  1. снизу вверх(bottom-up- подход) – сначала проектируются самые нижние модули – они в данной иерархии инкапсулированы и ничего не знают о вышестоящих модулях. Подставляют виртуальные сервисы универсального характера, которые нужны всем.(P. S. Современные объектно-ориентированные системы в данном случае предлагают нам сетевые структуры.) на их базе строятся сервисные модули более высоких уровней – и так далее, пока не дойдем до единого главного модуля всей системы. Недостаток такого подхода: мы никогда точно не знаем, что нам понадобится в будущем.

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

В случае подхода top-down в процессе проектирования происходит постепенное уточнение. При двух этих подходах структура проекта, очевидно, будет различной: при проектировании снизу-вверх проектные модули будут более универсальными, а при проектировании сверху вверх – более специфичны.

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

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

Модульная структура языка ADA

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

Пакет состоит из двух частей: спецификации пакета (аналог модуля определения в Modula-2) и тела пакета (аналог IMPLEMENTATION в Modula-2).

//спецификация пакета

package M is

определение (типов, переменных, констант+ заголовки процедур)

end M;

//тело пакета

package body is

//реализация всех процедур и функций

end M

В Modula-2 тело пакета, как и модуль реализации, предназначается только для реализации.

Отличие Ады в том, что пакеты могут вкладываться.

Замечание. Первый аналог логического модуля – это процедура или функция. Уже начиная с Алгол-60 процедур и функции можно помещать внутрь других процедур и функций.

Пример (Паскаль):

procedure P;

var X1, X2: T; //доступны для вложенной процедуры PIN

procedure PIN;

var X:T1;

…………………….

end

end

В Аде модули также могут быть вложены друг в друга.

Все стандартные имена в Ада берутся из стандартного пакета package STANDART. Пользовательские пакеты вкладываются внутрь него.

При этом «вложения» устроены таким образом, что если вложены друг в друга спецификации, то вложены и тела.

STANDART

package M1 is

package M12 is

………………………………………………

end M12

package M2 is

package M21 is

………………………………………………

end M21

………………………….

end M2

………… ……………………….

end M1

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

В пакете М1 видимость обьектов из М12 потенциальная.

Имена экспортируются во вне, но доступны они лишь потенциально. Очевидно, этого недостаточно.

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

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

  2. для иллюстрации следующей проблемы приведем пример:

Пример:

имя enum_T имя константы

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

С точки зрения модели видимости, в Аде есть препятствие к перегрузке операций: все на свете должно быть определено внутри некоторого пакета. Пусть у нас есть тип vector, для которого мы перекрыли операцию «+». Но она, кроме модуля, в котором была переопределена, никому не нужна. Выходит, что для доступа к данной операции нужно будет уточнять доступ. А уточнение работает только в префиксной форме (*). Т. е., чтобы операция была видна внутри модуля vector, где она описана, надо написать так:

a, b, c: vectors.Vector;

a:=vectors:”+”(b, c);

Очевидно, смысл перегрузки операций пропадает. Такая запись равносильна, к примеру, записи

Vectors.Plus(b, c);

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

use vectors;

a, b, c: vectors;

a, b, c: Vector;

a:=b+c; //и все будет Ok! 

(*)Любую перегруженную операцию можно употреблять как в префиксной:a=b+c;

так и в постфиксной форме:

a=operator+ (b, c);

А если аргументы операции +, к примеру, не видимы непосредственно?

(С++ в этом случае разрешает неявный импорт: неявный поиск в других пространствах имен(using namespace)

Рассмотрим такую ситуацию:

Пусть у нас есть пакета: М и М1, в каждых из которых есть имя Х, и, написав в программе

use M;

use M1;

мы обращаемся к имени Х. – возникает конфликт имен!

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

В Ada семантика программы будет меняться в зависимости порядка модулей (и в зависимости от порядка модулей по-разному разрешается конфликт имен!).

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

(неявный импорт:

В С# using

В Java import имя_пакета;//ошибка-нельзя экспортировать пакет в Java!

import имя_класса; //Ok!

import имя_пакета.* ;//Ok! – мы импортируем все имена из пакета

В Pascal uses

Итак, как мы выяснили, use в Ada – крайне ненадежная конструкция: программы продолжают компилироваться, но их семантика при этом сильно меняется. Тут помогает переименование:

a renames b; //a теперь описано уже тут

Можно также переименовать операцию «+»:

function “+”(X, Y: vectors.Vector) return vector renames vectors;

Еще пример переименования:

V renames vectors.Vector

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

Один из важнейших ресурсов Ада – определение новых типов данных.

DEFINITION MODULE STACKS;

TYPE stack=RECORD

B: Array[0..N] of T;

TOP: [0..N];

END; //конец записи

PROCEDURE PUSH(VAR S: STACK; X: T);

PROCEDURE POP(VAR S:STACK; VAR X: T);

Пусть внутри модуля находятся процедуры

IsEmpty

IsFull

PROCEDURE Init(VAR S: stack);//(инициализация стека)

и переменная

VAR done: Boolean;//сообщающая последний результат операции над стеком

END STACKS;

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

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

PROCEDURE Init*(VAR S:stack);

VAR DONE * BOOLEAN

PROCEDURE GetError(): Boolean;

Но тогда переменная DONE может быть испорчена. Функция Get Error, очевидно, должна возвращать значение переменной DONE. Но вызов функции – это нелокальный переход, и с точки зрения современной архитектуры он плох.

(Стандартный прием увеличения быстродействия – конвейеризация. Глубина конвейера в современных процессорах – не более 15 инструкций. Если вычисления выполняются последовательно, конвейер заполняется. С локальными переходами процессор «умеет» бороться, а с нелокальными – нет, они сильно снижают эффективность конвейера).

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

package Stacks is

type stack is

record

b: array(0..N) of T;

top: integer :=0;//при объявлении записи top всегда будет обнуляться

procedure Push(s: inout Stack; X: in T);//процедура

Как лучше реализовать Pop – как процедуру или как функцию?

PROCEDURE POP(VAR S:stack): T;//в ADA так писать нельзя!!!!!!

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

Изначально в Аде могут быть:

  • функции

  • процедуры

  • процедуры, возвращающие значение – это функции с побочным эффектом! (В конечном итоге от этого отказались, т.к. разрешить функции менять свои формальные параметры очень тяжело)

Таким образом, единственная возможность – определить Pop как процедуру:

Procedure POP(S: inout stack; X: out T);

………….

End Stacks;

Заметим, что возможна ситуация

X: Stack;

X.top=1;//top, напомним, автоматически инициализируется нулем, а мы тут кладем в нее единицу, целостность стека нарушается!

Структура типа очень важна, а она не инкапсулирована!

Поэтому переходим к следующей главе.

Глава 7. Инкапсуляция и абстрактный тип данных

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

Сосредоточимся на механизме реализации инкапсуляции.

РОРИ – принцип разделения интерфейса и реализации.

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

  • единицы инкапсуляции: тип или экземпляр типа

  • атомы инкапсуляции: отдельные поля и члены типа или весь тип.

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

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

Ада и Modula-2 инкапсулируют целиком весь тип: такая тактика вынуждает нас к полной инкапсуляции.

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5224
Авторов
на СтудИзбе
426
Средний доход
с одного платного файла
Обучение Подробнее