TURBO PASCAL |
Новости
|
Данные:зачем применять к ним абстракции, что это может дать; как абстракции алгоритмов сливаются с абстракциями данных, какие преимущества это может дать.
На прошлом уроке мы говорили о том, как разбивать программы на модули (подзадачи) и какой выигрыш это может дать при написании программ. Стоит отметить, что процедурная абстракция не является единственным полезным применением абстракций через спецификацию и параметры. Другим, не менее важным их приложением является абстракция данных. До сих пор мы говорили об абстракциях лишь в применении к алгоритмам. В то же время "программа есть алгоритмы и структуры данных". При разработке программ (представляющих собой, вообще говоря, модели некоторых сущностей - реальных или умозрительных) естественной является локализация информации (данных) об этих сущностях - объединение переменных, хранящих эту информацию в некоторые структурированные совокупности (списки для описания результатов эксперимента, матрицы для описания линейных преобразований, стуктуры для объединения разнородной информации, etc.). Выигрыш от такого объединения очевидна - для многих элементарных и не совсем структур в ЯП высокого уровня существуют встроенные механизмы обработки. То есть за счет представления некоторых конкретных данных в некотором общем виде (абстрагируясь от их семантики) мы можем применять к ним общие методы обработки. Кроме того, очень часто до полной реализации всех модулей программы трудно определить состав и наиболее эффективное представление данных в памяти. К примеру довольно сложно определить, следует ли использовать массив или связный список для хранения однотипных данных. И если список, то какой - одно- или двусвязный. В то же время вполне понятно, что сам по себе список понадобится. В такой ситуации было бы полезным абстрагироваться от представления данных, ограничившись определением действий (операций, операторов и процедур/функций) над данным представлением. Почти очевидно, что оба из приведенных примеров есть ничто иное, как применение абстракций через спецификацию и параметры, с которыми мы уже знакомы. В самом деле при таком подходе существует договоренность о способе обработки какого-то элемента (группы элементов) той или иной процедурой или операцией при выполнении для некоторго (любого) объекта - элемента данных - определенных условий. Единственное, что остается - определиться с условиями, которым должны отвечать обрабатываемые объекты. Можно сказать, что общим свойством для всех объектов подобного рода будет принадлежность некоторому классу объектов. Классом мы здесь назовем совокупность всех объектов, обладающих некоторым общим свойством класса (или несколькими его свойствами). То есть класс является абстракцией всех свойств объектов, принадлежащих данному классу, за исключением свойств самого класса. При таком подходе к данным и алгоритмам их обработки процесс разработки программ становится как более гибким - у программиста появляется гораздо больше свободы для маневра на всех этапах разработки программы - так и более прозрачным - абстракция данных делает необходимыми применение абстракций к алгоритмам и естественой - декомпозицию. Пример,или зачем это надоПриведем пример. Допустим, что приходится писать программу обработки результатов какого–либо эксперимента, представленные в виде матриц. Допустим также, что результаты - качественные, то есть могут быть представлены в виде чисел (0, 1, 2, .., N), и большинство из них равны 0. Алгоритмы обработки будем считать настолько сложными, что для их программирования a priori потербуется отдельный специалист, который знаком с программированием постольку поскольку. Размеры задач - большие, тестовые данные - есть, их размерность невелика. Ситуация, прямо скажем, жуткая. Для того, чтобы специалист мог программировать свои алгоритмы, методы программирования должны быть довольно простыми, желательно не выходящими за рамки матричного исчисления. С другой стороны, необходимая экономия памяти ЭВМ делает операции с теми же матрицами довольно сложными - необходимо либо оперировать блочными матрицами, либо списками, представляющими разреженные матрицы, причем на начальном этапе способ обработки матриц не очевиден. Помочь здесь может декомпозиция и, соответственно, абстрагирование. Введем в рассмотрение некую абстракцию - класс "матрица". Над элементом этого класса определим операции "обращение к элементу", "умножение на число", "умножение матриц", "сложение", то есть произведем абстракцию алгоритмов через спецификацию. Наконец, определим каким образом и для каких объектов будут вызываться данные операции - абстракция через параметры. Результатом всех этих абстракций является обоснование следующей декомпозиции: специалист разрабатывает алгоритмы обработки результатов эксперимента в терминах введеных операций и матриц; программист раз разрабатывает вспомогательные алгоритмы (умножение, деление и тому подобные) в терминах матриц и операций доступа к отдельным элементам; программист два заниматся проблемами представления матриц. Выигрыш от этого следующий. Программист два за два часа программирует реализацию простейшего объекта класса "матрица" - обычного двумерного массива - в соответствии со спецификацией. С этого момента программист раз становится независимым и может программировать элементарные вспомогательные алгоритмы (тоже довольно простая работа, выполнимая за короткое время). Почти одновременно с ним в работу включается специалист, который разрабатывает сложные алгоритмы в терминах матриц и одновременно тестирует их на тестовых данных. Это возможно, потому как тестовые данные могут быть представлены существующими объектами класса "матрица". Параллельно с этим программист два занимается реализацией экономного представления других объектов класса "матрица", и производит выбор подхдящего варианта. Результат следующий. Программа пишется и одновременно отлаживается примерно в два с половиной раза быстрее за счет параллельности разработки, еще в некоторое количество раз быстрее за счет того, что каждый исполнитель работает с небольшим по объему и сложности модулем. В частности, специалист не занимается проблемами представления, в которых он, возможно, и не сможет разобраться, но в то же время свободно работает с некими абстрактными объектами. Приблизительная временная диаграмма выполнения декомпозированного и недекомпозированного проектов выглядит так
Заметно, что экономится общее время разработки, а затраты на разработку в принципе не меняются. Что характерно, параллельно с указанными программистами могут трудиться, скажем, разработчики интерфейса или автоматического сбора данных. Объединение данных с алгоритмами,или инкапсуляцияИз всего вышесказанного можно сделать вывод о том, что применение абстракций по отдельности к алгоритмам и данным менее эффективно, чем к их совокупности. Результатом такого одновременного абстрагирования является то, что программист начинает представлять программу целиком, не отделяя данные от алгоритмов, их обрабатывающих. Кроме того, абстрагирование от конкретных свойств (подробностей) объектов определенных классов и оперирование отлько свойствами класса приводит к тому, что человек при должной тренировке и образовании может охватить мысленным взором весь проект и/или любой его модуль, а реализация может производиться множеством программистов, причем частично параллельно. Таким образом имеет смысл говорить о том, что объединение алгоритмов с данными является естественным развитием концепции модульного программирования, как, впрочем, и объединение такого рода конгломератов в группы (классы) по некоторым общим признакам; такого рода объединения позволяют программисту (группе программистов) создавать большие проекты. Реализация подходаЕстественно, что все предыдущие рассуждения не имели бы особого смысла, если бы оставались только рассуждениями. Однако это не так. Концепция объединения по общим признакам, а также объединения данных с алгоритмами, их обрабатывающими, была осознана, а затем строго формализована: были выявлены принципы, необходимые и достаточные для реализации такого подхода. О них, часто и вполне справедливо называемых "тремя китами ООП" мы поговорим в другое время, а в данный момент рассмотрим, что же из себя представляют объединения данных и алгоритмов. Любого такого рода объединение характеризуется состоянием - совокупностью текущих значений элементов данных (1). Состояния же меняются под воздействиями, не принадлежащими объединению (или не являются стабильными). Процесс смены состояний как правило сопровождается выдачей "наружу" других воздействий (на другие объединения). Для людей хотя бы поверхностно знакомых с теориями моделирования такого рода ситуации являются хорошо знакомыми. Но сейчас речь о другом. Если ввести стандарт на взаимодействия объектов друг с другом, то можно рассматривать их как элементы одного и того же класса и легко ими управлять. Такой подход называется программированием, управляемым сообщениями, и получил широкое распространение. ВыводыИтак, мы вплотную подошли к концепции объектно–ориентированного программирования, и уже увидели его приемущества. Еще раз перечислим их:
(1) Обратно Кстати,
такого рода состояний конечное число. |
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |