Модульные описания
Когда интерес стейкхолдера относится не ко времени работы системы, а ко времени построения системы - модульного синтеза, закупки модулей, сборки системы из модулей, то он обращается к модульным описаниям. Модульные описания отвечают на вопрос «как сделана система» (ср. с компонентным «как работает система»), на модульных диаграммах показываются модули (modules), соединяемые через интерфейсы (interfaces, буквально -- «междумордия», «то, что между»). Интерерфейс обычно описывается каким-то стандартом, описывающим как свойства соединения, так и происходящее в ходе взаимодействия модулей через соединение. Интерфейсы модулей похожи на порты компонент в том плане, что это именно места присоединения, они не конструктивные элементы, они не занимают объёма в пространстве, хотя у них и может быть форма. Вилка и штепсель, гнездо и штеккер: интерфейс - это то, что между ними. А сама физическая вилка? Это интерфейсный модуль, главное назначение которого - обеспечить какой-то интерфейс. И у этого модуля два интерфейса: один целевой, а другой - присоединяющий его к какому-то модулю, для которого нужен целевой интерфейс. Вот пример такого интерфейсного модуля (который в просторечии называют USB-интерфейс, что неверно - у него есть ещё и сигнальный интерфейс к плате, и отдельный интерфейс к питанию и даже интерфейс к человеку: светодиод, который мигает, когда идёт передача данных и кнопка включения, а ещё есть механический интерфейс крепления к корпусу или другой плате):
А как же соединения, которые нужны для работы - все эти трубы, кабели, волноводы? Это тоже модули, и у них есть свои интерфейсы: они находятся между ними и теми модулями, которые они соединяют. Что проходит через эти интерфейсы и как оно связано с работой всей системы?! Неизвестно, ибо речь идёт о конструктивных единицах: функции тут не определить, для этого нужно выходить за пределы модульного описания. Единственное, что важно, это наличие соединения: монтажник должен убедиться, что соединение установлено, модуль сможет выполнять свой сервис. Так что для интерфейсов известны правила, по которым устанавливается соединение через интерфейс, но неизвестно, что именно и зачем передаётся через этот интерфейс - это будет известным только из принципиальной схемы. Например, принтер и компьютер связаны через USB интерфейс, но какая информация идёт принтеру, это интерфейсу неизвестно. Утюг к электросети подсоединён через интерфейс между евровилкой и евророзеткой, но этому интерфейсу неизвестно, какой через неё пойдёт ток и зачем. С другой стороны, известны предельные значения тока, который может пройти через этот интерфейс, равно как предельное количество информации, которое может пройти через USB-интерфейс. Задача модульного синтеза выбрать такие интерфейсы, которые смогли бы выдержать соединения, предусмотренные компонентной структурой системы.
Вот ещё пример модульного описания, в этом случае речь идёт просто о списке комплектующих, которые нужно купить для изготовления какой-то старинной версии iPhone:
Обратите внимание, сколько тут упоминается разных стандартов: GPS, HSPDA, DDR, Bluetooth - перечисление интерфейсов обычно для модульных описаний. Ведь вся суть модулей - это замена реализации какой-то функции путём простой замены модуля на стандартном интерфейсе. Вместо одного принтера через интерфейс USB к компьютеру можно подключить другой экземпляр принтера той же марки, или даже принтер другой марки, или не принтер, а какое-то другое устройство (скажем, сканер, или даже дополнительный дисплей) - без стандартизации интерфейса это было бы невозможно.
Платформы и технологические стеки
Если рассмотреть модульную холархию, то в ней можно увидеть какие-то наборы мелких конструктивных «кирпичиков», представляющих через свои интерфейсы сервисы для сборки на их основе «кирпичиков» более высокого уровня. Вот такой согласованный по предоставляемым ими совместно сервисам набор модулей с их предопределёнными интерфейсами называют платформой.
Платформа - это всегда модульное рассмотрение, обсуждение платформы всегда связано с её сервисами, т.е. внешним поведением, предоставляемом на интерфейсе к другим модулям. Для программных модулей этот интерфейс обычно называется API (application program interface), программный интерфейс приложения. Если речь идёт не о программной системе, то можно говорить просто об интерфейсе приложения, или прикладном интерфейсе. Прикладной - это определяемый использующей системой платформы (согласованного в части выполнения каких-то сервисов набора модулей) или модуля. Приложение - это использующая система для платформы модуля, части приложения находятся в операционном окружении модуля.
Основной вопрос при обсуждении платформ - это так называемая видимость интерфейсов. Интерфейсы какого-то низкого системного уровня не должны быть видны снаружи модуля, то есть невозможно соединение модулей иначе, чем через предусмотренные в нём интерфейсы. Грубо говоря, если у вас коробочка с каким-то разъёмом, то нельзя воткнуть внешнее устройство не в этот разъём, а куда-нибудь внутрь коробочки, мимо этого разъёма. Для обсуждения видимости интерфейсов используется диаграмма модульных уровней, диаграмма холархии системных уровней. Каждый уровень отделён от другого уровня каким-то интерфейсом. Реализации нижестоящих уровней тем самым могут быть сменены так, что использующая система этого не заметит. А итоговую холархию называют платформенным стеком или технологическим стеком (stack, стопка - диаграммы похожи на стопку подносов в столовой или стопку листов бумаги в пачке). Вот пример различных технологических стеков для организации связи (
http://www.slideshare.net/Techtsunami/cn-prt-iot-v1):
На диаграмме видно, что в разных стандартах связи определяются пять уровней (по отношению часть-целое) модулей, которые можно разделить реализующих передачу физического сигнала (physical), передачу данных (Data Link), использующую передачу физического сигнала, и так далее. Неважно, что делают эти уровни платформенного стека, но главное тут то, что никакой модуль вышестоящего уровня «не видит» модули более низкого уровня (не имеет к ним доступа, не может туда «воткнуться»), чем находящийся непосредственно под ним, и интерфейсы реализующих сервисы этих платформенных уровней стандартизованы - как стандартизован и сам набор этих уровней.
Платформенность даёт возможность эффективного разделения труда: реализацией каждого уровня платформенного стека может заниматься отдельная команда, и команды могут соревноваться за эффективность реализации. Инженеры, использующие какие-то платформы для создания своих целевых систем могут не задумываться, как именно и из каких систем были сделаны эти платформы. Они могут просто использовать прикладной интерфейс этих платформ. А если этот прикладной интерфейс стандартизован, то они могут ещё и выбрать подходящий им по цене и характеристикам вариант реализации. И это происходит намного уровней вверх и много уровней вниз по технологическому стеку.
Деньги обычно приходят от удачного и массового использования верхнего, прикладного уровня. Но вот «перетряхивание» всего технологического/платформенного стека, перестройка всех рынков идут тогда, когда меняется принцип реализации самого нижнего уровня модулей, меняется платформа нижнего уровня. Например, когда в компьютерах поменялись механические или пневматические элементы на лампы, компьютеры стали масштабируемы и они начали напоминать уже функционально современные компьютеры, а не калькуляторы прошлых лет. Замена ламп на дискретную полупроводниковую технику позволила наладить массовый выпуск компьютеров и это разительно изменило компьютерную технику. Замена дискретной электроники на большие полупроводниковые интегральные схемы опять перевернуло весь компьютерный рынок со всеми надстройками программного обеспечения. Замена CPU на GPU перевернула рынок искусственного интеллекта. Замена людей-исполнителей на роботов-исполнителей переворачивает все промышленные предприятия.
Необходимость хорошей модульности
Система должна собираться из модулей по принципу подводной лодки, в которой все отсеки делаются максимально автономными - если один из них будет затоплен, это не будет означать затопления подводной лодки. В системе все части системы взаимосвязаны, в системном окружении они ведут себя совершенно не так, как могли бы вести себя без системного окружения. Если у нас нет интерфейсов, через которые мы контролируем все взаимодействия в системе, то любая попытка улучшить модуль может привести к улучшению только этого модуля - но ухудшению системы в целом через влияние на другие модули по неотслеживаемым связям.
Интерфейс - это не просто соединение, это соединение через какой-то вполне определённый канал по вполне определённому протоколу (лучше бы -- определяемому стандартом, хотя это и не всегда соблюдается), так что это взаимодействие можно отследить, и ошибка не распространится по системе. Более того, можно просто заменить модуль на альтернативный (это проще, если интерфейс стандартный) - и система продолжит работать. Если же какие-то связи будут проходить не через интерфейсы модулей, а система будет эти связи использовать для реализации своей функции, то замена модуля приведёт к исчезновению этих связей и нарушениям в работе системы.
Есть множество методов, которые помогают уменьшать связность модулей в создаваемой системе. Одним из наиболее известных таких методов является DSM (design/dependency structure matrix,
http://www.dsmweb.org/).
Минимальная связность модулей нужна и в «железных» системах, и в программных системах, и в организационных, и даже в танцах. Это совсем не означает, что части системы/подсистемы не находятся в тесном взаимодействии друг с другом. Это означает, что эти взаимодействия ставятся под жёсткий контроль, и подсистемы можно улучшать, а в случае стандартизации интерфейса даже заменять на принципиально другие по конструкции и принципу действия, не рискуя при этом ухудшить работу всей системы в целом.
Системный подход обычно называют холистическим, ибо он обращает внимание на систему в целом. Но нет других подходов, которые так бы интересовались разбиением на самые разные части, как системный подход. Суть системного подхода не только ко вниманию к целой системе, но и одновременному вниманию к частям системы.
* * *
Это из черновика пятой главы "Определение и описание системы" моего нового учебника системного мышления.