Объектно-ориентированное программирование и программная инженерия
Покупка
Тематика:
Программирование и алгоритмизация
Издательство:
ИНТУИТ
Автор:
Мейер Бертран
Год издания: 2016
Кол-во страниц: 208
Дополнительно
В этом курсе переместимся на передний край современной технологии программирования и посмотрим, какие преимущества можно получить, если использовать всю мощь ОО-идей. Первые лекции описывают многие механизмы наследования, включая полиморфизм, динамическое
связывание, множественное наследование, понятие ограниченной универсальности. Затем исследуются новые средства, которые добавляют существенную выразительную силу объектному каркасу. В Eiffel они называются агентами (терминология не устоялась, в других языках их называют делегатами, замыканиями). Рассмотрение агентов сопровождается знакомством с основами лямбдаисчисления. Последующие лекции представляют проектирование, управляемое событиями, - гибкую архитектуру программных проектов, дополняющую наши прежние структуры управления. В 2-х последних лекциях рассматриваются требования, необходимые для перехода на новый уровень, перехода от простого программирования к профессиональной разработке ПО промышленного качества. Этот уровень называется программной инженерией.
Тематика:
ББК:
УДК:
ОКСО:
- ВО - Бакалавриат
- 09.03.01: Информатика и вычислительная техника
- 09.03.02: Информационные системы и технологии
- 09.03.03: Прикладная информатика
ГРНТИ:
Скопировать запись
Фрагмент текстового слоя документа размещен для индексирующих роботов
Объектно-ориентированное программирование и программная инженерия 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