Интерфейс класса
4.3. Использование класса
Теперь мы постараемся понять, на что похож класс и как можно его использовать для построения новых классов – клиентских классов – в нашей собственной программе.
Уже знакомые нам классы были написаны для моделирования свойств и операций, связанных с транспортной системой города, подобной Парижскому метро. Мы используем Париж из-за его известности – это город, являющийся мировым центром туризма. Но, конечно, это только пример, ПО ничего не знает об особенностях этого города. Вся информация о городе и его транспортной сети читается из файла, который можно заменять в соответствии с вашим выбором (в ETH мы используем Цюрих и его трамвайную сеть – основу транспорта в этом городе).
Файл, хранящий информацию, создается в формате XML – принятом ныне стандарте описания структурированных данных.
Ниже для ссылок приводится план Парижского метро (упрощенная версия, где опущены некоторые станции).
Как определить, что должен делать хороший класс
Предположим, нас попросили спроектировать ПО, моделирующее метро, как оно видится нынешними и будущими пассажирами. Как и в любом проекте ПО, ключевым является вопрос: какие классы следует создать? Чтобы найти хорошие классы, отвечающие на наш вопрос, обратимся к поиску концепций проблемной области, которые:
- описывают множество объектов (их будущие экземпляры);
- могут быть четко объяснены;
- могут быть охарактеризованы в терминах четко определенных методов, включающих как запросы, так и команды, применимые к соответствующим объектам.
Документ с минимальными требованиями
Можем ли мы найти классы и их методы, моделирующие метро? Зачастую первый шаг проектирования состоит в том, чтобы описать простым и ясным языком проблемную область. Давайте попробуем.
Почувствуй Париж: Добро пожаловать в метро
Метро – это сеть поездов, главным образом, идущая под землей, позволяющая людям путешествовать по городу быстро и с удобствами.
Сеть состоит из линий, каждая линия включает множество станций, две из которых являются конечными станциями. Поезда на линии идут от одной конечной станции до другой, останавливаясь на каждой станции, расположенной вдоль линии, а затем возвращаются назад таким же способом.
Некоторые станции принадлежат двум или более линиям; они называются пересадочными станциями, позволяя связывать одну линию с другой.
Чтобы добраться до некоторого пункта назначения в городе, используя метро, необходимо идентифицировать станцию, ближайшую к той точке, где вы находитесь, и станцию, ближайшую к пункту назначения. После этого необходимо составить маршрут поездки между выбранными станциями. Маршрут включает несколько этапов, каждый из которых состоит из последовательно идущих станций одной линии. Последовательные этапы соединяются на пересадочных станциях. У метро есть важное свойство: всегда существует маршрут для любой пары станций метро (математики сказали бы, что метро задается связным графом).
Это описание довольно формальное, даже педантичное. Вряд ли его мог бы сформулировать посетитель, ранее не пользовавшийся метро. С другой стороны, оно менее точное и менее полное, чем можно было бы ожидать от "документа требований", используемого в индустрии при разработке проектов ПО (эта тема подробно обсуждается в лекции, посвященной инженерии ПО). Данный текст требований достаточно хорош для наших текущих целей поиска нескольких классов.
Начальные идеи поиска классов
Как обычно, в документах требований некоторые детали не относятся к нашим непосредственным потребностям, например, то, что сеть главным образом располагается под землей. Само слово "сеть" оказывается не столь уже полезным. Но после некоторых размышлений можно выделить четыре концепции, претендующие на роль классов.
- STATION. Метро состоит из станций; люди едут от одной станции к другой, проезжая мимо некоторых станций. Это понятие кажется жизненно важным для нашего ПО.
- LINE. Метро состоит из линий, каждая из них соединяет несколько станций, проходящих в определенном порядке.
- ROUTE. Маршрут задает описание того, как добраться от одной станции метро к другой.
- LEG. Этап маршрута задает множество непосредственно следующих станций одной линии.
Между введенными понятиями существуют тесные отношения: линия составлена из станций, этап также состоит из станций и является частью линии, маршрут складывается из этапов разных линий.
В доступном для нас ПО Traffic есть классы, покрывающие эти понятия, так что мы сможем рассмотреть некоторые из их свойств. Более точно, Traffic – это библиотека: коллекция программных элементов, которые сами по себе не составляют программу, но обеспечивают важную функциональность, полезную для многих программ. Хотя библиотека Traffic доступна как часть материалов этой книги, в этой лекции мы будем работать так, как если бы мы обязаны были спроектировать соответствующие классы, начиная с базисных концепций: линия, станция, этап, маршрут. Конечно, вам не возбраняется изучать уже созданные классы Traffic. Если вы так и поступите, то учтите следующие соглашения.
Соглашения: Имена классов библиотеки Traffic
Для ясности и во избежание путаницы с другими библиотеками все классы в библиотеке Traffic имеют имена, начинающиеся префиксом TRAFFIC_, например, TRAFFIC_STATION, TRAFFIC_LINE, TRAFFIC_ROUTE, TRAFFIC_LEG.
Для краткости обсуждение в этой книге игнорирует префикс, говоря о классах STATION или LINE. Префикс следует использовать при поиске библиотечных классов в EiffelStudio.
Это соглашение применимо к библиотечным классам. Имена классов в примере, такие как TOURISM и PREVIEW из предыдущей лекции, не используют префикс.
Что характеризует линию метро
Давайте начнем с понимания интерфейса (API, программного интерфейса) класса LINE, представляющего линии метро. Вы можете использовать среду EiffelStudio, чтобы посмотреть интерфейс любого доступного класса.
Начнем со взгляда на упрощенную форму класса LINE, называемую SIMPLE_LINE. Что значит взглянуть на класс? Класс многолик, и на него можно смотреть с разных точек зрения. Можно рассматривать текст класса, и EiffelStudio позволяет сделать это, но нам требуется прямо сейчас совсем иной взгляд. Помимо текста класса, EiffelStudio позволяет отображать другие облики (views) нашего класса, каждый из которых высвечивает различные свойства. Облик или вид класса, интересующий нас в данный момент, известен как Контрактный Облик (contract view). Причины такого наименования вскоре станут ясными.
Для его получения введите имя класса в соответствующее поле, затем щелкните кнопку "contract view", расположенную справа в верхнем ряду кнопок. Ее можно найти, подводя курсор к кнопке и следя за появляющейся подсказкой. Результат выглядит следующим образом:
Контрактный облик показывает методы – команды и запросы, – применимые к экземплярам класса SIMPLE_LINE, который представляет линию метро. Эти методы изучаются в последующих разделах.
Сразу же после обсуждения методов вернитесь к предыдущей картинке (или снова отобразите на экране соответствующий контрактный облик), чтобы убедиться, что вы понимаете все детали контрактного облика класса.
Следя за обсуждением запросов и команд, следует помнить, что класс описывает множество возможных объектов, его экземпляров (каждый представляет линию метро). Методы объявляются в классе, каждый определяет операцию, применимую к любому такому объекту. Например, класс будет иметь запрос south_end, дающий одну из двух конечных станций (ту, которая южнее другой). Это означает, что мы можем применять этот запрос к любой линии метро. Если Line8 обозначает экземпляр SIMPLE_LINE, то Line8.south_end обозначает ее конечную станцию. Когда речь не идет о конкретном экземпляре, мы позволяем себе говорить "SIMPLE_LINE", подразумевая под этим типичный экземпляр класса, задающего типичную линию.
Класс SIMPLE_LINE представляет слегка упрощенную версию класса LINE; обсуждение применимо к обоим классам. Рассмотрим вначале запросы, а потом перейдем к командам.