© А.И. Легалов

Методологические выкрутасы

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

Куда это я клоню? А вот куда. Описывая основные достоинства ООМ Гради Буч [Буч98] совершенно серьезно говорит, что: "Объектная модель позволяет в полной мере использовать выразительные возможности объектных и объектно-ориентированных языков программирования". Как будто построение объектной модели происходило не на основе этих самых языков! Ведь любая методология разрабатывается с использованием уже накопленных в предметной области эмпирических фактов и практических результатов, коими, в данном случае, и являлись существующие языки программирования. Ведь до появления ООМ прошел не один десяток лет, если плясать от Симулы-67 [Дал69]. Только идиоты, политики и менеджеры могут создавать методологии, которые не используют выразительные возможности языков. Вряд ли можно отнести Буча к первым двум категориям. Это голова и гигант мысли в одном флаконе! Следовательно, он немного перестарался, чтобы раскрутить свои методы. Хотя, и политики в программировании более чем достаточно [Йордон].

Но, вместе с тем, я имею наглость утверждать, что методологическая надстройка - это такое надуманное творение, которое легко можно приспособить и к другим, альтернативным, идеям (политики постоянно подтверждает это на практике:). В частности, что нам мешает выстроить на процессах парадигму программирования, аналогичную объектно-ориентированной? Достаточно заменить "объект" на "процесс", чтобы прослыть новым методологом. И сейчас правой рукой я набираю на клавиатуре этот текст, а левой, в это время, судорожно правлю экземпляр книги Гради Буча [Буч98]. Надо спешить. И пусть меня попробуют обвинить в плагиате! Ведь сам Буч написал: "Однако, мы не можем сконструировать сложную систему двумя способами, тем более, что эти способы по сути ортогональны". Значит, новая методология будет другой, хоть и написана теми же словами. Я прекрасно осознаю все зыбкость этих "методологических" утверждений, но не могу удержаться от неожиданно наступившего словоизлияния.

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

Отчуждение клиента от собственности

ОО подход породил множество постулатов и догм, определяющих правильный стиль программирования. Со временем они перекочевали в различные книжки. Ряд зафиксированных приемов оказались связанными со спецификой конкретных языков программирования [Голуб, Мейерс2000-1, Мейерс2000-2, Элджер]. Другие были заявлены как универсальные и обосновались в "приемах объектно-ориентированного проектирования" [Гамма]. Я не отрицаю полезность накопленного эмпирического опыта и с удовольствием использую его в своей практике. Но, вместе с тем, создается впечатление, что мы пользуемся не той системой отсчета. Что-то напоминает геоцентрическую систему Птолемея, которая поставила землю в центр вселенной. Для простейших расчетов все идет нормально. Но как только переходим к более сложным и точным расчетам, каждая планета начинает двигаться по каким-то непонятным, дополнительным окружностям. И без уточняющих правил, исключений, измерительных инструментов, а также шаманских ритуальных плясок не обойтись. Я не думаю, что в мгновение ока поставлю в центр нашей системы солнце. Скорее всего, у меня на этом месте расположится Марс. Однако, ряд суждений хотелось бы сделать.

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

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

Однако косвенное взаимодействие необязательно должно обеспечиваться через явный вызов процедуры. Еще на заре параллельного программирования был придуман обмен данными между процессами через почтовые ящики. Одни процессы загружали почту (информацию), а другие забирали ее. Внутренняя организация процессов оставалась при этом закрытой. Достаточно было только договориться о формате обмена данными и подключиться к почтовым ящикам. При этом обмен мог вестись через простые переменные очереди, стеки и любые другие объекты одинаковым для процессов способом. Любые внутренние изменения данных в процессах никоим образом не влияли на их взаимодействие. Так что, интерфейс - это не только процедуры. Он может быть выстроен и на основе модели данных. При этом неважно, что посредники между почтовыми ящиками и процессами являются процедурами, так как нас совершенно не волнуют ни их сигнатуры, ни внутренние модификации процессов. Можно легко менять процедуры, обслуживающие постовые ящики. Можно даже использовать несколько разных процедур процесса для обслуживания одного ящика, выбирая нужную процедуру в зависимости от текущего состояния ожидания.