279
Воспользуйтесь колесиком мышки чтобы настроить масштаб
aaaadddaaaa
О ПОТЕРЯННОМ УРОВНЕ

Приложения ТРИЗ к программированию

© Сергей Сычёв, TRIZ-RI Group, Кирилл Лебедев, г. Санкт-Петербург

Приложения ТРИЗ к программированию. О потерянном уровне


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


ДО. ТРИ ПОХОЖИХ И НЕПОХОЖИХ ПРИМЕРА

Приступим к ним без вступлений.

ПРИМЕР 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 Категория "… и т.д. 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
Это интересно, конечно, но, что Вы скажете по теме? Считаете ли Вы, что застой в теории архитектуры все же есть..?

[ответить] [новое сообщение для всех] [все ответы на это сообщение]

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

  • В теории архитектуры наблюдается застой

  • Хорошо ли учат в ВУЗах архитектуре?

  • О критериях качества архитектурных решений

Но поскольку все они встроены в контекст одного обсуждения (участники Форума общаются друг с другом), то на несколько "Тем" их не разорвать.

Решение заключается в разделении "Темы" на смысловые "Нити" с последующим помещением всех этих "Нитей" в общий контекст "Обсуждения-аналоги":

У каждого сообщения (если смотреть со стороны "администратора") появилась опция "создать нить". После нажатия на соответствующую ссылку вводим название "Нити" и сохраняем. Заголовок появляется слева на панели, а выбранное сообщение становится первым в новой смысловой "Нити" справа.

Кроме того, каждое сообщение теперь можно отобразить в любую из "Нитей". И те сообщения, которые (по смыслу) могут быть отображены в нескольких "Нитях", отображаются в нескольких. И, конечно, где необходимо, добавим гиперссылки.

Теперь, если нажать на "Корень", то увидим все сообщения подряд, как выше. А если на конкретную "нить", то увидим сообщения принадлежащие ей. См. ниже:

Тема "Застой в теории архитектуры"

 

Обсуждения-аналоги(нити)

Корень

   

В теории архитектуры наблюдается застой [сообщений: 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 - 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]: "Шаблоны высшего уровня ограничивают шаблоны низшего".

Вот-вот, оно самое. Но красивее будет сказать: "Стили инкапсулируют шаблоны, как шаблоны инкапсулируют классы и объекты, как классы инкапсулируют объекты и методы (функции)".

А еще лучше смотреть сразу на всю эту закономерность в целом. И проектировать (совершенствовать) даже конкретную программу "методом уяснения ее иерархии и продвижения дальше по закономерности". См. еще раз первые три примера.

Совершенно (в этот момент!) можно не думать о реализации (она сама упростится, если следовать данному правилу). Назовем это "тенденциозным программированием".

Однако чтобы не уйти в философию, на этом и остановимся.

ЛИТЕРАТУРА:

Материал опубликован на сайте "Открытые методики рекламы и PR "Рекламное Измерение" 23 января 2007 г.

aaaadddaaaa