Приложения ТРИЗ к программированию
Иногда наблюдение за общими закономерностями помогает в решении частных задач. Инженеры подсматривают за природой, математики - за катастрофами, экономисты - за эволюцией каких-нибудь "малых групп", а куда посмотреть программисту..?
ДО. ТРИ ПОХОЖИХ И НЕПОХОЖИХ ПРИМЕРА
Приступим к ним без вступлений.
ПРИМЕР 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. НЕ УЧИТЫВАЕМ, А ГРУППИРУЕМ
Так, решение первой задачи заключается в том, чтобы:
-
Прекратить бороться с многофакторностью и/или думать над тем, какие критерии "правильные"... (прекратили)
-
Ввести понятие группы прав", которые можно создавать по любым основаниям (то есть совершить "надсистемный переход" [2]) и соответствующие правила формулировать для "группы"
-
Пользователя (который регистрируется на сайте) помещать в соответствующую "группу" либо создавать отдельную "группу прав" для данного Пользователя.
-
При необходимости в пределах каждой "группы" линейно разграничивать права разным Участникам.
-
Индексировать
Например, было так:
-
"Посетители из Москвы":
-
Михайлов
-
Петров (попал в два контекста с разными правами и потому чего-нибудь не увидит)
-
Колобков
-
Иванов
-
Медведев
-
………
-
-
"Любители темы "Занимательный буддизм"
-
Иванов
-
Петров (попал в два контекста с разными правами и потому чего-нибудь не увидит)
-
Сидоров
-
Джонсон (попал в два контекста с разными правами и потому чего-нибудь не увидит)
-
……………...
-
-
"VIP’ы"
-
Колобков
-
Волков (он не из Москвы и потому может попасть под соотв. ограничение, а VIP’ы не должны под него попадать)
-
Медведев
-
………………
-
-
"Иностранцы"
-
Джонсон (попал в две группы с разными правами и потому чего-нибудь не увидит)
-
Буш
-
Картер
-
………………
-
Стало так:
-
Группа прав 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 |
Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть..? |
[ответить] [новое сообщение для всех] [все ответы на это сообщение] |
Очевидно, уже под одним заголовком смешались три смысловые нити обсуждения:
-
В теории архитектуры наблюдается застой
-
Хорошо ли учат в ВУЗах архитектуре?
-
О критериях качества архитектурных решений
Решение заключается в разделении "Темы" на смысловые "Нити" с последующим помещением всех этих "Нитей" в общий контекст "Обсуждения-аналоги":
У каждого сообщения (если смотреть со стороны "администратора") появилась опция "создать нить". После нажатия на соответствующую ссылку вводим название "Нити" и сохраняем. Заголовок появляется слева на панели, а выбранное сообщение становится первым в новой смысловой "Нити" справа.
Кроме того, каждое сообщение теперь можно отобразить в любую из "Нитей". И те сообщения, которые (по смыслу) могут быть отображены в нескольких "Нитях", отображаются в нескольких. И, конечно, где необходимо, добавим гиперссылки.
Теперь, если нажать на "Корень", то увидим все сообщения подряд, как выше. А если на конкретную "нить", то увидим сообщения принадлежащие ей. См. ниже:
Тема "Застой в теории архитектуры"
Обсуждения-аналоги(нити)
[Добавить аналогичное обсуждение]
Авторы
|
|
Автор: Иванов В теории архитектуры наблюдается застой… Он выражается в том, что … [ответить] [новое сообщение для всех] [все ответы на это сообщение]
[создатьнить] [отображение ...] [удалить ] От: Петров Кому: Иванов Дата: 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 Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть...
[ответить] [новое сообщение для всех] [все ответы на это сообщение]
[создатьнить] [отображение ...] [удалить ] [ в начало ] |
Тема «Застой в теории архитектуры»
Обсуждения-аналоги (нити)
Корень
[Добавить аналогичное обсуждение]
Авторы
|
|
Автор: Петров Дело не в теории. Просто в ВУЗах плохо учат...
[ответить] [новое сообщение для всех] [все ответы на это сообщение]
[создатьнить] [отображение ...] [удалить ] От: Козлов Кому: Петров Дата: 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 Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть...
[ответить] [новое сообщение для всех] [все ответы на это сообщение]
[создатьнить] [отображение ...] [удалить ] [ в начало ] |
Читатель обратил внимание и на две опции, расположенные слева на панели:
-
"Добавить аналогичное обсуждение" и
-
"Присоединить нить к текущей"
Первая позволяет начать новое обсуждение сразу в текущем контексте, если это органично. А вторая - присоединять близкие по содержанию обсуждения из других контекстов.
Выше был приведен условный пример. Ниже дана ссылка на одно из реальных обсуждений сети: "Как сделать так, чтобы вас заметили". Ссылка дана на Корень, однако, поглядите все нити слева на панели.
Таким образом, теперь иерархия Форума такая:
-
Форум
-
Категории (группы Тем)
-
Темы Форума
-
"Нити" обсуждений, собранные в группу "Аналоги" - ранее был "проскок" этого уровня
-
Сообщения в Темах Форума
Новая структура позволила ввести "контекстность" (например, группировку "Тем" и возможность оперирования уже укрупненной "группой" ("пачками тем", а не "темами"), свойства которой можно описать отдельно и др.).
РАЗБОР ПРИМЕРА 3. О СОПРОВОЖДЕНИИ БАЗЫ ДАННЫХ
Следуя приведенной выше логике рассуждений, перестаем думать над совершенствованием вызывающего кода и встраиваем пропущенный системный уровень. Поскольку сейчас многофакторность существует из-за того, что таблицы и вызывающий код общаются напрямую, вводим между ними посредника [3] (пока еще не знаем какого, но точно знаем, что он должен быть) и формулируем к нему требования.
Идеально, если все запросы вызывающий код направляет в any ("куда надо"), а уже оттуда они перенаправляются конкретной таблице. Наличие таблиц и их количество скрыто от вызывающего кода. Можно беспрепятственно добавлять новые таблицы. Вызывающий код от этого не изменится.
В частном случае, это можно реализовать в виде класса ДиспетчерБазы, в котором регистрируются таблицы, и который является диспетчером запросов. Поэтому мы вставляем не только "пропущенный класс", но и "пропущенный идентификатор" - идентификатор таблицы.
Все запросы вызывающий код всегда направляет классу ДиспетчерБазы (где есть СправочникТаблиц с их идентификаторами), а тот, в свою очередь, перенаправляет их конкретной таблице.
Раньше мы имели только идентификатор (целое число) записи в конкретной таблице, и вызывающий код должен был знать о том, какой таблице его передать. Теперь он этого не знает и знать не должен, поскольку с таблицами общается класс ДиспетчерБазы. (А ранее был проскок этого уровня.) Поэтому в качестве идентификатора будет выступать пара:
- Идентификатор таблицы.
- Идентификатор записи.
Эту пару можно "оформить" в новый класс СправочникИдентификаторов, где, собственно, справочник идентификаторов и будет находиться, и передавать его базе данных при запросе:
Запись = ДиспетчерБазы.ПолучитьЗапись(СправочникИдентификаторов);
Если нет желания создавать специальный класс, справочник идентификаторов можно "свернуть" в целое число. Например, задав для каждой таблицы свои диапазоны:
-
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]: "Шаблоны высшего уровня ограничивают шаблоны низшего".
Вот-вот, оно самое. Но красивее будет сказать: "Стили инкапсулируют шаблоны, как шаблоны инкапсулируют классы и объекты, как классы инкапсулируют объекты и методы (функции)".
А еще лучше смотреть сразу на всю эту закономерность в целом. И проектировать (совершенствовать) даже конкретную программу "методом уяснения ее иерархии и продвижения дальше по закономерности". См. еще раз первые три примера.
Совершенно (в этот момент!) можно не думать о реализации (она сама упростится, если следовать данному правилу). Назовем это "тенденциозным программированием".
Однако чтобы не уйти в философию, на этом и остановимся.
ЛИТЕРАТУРА:
-
Альтшуллер Г.С. Структура талантливого мышления.
-
Сычев С.В., Лебедев К.А. Как вспомнить "и так известное".
-
Сычев С.В., Лебедев К.А. Освобождение узников оператора "IF".
-
Сычев С.В., Лебедев К.А. Что увидишь, то и неси (в статье "TStupid, или Новейший органон").
-
Сычев С.В., Лебедев К.А. Неважно, где рисовать(в статье "TStupid, или Новейший органон").
-
Сычев С.В., Лебедев К.А. Пусть само проявится (в статье "TStupid, или Новейший органон").
-
Лео Броди. Способ мышления – Форт. Язык и философия для решения задач, глава 1 "Философия Форта".
-
Гради Буч. Объектно-ориентированный анализ и проектирование с примерами приложений на C++, 2-е изд./Пер с англ. М.: "Издательство Бином", СПб: "Невский диалект", 1998 г. Или электронная версия.
-
Александр Костинский, Владимир Губайловский. Эволюция языков программирования.
- Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию: Пер.англ. М.: Издательский дом "Вильямс" 2002. 288 с.: ил.
-
Реферат на тему "Языки программирования. Их классификация и развитие".
Материал опубликован на сайте "Открытые методики рекламы и PR "Рекламное Измерение" 23 января 2007 г.