Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Объектно-ориентированное программирование и программная инженерия

Покупка
Артикул: 830734.01.99
Доступ онлайн
1 000 ₽
В корзину
В этом курсе переместимся на передний край современной технологии программирования и посмотрим, какие преимущества можно получить, если использовать всю мощь ОО-идей. Первые лекции описывают многие механизмы наследования, включая полиморфизм, динамическое связывание, множественное наследование, понятие ограниченной универсальности. Затем исследуются новые средства, которые добавляют существенную выразительную силу объектному каркасу. В Eiffel они называются агентами (терминология не устоялась, в других языках их называют делегатами, замыканиями). Рассмотрение агентов сопровождается знакомством с основами лямбдаисчисления. Последующие лекции представляют проектирование, управляемое событиями, - гибкую архитектуру программных проектов, дополняющую наши прежние структуры управления. В 2-х последних лекциях рассматриваются требования, необходимые для перехода на новый уровень, перехода от простого программирования к профессиональной разработке ПО промышленного качества. Этот уровень называется программной инженерией.
Мейер, Б. Объектно-ориентированное программирование и программная инженерия : краткий курс / Б. Мейер. - Москва : ИНТУИТ, 2016. - 208 с. - Текст : электронный. - URL: https://znanium.ru/catalog/product/2147044 (дата обращения: 29.11.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов

                                    
Объектно-ориентированное программирование и
программная инженерия

2-е издание, исправленное

Мейер Б.

Национальный Открытый Университет “ИНТУИТ”
2016

2

Объектно-ориентированное программирование и программная инженерия/ Б. Мейер - М.:
Национальный Открытый Университет “ИНТУИТ”, 2016

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

(c) ООО “ИНТУИТ.РУ”, 2012-2016
(c) Мейер Б., 2012-2016

3

Введение

У слушателей Интернет университета появилась уникальная возможность не только
пройти курсы лекций по замечательной книге “Почувствуй класс. Учимся
программировать хорошо с объектами и контрактами”, но и увидеть, услышать автора
книги – профессора Бертрана Мейера. Отвечая на вопросы профессора Владимира
Биллига – переводчика книги, Бертран Мейер объясняет, почему этот курс может быть
интересен студентам, приступающим к изучению информатики, чем книга может быть
интересна преподавателям, читающим подобный курс, чем книга и курсы по ней могут
быть интересны профессионалам ИТ. Он рассказывает о том, как учат информатике в
ЕТН – одном из старейших учебных заведений Европы, об особенностях этого курса. В
беседе затрагиваются и другие вопросы, в частности Бертран говорит о своей любви к
русскому языку и о том, как он, будучи школьником, учил русский язык. Эта лекция
является хорошим введением в курс, полученным “из первых уст”.

Видео

4

Наследование и полиморфизм

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

Мир (готовы ли вы уже в самом начале лекции погрузиться в водовороты жизни?)
полон беспорядка. Возможно, Природа ненавидит беспорядок, а может быть — и нет, я
в этом не уверен. Ваша точка зрения во многом зависит от того, кого вы читали —
Платона, Аристотеля, Канта. Наука определенно борется с беспорядком. Здравые
рассуждения о мире требуют порядка.

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

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

Чтобы стать науками, ботанике и зоологии нужен был Линней, который в 18-м
столетии создал эффективную классификацию живых существ. Биологическая
таксономия говорит нам, что дельфины принадлежат виду, называемому по латыни
Delphinius delphis, они включены в род Delphinius, который сам является частью —
пропуская некоторые уровни классификации — отряда китовых из класса
млекопитающих, принадлежащего, вне всякого сомнения, царству животных1).

Объекты в этом случае естественные, а классификация искусственная.

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

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

5

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

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

Подобно математикам, мы, программисты, имеем дело с абстрактными объектами —
творениями нашего воображения — и не можем обвинять никого, кроме себя, при
обнаружении беспорядка в мире наших объектов. И нам, как и всем, нужно
преобразовать беспорядок, создавая подобие порядка. Возможно, нам это нужно
больше, чем кому-либо, поскольку мы являемся чемпионами в создании энтропии, ибо
наши программы способны создать самую немыслимую путаницу, которая только
возможна. Говорят, что “человеку свойственно ошибаться, но путаницу несомненно
создает компьютер” ; добавим к этому: “или компьютерный программист”.

