div.main {margin-left: 20pt; margin-right: 20pt} М. Безверхов. vasilisk@nm.ru
Компонентное программирование.
Глава 3. Препятствия "на подходах к..."
Текущее состояние компонентной идеи в программировании
оценить непросто. Как и всякое явление большого масштаба оно вряд-ли может
быть оценено плоской и линейной системой оценок. Скорее, можно говорить об
устойчивых наборах «движущих сил» и сегментов «программостроения» в
которых, по тем или иным причинам, преимущество имеют определенные
течения. Например, можно рассмотреть программирование из компонент со
стороны рынков и категорий товаров, на них обретающихся. Можно
рассматривать и со стороны групп пользователей, решающих разными
программными средствами какую-то задачу одного класса. А можно – со
стороны парадигмы программирования, принятой в той или иной специфичной
части информатики. Но здесь мы рассмотрим «движущие силы» со стороны
программиста, создающего программы. Ведь именно «устройство программиста»
является самой важным фактором во всех аспектах проблемы. Да и несмещенные
оценки получить трудно, если приглядываться к проблеме исключительно
профессиональным взглядом, не отдавая себе отчета что именно он вносит
самые существенные искажения.
И тут первое, что обращает на себя внимание – резкая
отличность программирования, как человеческой деятельности от других…
видов деятельности. Например, во всех других областях разработка и
проектирование отделены от производства сконструированного, а в
программировании – совмещены. Как следствие, многие очевидные бы в
организации проектных работ явления (хорошо, кстати, изученные
человечеством) здесь видны не столь отчётливо, а организация работ – очень
сильно отличается от других отраслей. И прямые аналогии из разноотраслевых
подходов работают плохо.
Другим таким уникальным обстоятельством является то, что
никакая, сколь-нибудь сложная, человеческими руками сделанная, конструкция
не делается из одного материала. Всегда разные её детали выполняются из
материалов разных, что совершенно естественно предполагает неявное
«компонентное конструирование». Не бывает «цельнометаллических
автомобилей» и «цельнокирпичных домов»… А вот «компьютерные программы» -
изделия как раз совершенно «из одного материала», что заменяет настоящее
компонентное конструирование очень своеобразным подходом, рассматриваемым
немного ниже.
Программы невещественны, являются как бы воплощением «чистой
идеи» что затрудняет программисту понимание того, что создание программы
есть процесс конструирования инженерного изделия. Т.е. программирование -
не процесс написания инструкций процессору, не процесс выдумывания
структур данных, не процесс изобретения алгоритмов, реализующих данную
задачу, а процесс создания изделия, которое компромиссным образом
удовлетворяет совокупность разнородных требований. И не все они –
«программистские», большая часть ограничений программы лежит в
человеческом мире - начиная от способностей некоторого сообщества людей
произвести программный продукт и кончая способностями другого сообщества
его использовать.
Кроме того, и в самой дисциплине программирования существует
большой накопленный багаж подходов, парадигм, профессиональных приёмов,
которые отнюдь не способствуют «компонентному восприятию
действительности». Явления эти – чисто философской природы, поэтому
«простой программист-практик» о них задумывается редко, а они сильно
определяют мышление этого самого программиста. В качестве примера
рассмотрим только один, но очень характерный (на уровне одной из парадигм
программирования) приём «совмещения несовместимого» в его приложении к
процессу конструирования программ.
Дело в том, что компонентный способ решения проблем –
человеческий способ «от природы». Психология восприятия человека такова,
что он в состоянии оперировать не более, чем 7±2 объектами одного ранга
одновременно. На большее не хватает его внимания. Зато, со значительно
меньшими усилиями он способен менять план рассмотрения проблемы переходя с
более общего уровня на более частный и наоборот.
Поэтому трудность конструирования любой модели из
нерегулярных элементов сильно растёт с увеличением их числа.
Сконструировать модель из 49 объектов одного ранга для человека –
непосильная задача. Ему значительно проще сконструировать семь подсистем и
одну систему из подсистем, объединяющую их все.
А вот «психология восприятия компьютера» – совсем другая.
Реализовать алгоритм, обрабатывающий 49 однородных объектов значительно
проще, чем их группировать, а потом обрабатывать группы. Вследствие этого
образуется некое противоречие между способом мышления и способом
реализации компьютером задуманного человеком.
Эта проблема действительно существует ещё со времен первого
компьютера. Существует и её чисто инженерное решение –
программа-транслятор, как инструмент, преобразующий мощности множества «в
котором мыслит человек» в множество «в котором исполняет команды
компьютер». По сути, человеку предлагается построить высокоуровневую
модель на некотором абстрактном языке, которая формальным способом будет
трансформирована в язык управляющий исполнительным устройством. В самом
этом нет ничего плохого, напротив, данный подход имеет много очень
выгодных сторон и давно стал стандартным. Настолько стандартным, что
как-то не сразу и видно, что подход-то не является безразмерно
масштабируемым! Ведь какой «степени мелкости» ни были бы машинные команды
и какой «степени крупности» ни были бы конструкции входного языка, на
человеческом-то уровне все равно остается «семь объектов» которыми человек
в состоянии оперировать. А, значит, проблема остаётся...
«Языки программирования» её ослабили. Понятие «подпрограмма»
есть не что иное, как формальная спецификация использующая компонентный
образ мышления. Если программист не может удержать в области своего
внимания весь фрагмент, он должен выделить части фрагмента, оформить их в
виде «подпрограмм» и перейти к рассмотрению той же ситуации на более
высоком уровне абстракции. Только вот проблема-то меняет лишь личину –
более высокий уровень абстракции в понятии программиста это «семантически
более высокий уровень», в то время как синтаксически уровень абстракций
(которым оперирует транслятор) остается всё тем же. И «вызов подпрограммы»
для процессора есть всего-навсего «переход с запоминанием адреса
возврата»… Выходит так, что какие бы структурные образования ни выделялись
в программе, как бы они ни комбинировались, на выходе транслятора все
равно получается однородный монолит кода и данных. Да ещё какой монолит –
ни код, ни данные визуально неразличимы, ибо имеют одну и ту же
природу!
Наличие «разрабатываемых в отдельном производственном цикле»
библиотек подпрограмм нисколько не влияет на эту проблему – для получения
работоспособного модуля уже линкер, но должен увидеть все исходные
части собираемого программного модуля. Отсутствие какого-либо объекта на
этапе сборки влечет за собой невозможность получить результат, и то, что
сделает линкер опять будет монолитом.
Конечно, написанное выше немного утрирует проблему: есть
библиотеки динамической компоновки, есть модульно-слоевая архитектура
операционных систем – но общая тенденция этим обозначена. Парадигма
устройства процессора заставляет программиста мыслить в категориях
логических абстракций, отчётливо понимая что они – только его логические
абстракции. Что «на выходе всё равно всё вместе будет и будет плоским». А
потому – компонентное проектирование есть как бы частное дело каждой
конкретной программы. Сам собой и очень естественно образуется
профессиональный взгляд, что всякая программа есть модель не части, но
полной вселенной. Если приводить машиностроительные аналогии, то это
взгляд, что при разработке нового станка нужно все перепроектировать
заново, и что в одном цеху – один станок. А линия из станков – это не
группа отдельных станков, а один большой (другой!) станок...
И всё же, это только препятствия. Но к чему? Что в таком
случае понимать компонентным программированием без машиностроительных
аналогий, и, главное, что оно даёт? Давайте определимся точнее...
|