воскресенье
15:49
Deeptown Night
Ru Gb

Project blogs

Потоки данных в Диптауне

Published by Дмитрий Роот on 23.04.2007

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

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

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

Очевидно, иметь отдельный интерфейс для каждого потока данных - это неудобно и неуниверсально (как жаль, что этого до сих пор не понимают в Microsoft). При таком подходе, если я пишу, например, программу, обрабатывающую HTML-страницы, мне нужно написать отдельно модуль, читающий эти страницы из файлов на диске, отдельно - из zip-архивов, отдельно - качающий из интернета и т.д. Я, конечно, человек не ленивый и потружусь написать все эти модули. Но моя программа всегда будет ограничена в функциональности именно теми модулями, которые я реализую, а для добавления дополнительной функциональности - скажем, чтения страниц по протоколу FTP - потребуется еще один модуль.

В операционных системах семейства UNIX с этим обстоит намного лучше. Во-первых, здесь реализован универсальный интерфейс чтения/записи данных в абстрактный "файловый дескриптор", безотносительно источника данных, который скрывается за этим дескриптором. А во-вторых, файловая система UNIX позволяет рассматривать устройства как обычные файлы. Но и здесь не без проблем. Во-первых, предлагаемый ОС UNIX программный интерфейс предоставляет абстракцию только для функций чтения/записи, а открывать каждый из потоков все равно приходится при помощи отдельного интерфейса. А во-вторых, количество поддерживаемых файловой системой потоков данных ограничено и расширяемо только на уровне ядра.

В ядре Диптауна реализовано более красивое, на наш взгляд, решение. Во-первых, интерфейс потока данных универсален по отношению к операции открытия: необходимые параметры передаются в виде некоторой строки (например: file:info.txt или ftp://dev.deeptown.org/info.txt). Во-вторых, ядро позволяет очень просто - через наследование классов - добавлять реализации новых потоков данных.

Такой подход позволяет на уровне приложения полностью абстрагироваться от источника данных, с которым работает данное приложение. В итоге абсолютно все приложения, использующие данный интерфейс ядра, будут одинаково хорошо работать и с файлами, и с архивами, и с удаленными файлами (доступными по протоколу HTTP, FTP и пр.). Более того: при добавлении нового источника данных, все ранее написанные приложения будут отлично работать и с новым источником.

Кроме того, этот подход позволяет на уровне ядра определить некоторые универсальные механизмы работы с потоками данных, применимые для всех потоков, такие как: передача данных из одного потока в другой, фильтры, конверторы форматов данных и некоторые другие. Таким образом, во многих случаях работа с данными вообще не требует программирования, а заключается лишь в применении вышеуказанных механизмов в правильной последовательности.

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

В тексте я попытался сделать упор на сравнении различных подходов к проектированию. Думаю, что пример с потоками данных - наиболее простой, и в то же время наиболее показательный. Он демонстрирует, какие преимущества дает выбранный нами подход к проектированию, применяемый повсеместно в проекте. Фактически, все ядро Диптауна представляет собой набор интерфейсов и очень простых универсальных классов, которые манипулируют этими интерфейсами в соответствии с их смыслом. И это дает фантастическую функциональность! Например, если определить десять различных потоков данных, десять баз данных и десять объектов виртуального пространства, мы получим 101010 = 1000 различных комбинаций "объект-база-поток", и все тысяча будут нормально работать!

Please login or register to see comments