Чтобы справиться с беспорядком, подобно всем наукам, мы можем использовать
таксономию. Мы можем объединить наши объекты в категории и рассматривать
иерархические отношения между этими категориями. Как дельфин, будучи
млекопитающим, является позвоночным животным, как поле в математике является
кольцом, так и такси, моделируемое в нашей программе, является транспортным
средством и как таковое является движущимся городским объектом. Пешеход также
является движущимся городским объектом, но не является транспортным средством.
Наследование позволит нам делать выводы о таких отношениях, как “является” (“is—
a”) и использовать таксономии для структурирования нашего ПО.

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

Такси и транспортные средства

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

6

Наследуемые компоненты

Класс TAXI из TRAFFIC обеспечивает — вы можете это проверить — такой компонент,
как

take (from_location,to_location: LOCATION)
    — Доставить пассажира из from_location в to_location

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

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

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

Где же находятся соответствующие свойства? Ответ можно найти, взглянув в начало
объявления класса:

note
…
 class
  TAXI
inherit
  VEHICLE
feature
 ... Оставшаяся часть класса...

Класс TAXI наследует от VEHICLE ; и в самом деле, если посмотреть на класс VEHICLE, то
можно найти команды load, для посадки пассажиров в транспортное средство, так же
как и unload — для высадки, и запрос count, дающий текущее число пассажиров.
Теперь, обратившись к началу объявления класса VEHICLE, вы увидите:

note
...
deferred class
  VEHICLE
inherit
  MOVING
feature
…Оставшаяся часть класса...

Класс VEHICLE наследует от класса MOVING, который описывает движущиеся объекты и

7

имеет запрос position.

Классы VEHICLE и MOVING объявляются не просто как class, а как deferred class. Мы
вскоре познакомимся детально с концепцией отложенного класса, указывающего на то,
что не все его компоненты полностью заданы; реализация некоторых из них оставлена
его потомкам — классам, наследующим от него.

Глядя, как эти три класса описывают типы объектов периода выполнения — такси,
транспортные средства, движущиеся объекты, — мы понимаем, о чем говорит нам
наследование. Оно устанавливает, что в системе Traffic любое такси может
рассматриваться как транспортное средство, которое, в свою очередь, является
движущимся объектом. В частности, все свойства класса MOVING применимы к целям
типа VEHICLE и TAXI, и все свойства класса VEHICLE применимы к целям типа TAXI.

Термины наследования

Как обычно, помогает точная терминология.

Определения: наследник, родитель, (правильный) потомок и предок

Если B наследует от A ( В Eiffel A перечислено в предложении inherit класса B), то B
наследник A, а A - родитель B. Потомками класса является сам класс и (рекурсивно)
потомки его наследников. Сам класс не включается в число правильных потомков.
Предок и правильный предок являются обращенными понятиями по отношению к
потомкам.

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

В литературе иногда встречается термин “подкласс”, означающий иногда наследника,
иногда правильного потомка. Аналогично встречается и термин “суперкласс”.

На рисунке ниже, иллюстрирующем наш пример, все классы являются потомками
класса MOVING. Все классы — его правильные потомки, за исключением самого класса.
Правильными предками класса TAXI являются классы VEHICLE и MOVING.

Рядом с каждым классом на рисунке показан один или два компонента, вводимые этим
классом. Обратите внимание на соглашение, принятое при представлении
наследования на диаграммах: наследование изображается в виде одиночной стрелки,
Напоминаю, что другое отношение — “клиентское” — изображается двойной
стрелкой.

8

Рис. 1.1.  Иерархия наследования

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

От вас не требуется вручную рисовать диаграмму, отображающую отношения между
классами. Если классы скомпилированы, то инструментарий Diagram Tool EiffelStudio
создаст диаграмму. Достаточно просто щелкнуть вкладку Diagram, и появится
требуемая диаграмма:

9

Рис. 1.2. 

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

Компоненты, приходящие от высших авторитетов

Мы можем теперь оценить новинку, вводимую наследованием. Понятие “компоненты
класса” больше не означает только компоненты, заданные в классе, но и компоненты,
наследуемые от родителя. Так, объявив объекты m: MOVING, v: VEHICLE, t: TAXI,
мы можем помимо прочего писать:

v.load (...)
t.take (...)
v.count   — Выражение

Возможны и другие вызовы, такие как:

t.count
t.load
t.position
v.position

Здесь используются компоненты, наследуемые от родителя или, более точно, от
правильных предков. Полезно различать “наследуемые” и “непосредственные”
компоненты.

Определения: компоненты класса, непосредственные, наследуемые, вводимые

Компонент класса - это одно из двух:

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

Заметьте, что определение включает рекурсию.

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

Плоский облик

10

Доступ онлайн
1 000 ₽
В корзину