Тверской государственный университет
Опубликован: 03.10.2011 | Доступ: свободный | Студентов: 3284 / 60 | Оценка: 4.33 / 3.83 | Длительность: 19:48:00
ISBN: 978-5-9963-0573-5
Лекция 10:

Переменные, присваивание и ссылки

Делаем списки явными

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

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

Это даст нам возможность ввести более общие рамки для связанных структур, чем те, что рассматривались в последних примерах. Мы уже работали с классом STOP, чьи экземпляры содержат ссылку right на следующий экземпляр:

 Неявная структура списка

Рис. 9.18. Неявная структура списка

Доступ к остановке s, благодаря последовательному применению right, дает нам доступ ко всем последующим элементам, но сама структура списка остается неявной. Как следствие, сложно выразить вариант цикла в вышеприведенном примере, в то время как он интуитивно ясен — на шаге i мы выполнили обращение i элементов исходного цикла. Но у нас нет возможности ссылаться на такие глобальные свойства, поскольку мы имеем дело только с отдельными элементами. При систематическом подходе список сам является объектом:

 Связный список

Рис. 9.19. Связный список

Объект "список", показанный вверху, является экземпляром LINE. Он используется только как заголовок списка, не содержащий его элементов (эту роль играют экземпляры STOP), но он хранит общую информацию о списке: число элементов — count, ссылку first_element на первый STOP, позволяющий далее добраться до всех других элементов.

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

В библиотеке EiffelBase ячейки списка (такие как экземпляры STOP) принадлежат библиотечным классам, таким как LINKABLE, в то время как заголовок списка принадлежит классу, такому как LINKED_LIST.

Полезно выполнить следующее упражнение — переписать remove_right, put_right и reversed как методы класса LINE, их естественное место в этом классе, а не в классе STOP. При этом необходимо тщательно следить за void-значениями и граничными случаями (пустые линии, вставка и удаление на концах списка).

Где используются операции над ссылками?

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

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

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

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

Почувствуй методологию
Принцип ссылочного программирования

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

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

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

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

К счастью, современные среды разработки обеспечивают библиотеки компонент, включающие базисные типы структур объектов. Таковой является библиотека EiffelBase, разрабатываемая многими людьми в течение многих лет. Поддерживающие библиотеки есть и у языков Java, C#, С++:

Почувствуй методологию
Принцип библиотечных фундаментальных структур данных

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

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

Этот совет применим не только к действиям над ссылками: зачем повторно разрабатывать, когда можно повторно использовать?

Даже если вы должны написать собственную реализацию, отличающуюся от библиотечной, библиотека может помочь вам. Прежде чем все писать с чистого листа, можно начать с существующего класса и модифицировать его. Помните, однако, общий совет о дублировании кода. Прием "copy — paste" считается ужасным при разработке ПО.

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

Кирилл Юлаев
Кирилл Юлаев
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?