| О ПОТЕРЯННОМ УРОВНЕ Иногда наблюдение за общими закономерностями помогает в решении частных задач. Инженеры подсматривают за природой, математики - за катастрофами, экономисты - за эволюцией каких-нибудь «малых групп», а куда посмотреть программисту..?
 | ДО. ТРИ ПОХОЖИХ И НЕПОХОЖИХ ПРИМЕРА | Приступим к ним без вступлений. ПРИМЕР 1. УЧЕСТЬ НЕУЧИТЫВАЕМОЕ. (ПРО РАЗГРАНИЧЕНИЕ ДОСТУПА К ОДНОМУ САЙТУ.) Предположим, надо предоставить разные уровни доступа разным Посетителям Web-сайта: -
то, что может видеть любой Посетитель сайта; -
то, что может видеть любой Посетитель, который зарегистрировался; -
нечто дополнительное, что может видеть любой зарегистрировавшийся Посетитель из Москвы, но не должны видеть другие Посетители, независимо от того, зарегистрировались они или нет; -
иное дополнительное, что могут видеть конкретные Посетители Иванов, Петров, Сидоров и т.д., которые зарегистрировались, но это не должны видеть все иные Посетители; -
то, что может видеть VIP-Посетитель, которому специально подбираются темы, и при этом надо сделать так, чтобы его случайно не коснулись ограничения (например, если он не из Москвы и ему можно видеть то же, что Петрову); -
то, что может видеть зарубежный посетитель, если он не VIP и ….. обострим задачу…. -
….. и т.д. ….. вплоть до комбинаторного взрыва…. Как видим, основания для соответствующих разграничений очень разные. Модельно: А,В,7,©,§, W.... – т.е. «вдоль оси не ложатся». Поэтому разработчики не смогли их проиндексировать однородно. Возникла "многофакторность" и долгие размышления на тему о том, какие критерии выбрать. Бесспорно, всегда можно о чем-то договориться, но мы обострим противоречие [2] и введем следующее условие: «что бы мы ни придумали, позже непременно появится ранее неучтенное требование, которое испортит предыдущие правила». Как быть? ПРИМЕР 2. РАЗДЕЛИТЬ НЕРАЗДЕЛИМОЕ. (ПРО УПОРЯДОЧЕНИЕ СООБЩЕНИЙ И ТЕМ НА ФОРУМЕ.) Один из Интернет-Форумов поначалу имел следующую иерархию: o Форум o Темы Форума o Сообщения в Темах Форума
Например, o Форум «О строительстве и архитектуре» o Тема «Информация по стеновым панелям» o Тема «Паттерны архитектуры» o Тема «Ищем вменяемого прораба» o Тема «О технологиях строительства без глупостей» o Тема «А как Вы взаимодействуете с генподрядчиком?» o Тема «В теории архитектуры наблюдается застой!» o ……и т.д.…………………………………………………………….. o Тема «Кто подскажет, где найти библиотеку СНиП’ ов?» o Сообщения в Темах Форума (здесь их приводить не будем) Нетрудно заметить, что получилась «портянка», каких много в сети. Пока «Тем» было мало, с этим мирились, а когда их стало много, начали группировать «Темы» в «Категории»: o Форум o Категории (группы «Тем») o Темы Форума o Сообщения в Темах Форума Например, o Форум «О строительстве и архитектуре» o Категория «Теория архитектуры» o Тема «Паттерны архитектуры» o Тема «В теории архитектуры наблюдается застой!» o ……………. o Категория «Взаимодействия с подрядчиками» o Тема «Ищем вменяемого прораба» o Тема «А как Вы взаимодействуете с генподрядчиком?» o ……………. o Категория «Технология строительства» o Тема «О технологиях строительства без глупостей» o Тема «Кто подскажет, где найти библиотеку СНиП’ o Тема «Информация по стеновым панелям» o ……………… o Категория «… и т.д. N…» o Тема «………» o Тема «………» o ……………… o Категория «Разное»
Поначалу было удобно. Однако, по мере роста проекта, начали происходить следующие эффекты: Эффект 1. Все большее и большее число «Тем» стало необходимо относить к нескольким «Категориям» сразу. Например, - Тема «О паттернах архитектуры в стране невменяемых прорабов, нарушающих технологию»;
- Тема «Проблемы взаимодействия с подрядчиками – это продолжение общего российского беспредела или … ?»
- … и т.д., и т.п. …
Эффект 2. Внутри одной «Темы» (скажем, популярной с большим числом сообщений) почти всегда, по факту, начали смешиваться несколько «Тем». Например, Пользователи начинали с «застоя в теории архитектуры», а потом - в контексте обсуждения - логично переходили на смежные «Темы»: «о том, как учат в наших ВУЗ’ах», «О критериях оценки архитектурных идей» и т.д. А затем они вновь могли обратиться к «застою» или к любому иному смысловому фрагменту. «Разорвать» такое обсуждение на несколько «Тем» не получится – разорвется контекст. И если для решения задач, вызываемых эффектом 1, можно было «Тему», которая относилась к нескольким «Категориям», отображать во все эти Категории (а когда таких «Тем» становилось много, «Категории» переименовывать и/или заводить новые), то для решения задач, вызываемых эффектом 2, сходу решения найдено не было. Традиционно обострим задачу и запишем: «Всегда (по определению) будет возникать противоречие [2]: «разделить «Тему» надо и разделять ее нельзя». Как быть? ПРИМЕР 3. НЕ ЗАБЫТЬ ПОЗАБЫТЬ ИЗМЕНЕНИЯ. (О СОПРОВОЖДЕНИИ БАЗЫ ДАННЫХ.) «По наследству» досталась база данных, состоящая из N таблиц. Каждая таблица содержит записи, каждая запись характеризуется уникальным идентификатором. Записи из разных таблиц могут иметь одинаковые идентификаторы. Для получения конкретных данных предыдущими разработчиками был создан единый класс CTableString, объект которого заполнялся при обращении к соответствующей таблице. Например, можно было обратиться к определенной таблице напрямую и получить конкретные записи (см. пример на С++ -образном псевдокоде): int nTableStringID; CTableString TableString; //... Таблица_Наименование.ПолучитьЗапись(nTableStringID, TableString); Код работает с таблицами напрямую (т.е. «знает» об их существовании), поэтому он постоянно усложняется, т.к. нужно следить за тем, из какой таблицы берутся данные. И к тому же, для того чтобы получить определенную запись, коду еще нужно знать идентификатор записи, который является уникальным для соответствующей таблицы. Ситуация ухудшается, когда появляется необходимость добавить в базу данных еще одну или несколько таблиц, т.к. следить за тем, откуда берутся данные, становится сложнее (как на уровне таблиц, так и на уровне записей). Обострим задачу: пусть количество разных таблиц изменяется в базе данных довольно часто и непредсказуемо для разработчика. Но при этом вызывающий код пусть не меняется вовсе. Мы уверены, что большинство Коллег уже знает решение, а как насчет первых двух примеров?  | РЕ. ТРИ ПОХОЖИХ И НЕПОХОЖИХ РЕШЕНИЯ | Приведенные выше примеры роднит одна общая проектная ошибка, которую мы здесь назовем «Проскок уровня» (в иерархии системы). Проявления данной ошибки - «многофакторность и противоречивость» (и все задачи с этим связанные). Или можно сказать иначе: причина «многофакторности» - это проскок уровня. Разработчику, который думает над тем, как «устаканить многофакторное», надо: -
Прекратить бороться с многофакторностью, т.е. буквально отложить размышления на эту тему и перестать искать «правильные критерии» -
Построить иерархию -
Найти пропущенный уровень и реализовать его -
Все «многофакторное и противоречивое» на одном уровне сгруппировать на следующем РАЗБОР ПРИМЕРА 1. НЕ УЧИТЫВАЕМ, А ГРУППИРУЕМ
Так, решение первой задачи заключается в том, чтобы: -
Прекратить бороться с многофакторностью и/или думать над тем, какие критерии «правильные»... (прекратили) -
-
Пользователя (который регистрируется на сайте) помещать в соответствующую «группу» либо создавать отдельную «группу прав» для данного Пользователя. -
При необходимости в пределах каждой «группы» линейно разграничивать права разным Участникам. -
Индексировать Например, было так: Стало так: -
Группа прав 1 «Права этих людей» -
Иванов -
Петров -
………………………………….. -
Группа прав 2 «Права этих людей» -
Группа прав 3 «Права этих людей» Здесь осуществлен надсистемный переход: поскольку «Нечто» попадало в разные контексты, оно было помещено в «группу». Поскольку ранее «права» контекстно пересекались и гарантированно развести их не удавалось, было введено понятие «группа прав». И решение было реализовано на уровне «групп». (Подробнее о надсистемных переходах – см. в данной статье [2].) РАЗБОР ПРИМЕРА 2. ГРУППИРУЕМ, ЧТОБЫ РАЗДЕЛИТЬ НЕ РАЗДЕЛЯЯ Предположим, в какой-либо «Теме» произошел Эффект 2. (см. выше). И мы столкнулись с противоречием: «разделить «Тему» надо и разделить ее нельзя». Проиллюстрируем: Внутри одной «Темы» стали по факту смешиваться несколько «Тем». Приведем «условную портянку»: Тема «Застой в теории архитектуры» | Автор: Иванов Кому: Всем | | В теории архитектуры наблюдается застой… Он выражается в том, что … | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Петров Кому: Иванов Дата: 07.10.2004 16:15:53 | | Не согласен, прочитайте, например, исследование «Каменные мозги». | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Сидоров Кому: Иванов Дата: 07.10.2004 17:13:26 | | На какой выборке сделан Ваш вывод? | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Иванов Кому: Сидоров Дата: 08.10.2004 11:24:29 | | На какой "выборке" сделан ваш вывод? Какая выборка? Оглянитесь вокруг. | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Сидоров Кому: Иванов Дата: 08.10.2004 12:01:53 | | Какая выборка? Оглянитесь вокруг. Тогда надо писать: в архитектуре наблюдается застой, а не в теории... В теории как раз традиционно все ОК. | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Петров Кому: Сидоров Дата: 08.10.2004 12:10:05 | | Дело не в теории. Просто в ВУЗах плохо учат... | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Козлов Кому: Петров Дата: 08.10.2004 13:17:45 | | Просто в ВУЗах плохо учат... В ВУЗах учат нормально. Просто все из страны бегут. | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Петров Кому: Козлов Дата: 08.10.2004 13:25:37 | | В ВУЗах учат нормально. Просто все из страны бегут. Что значит нормально? Какие у Вас критерии? | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Волков Кому: Всем Дата: 08.10.2004 13:30:26 | Вопрос о критериях очень интересен. А до тех пор, пока эту тему не затронули, было скучно читать. И важно говорить не столько о критериях обучения, сколько о критериях качества архитектурных решений. Вот что я предлагаю: ++++++++++ -------------------- .....................
| [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Петров Кому: Волков Дата: 08.10.2004 15:19:59 | | Нет, эти критерии некорректны! | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Волков Кому: Петров Дата: 09.10.2004 10:20:42 | | Нет, эти критерии некорректны... А если так: +++++++++++++++ +_+_+_+_+_+_+_+_ --++--++--++--++--++ Что скажете? | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | | От: Иванов Кому: Волков Дата: 09.10.2004 10:27:05 | | Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть..? | [ответить] [новое сообщение для всех] [все ответы на это сообщение] | Очевидно, уже под одним заголовком смешались три смысловые нити обсуждения: -
В теории архитектуры наблюдается застой -
Хорошо ли учат в ВУЗах архитектуре? -
О критериях качества архитектурных решений Но поскольку все они встроены в контекст одного обсуждения (участники Форума общаются друг с другом), то на несколько «Тем» их не разорвать. Решение заключается в разделении «Темы» на смысловые «Нити» с последующим помещением всех этих «Нитей» в общий контекст «Обсуждения-аналоги»: У каждого сообщения (если смотреть со стороны «администратора») появилась опция «создать нить». После нажатия на соответствующую ссылку вводим название «Нити» и сохраняем. Заголовок появляется слева на панели, а выбранное сообщение становится первым в новой смысловой «Нити» справа. Кроме того, каждое сообщение теперь можно отобразить в любую из «Нитей». И те сообщения, которые (по смыслу) могут быть отображены в нескольких «Нитях», отображаются в нескольких. И, конечно, где необходимо, добавим гиперссылки. Теперь, если нажать на «Корень», то увидим все сообщения подряд, как выше. А если на конкретную «нить», то увидим сообщения принадлежащие ей. См. ниже: Тема «Застой в теории архитектуры»
Обсуждения-аналоги (нити) | Корень |
|
| В теории архитектуры наблюдается застой [сообщений: 6] [изм.: 09.10.2004 10:27:05] [открыта] | |
|
| Хорошо ли учат в ВУЗах архитектуре? [сообщений: 4] [изм.: 07.10.2006 15:35:06] [прочитана] | |
|
| О критериях качества архитектурных решений [сообщений: 4] [изм.: 07.10.2006 15:40:26] [прочитана] | [Добавить аналогичное обсуждение] [ Присоединить нить к текущей ] Авторы |
| Иванов | | | | Петров | => | Иванов | | | Сидоров | => | Иванов | | | Иванов | => | Сидоров | | | Сидоров | => | Иванов | | | Иванов | => | Волков |
| | Автор: Иванов В теории архитектуры наблюдается застой… Он выражается в том, что … [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Петров Кому: Иванов Дата: 07.10.2004 16:15:53 Не согласен, прочитайте, например, исследование «Каменные мозги». [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Сидоров Кому: Иванов Дата: 07.10.2004 17:13:26 На какой выборке сделан Ваш вывод? [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Иванов Кому: Сидоров Дата: 08.10.2004 11:24:29 На какой "выборке" сделан ваш вывод? Какая выборка? Оглянитесь вокруг. [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Сидоров Кому: Иванов Дата: 08.10.2004 12:01:53 Какая выборка? Оглянитесь вокруг. Тогда надо писать: в архитектуре наблюдается застой, а не в теории... В теории как раз традиционно все ОК. [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Иванов Кому: Волков Дата: 09.10.2004 10:27:05 Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть... [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] [ в начало ] | Тема «Застой в теории архитектуры» Обсуждения-аналоги (нити) | Корень |
|
| В теории архитектуры наблюдается застой [сообщений: 6] [изм.: 089.10.2004 10:27:05] [прочитана] | |
|
| Хорошо ли учат в ВУЗах архитектуре? [сообщений: 4] [изм.: 08.10.2004 13:30:26] [открыта] | |
|
| О критериях качества архитектурных решений [сообщений: 4] [изм.: 07.10.2006 15:40:26] [прочитана] | [Добавить аналогичное обсуждение] [ Присоединить нить к текущей ] Авторы |
| Петров | | | | Козлов | => | Петров | | | Петров | => | Козлов | | | Волков | => | Всем |
| | Автор: Петров Дело не в теории. Просто в ВУЗах плохо учат... [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Козлов Кому: Петров Дата: 08.10.2004 13:17:45 Просто в ВУЗах плохо учат... В ВУЗах учат нормально. Просто все из страны бегут. [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Петров Кому: Козлов Дата: 08.10.2004 13:25:37 В ВУЗах учат нормально. Просто все из страны бегут. Что значит нормально? Какие у Вас критерии? [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Волков Кому: Всем Дата: 08.10.2004 13:30:26 Вопрос о критериях очень интересен. А до тех пор, пока эту тему не затронули, было скучно читать. И важно говорить не столько о критериях обучения, сколько о критериях качества архитектурных решений. Вот что я предлагаю: ++++++++++ -------------------- ..................... [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] [ в начало ] | Тема «Застой в теории архитектуры» Обсуждения-аналоги (нити) | Корень |
|
| В теории архитектуры наблюдается застой [сообщений: 6] [изм.: 09.10.2004 10:27:05] [прочитана] | |
|
| Хорошо ли учат в ВУЗах архитектуре? [сообщений: 4] [изм.: 07.10.2006 15:35:06] [прочитана] | |
|
| О критериях качества архитектурных решений [сообщений: 4] [изм.: 09.10.2004 10:27:05] [открыта] | [Добавить аналогичное обсуждение] [ Присоединить нить к текущей ] Авторы |
| Волков | | | | Петров | => | Волков | | | Волков | => | Петров | | | Иванов | => | Волков |
| | Автор: Волков Вопрос о критериях очень интересен. А до тех пор, пока эту тему не затронули было скучно читать. И важно говорить не столько о критериях обучения, сколько о критериях качества архитектурных решений. Вот, что я предлагаю: ++++++++++ -------------------- ..................... [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Петров Кому: Волков Дата: 08.10.2004 15:19:59 Нет, эти критерии некорректны! [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Волков Кому: Петров Дата: 09.10.2004 10:20:42 Нет эти критерии некорректны... А если так: +++++++++++++++ +_+_+_+_+_+_+_+_ --++--++--++--++--++ Что скажете? [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] От: Иванов Кому: Волков Дата: 09.10.2004 10:27:05 Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть... [ответить] [новое сообщение для всех] [все ответы на это сообщение] [создать нить] [отображение...] [удалить ] [ в начало ] | Читатель обратил внимание и на две опции, расположенные слева на панели: Первая позволяет начать новое обсуждение сразу в текущем контексте, если это органично. А вторая - присоединять близкие по содержанию обсуждения из других контекстов. Выше был приведен условный пример. Ниже дана ссылка на одно из реальных обсуждений сети: «Как сделать так, чтобы вас заметили». Ссылка дана на Корень, однако, поглядите все нити слева на панели. Таким образом, теперь иерархия Форума такая: -
Форум - Категории (группы Тем)
- Темы Форума
- «Нити» обсуждений, собранные в группу «Аналоги» - ранее был «проскок» этого уровня
Новая структура позволила ввести «контекстность» (например, группировку «Тем» и возможность оперирования уже укрупненной «группой» («пачками тем», а не «темами»), свойства которой можно описать отдельно и др.). РАЗБОР ПРИМЕРА 3. О СОПРОВОЖДЕНИИ БАЗЫ ДАННЫХ Следуя приведенной выше логике рассуждений, перестаем думать над совершенствованием вызывающего кода и встраиваем пропущенный системный уровень. Поскольку сейчас многофакторность существует из-за того, что таблицы и вызывающий код общаются напрямую, вводим между ними посредника [3] (пока еще не знаем какого, но точно знаем, что он должен быть) и формулируем к нему требования. Идеально, если все запросы вызывающий код направляет в any («куда надо»), а уже оттуда они перенаправляются конкретной таблице. Наличие таблиц и их количество скрыто от вызывающего кода. Можно беспрепятственно добавлять новые таблицы. Вызывающий код от этого не изменится. В частном случае, это можно реализовать в виде класса ДиспетчерБазы, в котором регистрируются таблицы, и который является диспетчером запросов. Поэтому мы вставляем не только «пропущенный класс», но и «пропущенный идентификатор» - идентификатор таблицы. Все запросы вызывающий код всегда направляет классу ДиспетчерБазы (где есть СправочникТаблиц с их идентификаторами), а тот, в свою очередь, перенаправляет их конкретной таблице. Раньше мы имели только идентификатор (целое число) записи в конкретной таблице, и вызывающий код должен был знать о том, какой таблице его передать. Теперь он этого не знает и знать не должен, поскольку с таблицами общается класс ДиспетчерБазы. (А ранее был проскок этого уровня.) Поэтому в качестве идентификатора будет выступать пара: 1. Идентификатор таблицы. 2. Идентификатор записи. Эту пару можно «оформить» в новый класс СправочникИдентификаторов, где, собственно, справочник идентификаторов и будет находиться, и передавать его базе данных при запросе: Запись = ДиспетчерБазы.ПолучитьЗапись(СправочникИдентификаторов); Если нет желания создавать специальный класс, справочник идентификаторов можно «свернуть» в целое число. Например, задав для каждой таблицы свои диапазоны: • 1 – 1 000 000 – диапазон идентификаторов для 1-ой таблицы; • 1 000 001 – 2 000 000 – диапазон идентификаторов для 2-ой таблицы; • 2 000 001 – 3 000 000 – диапазон идентификаторов для 3-ей таблицы; • и т.д. Возможны, конечно, и иные реализации. Тем более, мы предполагаем, что необходимость инкапсулирования таблиц от вызывающего кода была очевидна и во время прочтения условий задачи. Но что общего мы находим во всех трех примерах? Причина каждой задачи – это «проскок одного из системных уровней» при проектировании. -
В первом примере был проскок уровня «Группа Прав». Ранее были просто «права», и в этом заключалась причина задачи. -
Во втором примере был проскок уровня «Смысловые Нити». Ранее сообщения группировались сразу в «Тему», и в этом заключалась причина задачи. -
В третьем примере был проскок уровня «Диспетчер Таблиц». Ранее таблицы и вызывающий код общались напрямую, и в этом заключалась причина задачи. И в этом месте мы уйдем от «частных случаев» к «общей закономерности».  | МИ. ЧЕМ «ИСТОРИЧЕСКИЕ ПРИМЕРЫ» ПОХОЖИ НА ТРИ ПРЕДЫДУЩИХ? | Вспомним «эволюцию языков программирования»: -
Позже произошел первый надсистемный переход: «нули и единицы» сгруппировались в «мнемоники» - часто повторяющиеся готовые сочетания «нулей и единиц», например, для команды пересылки данных – MOV, для команды сложения – ADD и т.п. Т.е. появились «ассемблеры» [8].
Заметим: мнемоники, как бы сказали теперь, «инкапсулировали» (закрыли) «нули и единицы» от программиста. Стали «интерфейсом» между программистом и «нулями». -
Затем произошел второй надсистемный переход: «простые ассемблеры» заместились «макроассемблерами», которые могли оперировать уже «группой мнемоник». И в этом смысле их стали называть «более мощными» [9]. И здесь надо отметить сразу два «надсистемных эффекта»: -
Каждая инструкция языка высокого уровня стала «еще мощней», т.е. компилировалась «сразу в десятки машинных команд». -
Инструкция языка высокого уровня понималась целиком, а операторы, входящие в инструкцию сами по себе (вне ее контекста), не имели смысла. Подобно тому, как в литературе обладают своим смыслом целиком фраза или стихотворение, а слова, их образующие, этим смыслом не обладают [9]. В результате исчезло соответствие между теми командами, которые пишет программист, и теми командами, которые исполняет процессор. Как известно, это позволило создавать языки, «заточенные» под предметную область: -
Фортран – для решения инженерных задач и научных расчетов. -
Кобол – для решения экономических задач. -
Алгол-68, Паскаль – для обучения студентов программированию. -
Бейсик – для написания диалогов пользователя с ЭВМ. -
Си – для написания операционных систем, трансляторов, баз данных и других системных и прикладных программ. -
Пролог – для методов автоматического доказательства теорем. -
Ада – для моделирования параллельного решения задач. [7] Изобретение языков высокого уровня позволило осуществлять перенос программы с машины на машину. И это позволило программисту (пишущему на высоком уровне) «не знать» или «знать минимально» устройство машины. Как бы сказали теперь, эти языки «инкапсулировали» (закрыли) «устройство машины» от программиста. Стали «интерфейсом» между программистом и компьютером. -
Затем произошел четвертый надсистемный переход: «структурное программирование» вытеснило «линейное». Программа стала пониматься как группа (читай: «надсистема») модулей, которые можно писать отдельно, а проектирование в значительной степени стало пониматься как проектирование интерфейсов для общения модулей. Если же поглядеть «через микроскоп» только на эволюцию языков высокого уровня, мы увидим в ином контексте те же эффекты: -
Языки первого поколения (FORTRAN I, ALGOL58, Flowmatic, IPL V) - это ассемблерные команды, которые группируются в вычислительные операции (сложение, вычитание, умножение, деление, присваивание). Программа, написанная на этих языках – это набор вычислительных операций. -
Языки второго поколения (FORTRAN II, ALGOL 60) – это уже вычислительные операции, которые выносятся в процедуры. Программа, написанная на этих языках – это набор процедур. (Как здесь, так и ниже «надсистемный переход» [2] очевиден.) -
В языках третьего поколения (ALGOL 68, Pascal) появилась абстракция данных: простые типы данных группируются в сложные типы данных (структуры). Программа, написанная на этих языках – это набор типов данных и операций над ними. -
Языки третьего поколения (Modula, C) - это средства для группировки процедур в модули. Программа, написанная на этих языках – это набор модулей. -
Языки третьего и четвертого поколений (Simula, Smalltalk, C++, Eiffel) – это средства для группировки процедур и простых типов данных в классы и объекты. Программа, написанная на этих языках – это набор классов и объектов. # Ь | ДО ДИЕЗ И МИ БЕМОЛЬ. НЕ НАДО ПРОСКАКИВАТЬ ПОЛУТОНА – В ЭТОМ СОЛЬ | А теперь вновь спустимся на землю. Предположим, разработчик пишет (сегодня!) некоторую программу. Не будем рассматривать логику программы и не будем рассматривать задачи, которые она призвана решить, а зафиксируем следующие системные уровни: -
Уровень 1. Код -
Уровень 2. Программный модуль -
Уровень 3. Типовой модуль (например, подпрограмма, класс, объект) -
Уровень 4. Группы близких, но неодинаковых на 100% «типовых модулей». Для их группировки «изобретают контекст», либо злоупотребляют «полиморфным наследованием». -
Уровень 5. Наборы из (2х, 3х, 4х...) «типовых модулей», объединенных общим контекстом (замыслом). Например, «паттерны проектирования» [12] или иное. (Об ином в следующих публикациях.) -
Уровень 6. Вся программа. Неважно, какую среду программирования и какой язык использует разработчик. В контексте данного материала важно то, что он думает над проектом, понимая его как набор сущностей третьего или четвертого уровня, куда он в процессе работы добавляет сущности уровня 1, 2 и 3. А потом из этих сущностей уровня "1,2,3" он пишет сразу объект уровня 6 (программу), совершая, тем самым, «проскок уровней». Проявления данной ошибки в логике проектирования нам уже известны – «многофакторность и противоречивость», а проще говоря - «сложность и глючность» программ. Коллеги иногда делают замечание о том, что «паттерны проектирования» [12] как раз иллюстрируют нам уровень, который ранее проскакивали. Мы пока и не спорим, просто стараемся показать общую картину.  | ФА. ПРО ВЕРХ И ПРО НИЗ. НЕ ТОЛЬКО ЛИРИЧЕСКОЕ ОКОНЧАНИЕ | Действительно, создать качественную программу «из объектов», двигаясь «снизу вверх» (от подсистем к системе; от реализации к проекту), можно только при условии предельной простоты такой программы. Однако, похоже, существует инерция мышления, оставшаяся с тех времен, когда все писали на низком уровне, и мысли о реализации неизбежно занимали наибольший промежуток времени. И многие программисты (конечно, не все) часто думают «снизу вверх». Больше над реализацией, чем над проектом. Но, например, хороший архитектор никогда не проектирует дом «из квартир», а думает о нем сразу «в целом», «вписывает» в контекст окружающей среды, пользуется знаниями о готовых «стилях» (или создает свой стиль, зная о других). Хороший авиаконструктор не проектирует новый самолет «из его элементов», но пытается понять, как машина «летает в целом», или отталкивается от «принципов полета этого класса машин» и т.д., и т.п. Мышление «снизу вверх» сродни попытке сложить организм из атомов углерода и водорода. Теоретически так сделать можно, но очень уж «многофакторно» и затратно как по времени, так и по ресурсам. И все равно, несмотря на затраты и при квалифицированной работе, получится урод + «теория неизбежности ошибок» вместо качественного продукта. За исключением, может быть, тех случаев, когда «организмом» (перепутав термины) назвали что-то предельно простое (например, 1 звено СН). Для того, чтобы "сложить организм", надо представить его в целом и понять иерархию его качественных уровней. (Наверняка, что-то пропущено, но сейчас дело не в этом). С проектной точки зрения, надо смотреть «сверху вниз» и не надо проскакивать системные уровни. Не стоит, например, пытаться строить органы из белков, минуя построение клеток - резко возрастают требования к квалификации «строителя» без какой-либо гарантии качества (наоборот, «глючность» вырастет независимо от квалификации). Аналогично: можно написать графический редактор и в машинных кодах, но лучше не надо. Важно обратить внимание на то, что каждый верхний уровень иерархии является «контекстом» для предыдущего. И, собственно, инкапсулирует его в себе. А сам контекст задается надконтекстом и т.д. Приведем характерную цитату из Г.С. Альтшуллера (Автора ТРИЗ), сказанную по другому поводу, но дающую точную аналогию: «Сверхцивилизация мыслится на уровне общества, но только более развитого, более энергетически вооруженного. А на самом деле сверхцивилизации должны быть этажом выше, на уровне надобщества. Может ли отдельная клетка рассчитывать на то, что именно ее будет специально искать (для установления контакта!) организм?» [1] То есть сверхцивилизация не ищет нас потому, что мы инкапсулированы в каком-то подклассе :-). И ей это просто «по барабану». Так, пользователь компьютера не интересуется программным кодом. Или: девушка любит юношу, но ей безразличны его аминокислоты. Совсем уж вернемся к программированию. Программистам, даже и при создании конкретной программы, важно постоянно держать в памяти следующее: как минимум, одна из закономерностей развития их отрасли - это «надсистемные переходы» (см. также переходы по «этажной схеме») [1]. При этом каждое следующее серьезное изобретение в области программирования - это почти всегда изобретение следующего интерфейса (это и есть «этаж») между системными «слоями»: -
Изобретение операционной системы - это изобретение интерфейса между машиной и приложениями. Операционная система инкапсулирует в себе соотв. функции. -
Изобретение языков программирования (например, ассемблера) - это изобретение интерфейса между кодом и человеком. Язык инкапсулирует в себе код. -
Изобретение языков более высокого уровня – то же самое на следующей стадии. -
Изобретение объектно-ориентированного программирования – это попытка создать интерфейс между функциями ("методами") и разработчиком. -
Поэтому нынешнее явление миру «шаблонно-ориентированного программирования» [12, стр 163] - совершенно закономерный надсистемный переход от «объектов» и «классов» к их готовым контекстным сочетаниям. -
Наверное, закономерен и дальнейший переход от «мышления отдельными шаблонами» к мышлению их готовыми сочетаниями (готовыми надсистемами из шаблонов). Давайте назовем эти готовые сочетания шаблонов «стилями». И тогда будет переход к «стильному программированию». Характерна цитаты из [12, стр 178]: «Шаблоны высшего уровня ограничивают шаблоны низшего». Вот-вот, оно самое. Но красивее будет сказать: «Стили инкапсулируют шаблоны, как шаблоны инкапсулируют классы и объекты, как классы инкапсулируют объекты и методы (функции)». А еще лучше смотреть сразу на всю эту закономерность в целом. И проектировать (совершенствовать) даже конкретную программу «методом уяснения ее иерархии и продвижения дальше по закономерности». См. еще раз первые три примера. Совершенно (в этот момент!) можно не думать о реализации (она сама упростится, если следовать данному правилу). Назовем это "тенденциозным программированием". Однако чтобы не уйти в философию, на этом и остановимся. ЛИТЕРАТУРА: -
-
-
-
-
-
-
-
-
Лео Броди. Способ мышления – Форт. Язык и философия для решения задач, глава 1 «Философия Форта». -
Гради Буч. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер с англ. – М . : "Издательство Бином", СПб: "Невский диалект",1998 г. Или электронная версия. -
-
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию: Пер. с англ. – М . : Издательский дом «Вильямс», 2002. – 288 с.: ил. -
Материал опубликован на сайте "Открытые методики рекламы и PR "Рекламное Измерение" 23 января 2007 г. КОНТАКТ: Сычев С.В. тел./факс: (863) 2-699-123, 2-698-765 e-mail: sch@triz-ri.ru skype: triz-ri
Лебедев К.А. e-mail: askofen@mail.ru
|