Осмысленная визуализация при анализе и проектировании информационных систем
Спойлер
Об используемой терминологии
Визуализация — представление информации или физического явления в виде, удобном для зрительного наблюдения и анализа.
Средство визуализации — это различные графические представления информации. Например, графики, диаграммы, схемы.
Иными словами, термин «визуализация» означает процесс, а «средство визуализации» — это уже наглядный результат.
И ещё небольшой дисклеймер
Статья может показаться дискуссионной и полной субъективизма. Кому-то полученные выводы могут показаться очевидными, но, надеюсь, оттого не менее полезными, ведь преследуемая мною цель состоит в том, чтобы заставить задуматься о применяемых практиках и в чём-то по-новому взглянуть на привычные вещи.
Вступление
Сегодня, пожалуй, трудно найти IT-специалиста, который в ходе своей деятельности контактировал бы только лишь с текстом. А таблицы, схемы и диаграммы так вообще прочно ассоциируются с работой системного аналитика. Причина этого простая: текст, оставаясь неотъемлемой частью любой документации и её ядром, не всегда может обеспечить полное и ясное представление информации. Он может быть неоднозначным, многословным и трудным для восприятия, и особенно когда речь идёт об описании сложных взаимосвязей и отношений между различными системами и их компонентами.
Если к этому добавить результаты исследований, утверждающих, что от 70% до 90% информации, получаемой мозгом, поступает через визуальные каналы, и что львиная доля человеческих ресурсов оптимизирована для обработки изображений, то становится очевидным важность визуализации. Но это теория, а насколько гладко обстоят дела на практике?
Проблема выбора
Если посмотреть многочисленные книги, статьи и видеоролики, возникнет ощущение, что средств визуализации много, все существующие нотации решают плюс-минус одни и те же или похожие задачи, но вопросам выбора наиболее подходящего инструмента и получаемой при этом ценности уделяется всё ещё недостаточно внимания.
Как результат, когда у аналитика, особенно начинающего, дело доходит до практической задачи, часто возникает вопрос: «А какую тут лучше изобразить диаграмму? Я подходящей не знаю.» или «Здесь может подойти несколько диаграмм, какую выбрать? Или вообще стоит посмотреть на другие нотации?».
Да, кто-то скажет, что у него с годами и опытом выработалось понимание, кто-то другой может сказать, что использует 2 или, максимум 3, вида диаграмм, ему хватает и вообще не страдает от проблемы выбора, но… Давайте рассмотрим 3 примера из жизни.
Кейс 1. Диаграмма деятельности: за деревьями и леса не видно
Все, думаю, знакомы с диаграммой деятельности UML (Activity Diagram) и её более простой формой — блок-схемой. Рисовать алгоритмы в виде блок-схем учат ещё в школе на уроках информатики, а некоторым приходится тем же заниматься ещё и в вузе. Как результат, привычка визуализировать алгоритмы в виде блок-схем порой проникает так глубоко, что некоторые аналитики считают естественным использовать диаграммы деятельности UML в самых разных ситуациях, в частности в задачах описания интеграционных взаимодействий.
Но чем это может быть плохо?
Во-первых, из прочтения диаграммы деятельности не становится очевидным, какие системы, компоненты систем или объекты обмениваются сообщениями. Имена взаимодействующих сущностей и вызываемых методов раскиданы по всей диаграмме и, чтобы составить полную картину участников процесса, надо предварительно вчитаться в диаграмму и выписать из всех упомянутых на ней участников.
Если каждому взаимодействующему компоненту назначить свою дорожку на диаграмме, то это может улучшить наглядность, но, вероятно, одновременно с этим произойдёт увеличение размеров диаграммы.
Слева — пример с одной дорожкой, справа — пример с тремя дорожками
Во-вторых, такие диаграммы становятся нечитаемыми в силу того, что они быстро разрастаются. Одной из причин может стать то, что автор нарушает уровни абстракции и наравне, или даже вместо, высокоуровневых деятельностей и действий, позволяющих на диаграмме деятельности представить общую логику процесса, в блоках фактически уже прослеживаются инструкции на уровне псевдокода.
В-третьих, теряется фокус на временно́м порядке взаимодействий: кто, в какой последовательности, когда, с какими задержками включается в процесс; на диаграмме активностей наглядно не покажешь время создания и уничтожения объекта в памяти, периоды его активности.
Мне доводилось видеть примеры подобного документирования. И здесь хотелось бы рассмотреть намеренно упрощённый фрагмент из одной из них. Возможно, это не самый «тяжёлый» пример, но, считаю, достаточно наглядный. Выглядело это примерно так: большая диаграмма, ориентированная сверху вниз, в которой в рамках единственной дорожки в блоках было указано, что следует выполнить веб-сервису по созданию кредита физического лица в случае его вызова из смежной системы. Сперва следовало взять из тела поступившего запроса поля, относящиеся к персональным данным клиента, выполнить вызов функции комплаенс-проверок, потом при успешности их результатов провести сложную процедуру поиска данного клиента в собственном справочнике клиентов. Потом предписывалось обработать результаты поиска и по итогу определить идентификатор клиента, сохранить его в переменную, вводимую в рассмотрение непосредственно на диаграмме, и далее в блоках диаграммы уже оперировали этой переменной. Диаграмма завершалась описанием формирования ответа вызывающей системе.
Примерный вид подхода, использованного при описании работы сервиса
В рассмотренной диаграмме было много разного. Каждое усложнение бизнес-логики (учёт новых типов кредита, срока действия паспорта или региона проживания клиента) могло потенциально привести к появлению новых параметров и манипулированию ими внутри блоков. В силу большого числа деталей стороннему наблюдателю понять логику в «крупную клетку» было нереально. Как говорится, за деревьями леса уже не видно.
Какие тут можно дать советы?
Для начала, нужно задаться вопросом, что нам важно и на каком аспекте мы хотим сфокусироваться:
если фокусируемся на последовательности взаимодействий между системами и компонентами, то наиболее предпочтительным будет использовать диаграмму последовательности. Актуальность данного варианта существенно возрастает при числе взаимодействующих компонентов более двух;
если хотим проработать поведение системы, то действительно надо использовать диаграмму деятельности, но не заниматься микропроектированием: не вводить в рассмотрение переменные, не оперировать полями структур данных и параметрами запросов и определённо не стоит заниматься написанием кода внутри диаграммы. В крайнем случае, если у вас есть веские основания для изображения пошагового детализированного алгоритма в графическом виде, лучше реализовать это в виде отдельной (дополнительной) диаграммы, оставив на основной диаграмме только общую высокоуровневую логику;
если же бизнес-сценарий не такой сложный, а вопрос находится в плоскости сопоставления и трансформации данных, передаваемых между различными системами, то стоит сделать таблицу соответствий (таблицу маппинга).
Важно понимать, что если один названный аспект не позволяет достичь нужного уровня детализации и понимания, то стоит воспользоваться сразу несколькими средствами визуализации, каждое из которых раскроет вопрос со своей стороны. Несколько диаграмм, схем, таблиц для представления сложной логики — это нормально и порой даже необходимо.
И отдельно хотелось бы остановиться на вопросе, почему диаграммы деятельности UML иногда используют в принципе как блок-схемы. Мне кажется, что здесь целый комплекс причин.
Внешняя схожесть. Да, надо признать, что диаграммы деятельности и старые-добрые (или не такие уж добрые?) блок-схемы внешне очень похожи. Неискушённый автор вполне может посчитать, что обе эти диаграммы являются своего рода диалектами (к примеру, в одном случае условие пишется внутри ромба, в другом — на исходящих из ромба дугах), а значит описание алгоритма вполне возможно.
В публикациях уделяется довольно мало внимания противопоставлению этих двух средств визуализации. Да и, признаться, не всегда понятно объясняется назначение диаграммы состояний как таковой. Вот пример: «Диаграмма активности — это диаграмма поведения UML. Он иллюстрирует рабочий процесс пошаговых действий системы. Напротив, блок-схема представляет собой графическую диаграмму, которая показывает порядок шагов для решения проблемы. Это основное различие между диаграммой деятельности и блок-схемой». Я лично ничего не понял и разницы не прочувствовал. А вот другой пример пояснений диаграммы деятельности: «Это, по сути, разновидность диаграммы состояний, где все или большая часть состояний являются некоторыми деятельностями…». Пожалуй, оставлю без комментариев.
Наличие «плохих» примеров. Нечасто, но иногда можно наткнуться на диаграммы, которые в содержащих их статьях подписаны как диаграммы деятельности, однако по своему смыслу они являются скорее блок-схемами.
Кейс 2. Диаграмма последовательности: лучше меньше, да лучше
Многие аналитики точно знают, что диаграммы последовательности (Sequence Diagram) используются для визуализации взаимодействия между компонентами решения, определения последовательности вызовов и выявления проблем в коммуникации между компонентами. Более того, иллюстрацию в виде диаграммы последовательности члены команды и согласующие эксперты часто ожидают от аналитика, внося их в свои чек-листы, так что выбор уже предопределён.
Но и здесь на практике можно встретить нюансы. Давайте рассмотрим ситуацию, когда мы реализуем некий многошаговый процесс взаимодействия с клиентом через мобильное приложение (МП). Клиент голосом выбирает в приложении продукт для покупки, и мы должны понять, что хотел клиент, предоставить ему детальную информацию и при получении согласия на то со стороны клиента осуществить оплату пластиковой картой.
Во-первых, у нас в процессе задействовано несколько систем: мобильное приложение (МП) и три бэк-системы (ниже по тексту упоминаемые как АС1, АС2 и АС3).
Во-вторых, так как у нас многошаговый процесс, то прежде чем клиент выполнит оплату, должно пройти несколько итераций взаимодействия клиента с нашей системой.
В-третьих, коль скоро взаимодействие выполняется с помощью голосового интерфейса, у нас могут возникнуть сложности с сопоставлением сказанного клиентом и каталогом продуктов; и тогда придётся либо переспрашивать, либо предлагать на выбор несколько продуктов, подходящих под запрос клиента. Также вполне реальна ситуация, когда клиент называет часть наименования, и эта часть подходит под название сразу нескольких продуктов.
В ходе проработки подобной задачи у аналитика родилось 11 диаграмм последовательности общим объёмом в 15 экранов. Одни диаграммы были меньше и проще, другие — наоборот. Автор попытался втиснуть всю логику, какая только была выявлена в ходе проведения анализа.
Возможности UML позволили реализовать задуманное: диаграммы стали изобиловать фреймами с опциональными и альтернативными ветками, а каждое взаимодействие с клиентом в силу особенностей архитектуры приводило к однотипной цепочке вызовов (от клиента к МП, от МП к АС 1 и т.д.). В итоге, гегелевский закон перехода количественных изменений в качественные проявил себя в полную силу: схемы стали попросту нечитаемыми, и к ним пришлось прикладывать текстовые описания. Надо ли говорить, что команда разработки не горела желанием всматриваться в эти схемы?
Иллюстрация того, во что могут превратиться «сиквенсы»
Напомню, что средства визуализации призваны устранять недостатки, характерные естественным языкам, упрощать понимание, и применяются, в частности, для более наглядного представления алгоритмов и логики. А в описанном примере средство визуализации в процессе насыщения деталями стало настолько неудобоваримым, что по иронии судьбы пришлось возвращаться к тексту.
Давайте подумаем, почему так произошло и как этого можно было бы избежать.
Начнём с общих соображений.
Уверен, что мы бы не оказались в описанной ситуации, если бы автор не пытался втиснуть бизнес-логику в диаграммы последовательности.
Лучшим выбором в данном случае мне представляется использование диаграмм деятельности UML или обычных текстовых юзкейсов в стиле Алистера Кобёрна (Alistair Cockburn). Там в структурированном виде можно представить всю возможную вариативность, оставляя, при этом, за скобками вопрос пересылки сообщений между системами.
Если после проработки бизнес-логики потребность в визуализации последовательности взаимодействий полностью не отпала, то тогда я бы рекомендовал придерживаться следующих эмпирических правил.
Размер диаграмм и их количество
Если число диаграмм последовательности для задачи доходит до 5 либо отдельная диаграмма приближается к размеру одного экрана, то это должно настораживать. В такой ситуации есть риск того, что вы столкнулись с одной из двух противоположностей:
вы либо показываете излишне много деталей, что делает диаграммы слишком сложными для восприятия,
либо вы пытаетесь визуализировать тривиальную логику, что отнимает ваше время, занимает место в артефакте анализа, но, при этом, никакой ценности не добавляет.
Число взаимодействующих объектов
Другой «маячок» — это если на вашей диаграмме последовательности в виде отдельных линий жизни представлено 5 или более взаимодействующих объектов. Это повод задуматься, а все ли они действительно важны для проводимого вами анализа и последующего использования членами команды разработки. Не стоит пытаться показывать все шлюзы, брокеры сообщений и иные сугубо инфраструктурные компоненты решения, если, конечно, детальная проработка такого компонента не является вашей непосредственной задачей.
Использование фреймов
Фреймы на диаграммах последовательности — полезная возможность, но использовать их нужно с осторожностью. Если их становится много, особенно если фреймы вкладываются друг в друга, то это существенно снижает наглядность визуализации и это верный признак того, что лучше логику вынести в диаграмму деятельности.
На что стоит обратить внимание помимо размера самой диаграммы
Дополнительные соображения
Другое важное правило, которым часто пренебрегают, состоит в том, чтобы строить диаграммы последовательности по возможности высокоуровнево и не пытаться представить на них текстовые сообщения, передаваемые пользователю, и другие элементы пользовательского интерфейса.
Причина в том, что высокоуровневые диаграммы продолжают оставаться актуальными значительно дольше, чем низкоуровневые. Так, если на стрелке подписан текст, который озвучивается или отображается пользователю, то изменение этого текста в приложении по запросу бизнес-заказчиков приведёт к тому, что диаграмма перестанет быть актуальной. Захотите ли вы поддерживать актуальность диаграммы в таких мелочах? Сомневаюсь. В качестве примера: лучше сделать общую надпись вроде «Сообщение о недостаточности денежных средств на карте», чем «Для совершения платежа на вашей карте недостаточно средств, попробуйте выбрать другую карту».
И, наконец, при построении диаграмм последовательности я бы рекомендовал идентифицировать и вынести повторяющиеся цепочки вызовов на отдельные диаграммы и не дублировать их, ведь при многошаговых процессах одни и те же цепочки вызовов могут повторяться по нескольку раз.
Фактически нужно сделать примерно то же самое, что делают разработчики при рефакторинге, вынося общий код в отдельный метод. Какие здесь могут быть варианты?
Можно единожды изобразить всю многократно повторяющуюся цепочку вызовов вместо того, чтобы показывать каждую итерацию взаимодействия с пользователем.
Можно разбить процесс на осмысленные фрагменты. К примеру, на одной диаграмме показать вызовы от клиента вплоть до вашей основной системы, а на другой диаграмме показать то, как ваша основная система взаимодействует с другими и какие есть особенности этих взаимодействий.
В ситуации, когда для достижения цели клиенту последовательно задаётся, скажем, 5 вопросов, данная рекомендация позволит не визуализировать на диаграмме 5 однотипных цепочек передачи сообщений. Плюс практика вынесения общей логики будет способствовать тому, чтобы диаграммы становились более высокоуровневыми, а надписи на них — более общими и универсальными.
Кейс 3. Диаграмма процесса: налево пойдёшь — коня потеряешь
Давайте рассмотрим другой пример. В продуктовой команде существует практика, согласно которой бизнес-аналитик прорабатывает клиентский путь, отрисовывая BPMN-подобную диаграмму. Это выглядит так: пользователю показали экран такой-то, если он нажал одну кнопочку, показываем один экран, если другую — другой. Если оказывается, что клиент не давал согласие на обработку данных — показываем один экран с предложением предоставить согласие, а если согласие было уже дано, то идём к следующему экрану. И так далее.
Но однажды жизнь дала трещину. Число ветвлений логики того, как реагировать на те или иные сведения о клиенте, стало большим и запутанным. В качестве иллюстрации рассмотрим фрагмент реальной схемы, который для большей наглядности был упрощён.
Фрагмент схемы, отвечающий за определение подхода к взаимодействию с клиентом
Какие тут можно увидеть проблемы?
Первая проблема кроется в нестрогом соблюдении нотации BPMN. Дело в том, что каждая ветка, выходящая из шлюза (представленного ромбом на схеме), должна содержать условие, при выполнении которого выбирается данная ветка. Здесь же мы видим, что в единственном шлюзе (зелёный ромб на схеме выше) собраны проверки разной степени важности и очерёдности, а условия на некоторых ветках не являются взаимоисключающими.
Автор подписывал ветки, исходя из того, что если условия где-то уже задействованы, то можно не повторяться, что уже некорректно (так, возраст клиента фигурирует только в 8-м блоке схемы). Это может вызвать разночтения у автора и потребителей данной диаграммы. Плюс такое неоднозначное представление вариативности может непреднамеренно замаскировать проблемы с полнотой учёта возможных вариантов развития событий.
Другая проблема состоит в неоднозначности формулировки условий. К примеру, не является очевидным то, как воспринимать условие вида «Клиент не является налоговым резидентом РФ, имеет второе гражданство или родился в США». Достаточно ли истинности любого из трёх условий или должно выполниться первое и одновременно любое из двух других? И как нам понимать фразу «имеет второе гражданство»: у клиента должно быть 2 любых гражданства или предполагается, что одно гражданство точно российское?
Примеры неоднозначностей (потенциальных источников ошибок)
И, наконец, третья проблема состоит в том, что не очень понятна цель некоторых проверок. Как следствие, возникает сомнение относительно полноты проверяемых условий; возникает ощущение недосказанности. К примеру, зачем мы проверяем, не родился ли клиент в США? Если нас интересуют именно американцы, то почему нигде не проверяется гражданство на США? Если нас интересуют лица, имеющие гражданства иных стран по праву рождения (по праву почвы), то почему не фигурируют Канада, Аргентина и другие страны с подобной законодательной базой? Также вызывает вопрос, почему здесь не делается различий между россиянами, имеющими второе гражданство, и иностранцами с двумя гражданствами?
Когда я стал задавать вопросы и дозированно получать ответы, сначала была предпринята попытка дополнить существующую схему, чтобы устранить на ней недоработки. Однако по мере того, как от бизнеса поступали ответы и разъяснения, схема росла, а условия на ветках становились чрезвычайно сложными. По ходу дела карта экранов стремительно теряла наглядность, осознать нагромождения зафиксированных условий становилось затруднительным, а клиентский путь уже был незаметен на фоне кучи ветвлений алгоритма. И в конечном счёте от этого отказались.
Если на этом моменте взять паузу и поразмышлять, то мы поймём, что в данном кейсе мы столкнулись с ситуацией, сложность которой была обусловлена значительным количеством законодательных требований по идентификации и обслуживанию клиента. И из своего опыта могу сказать, что нормативные требования — как раз наиболее типичный источник, если так можно выразиться, комбинаторной сложности.
Как следствие, в такой ситуации использование BPMN-диаграммы в традиционном для них виде оказывается неудачной идеей. Если же попытаться изменить подход и переписать проверки так, чтобы каждый шлюз отвечал за проверку отдельного параметра (сведения о клиенте), то у нас возникнут сложности другого рода:
Диаграмма окажется излишне перегруженной деталями: есть риск того, что определение подходов к взаимодействию с клиентом (в зависимости от сведений о клиенте) займёт на диаграмме больше места, чем само это взаимодействие.
Любое уточнение нормативных требований будет приводить к необходимости актуализировать диаграмму целиком, хотя основная цель данной диаграммы — это визуализация логики взаимодействия пользователя с разрабатываемым функционалом.
В результате был выбран следующий подход.
Весь блок с вариативностью проверок клиента я вынес на отдельную диаграмму, являющуюся фактически деревом решений. И все уточнения уже прорабатывал там. В процессе проработки я задавал свои вопросы бизнесу и, как я мог наблюдать, бизнес порой брал паузу, т.к. не всегда можно было сразу сформулировать позицию по отношению к тому или иному сочетанию характеристик клиента. Но труд не был напрасным и проблема была побеждена. Как оказалось, в действительности десятки вариантов сочетаний параметров можно было обойти за несколько вопросов и результаты ответов всегда сводились к одному из четырёх исходов, которые уже было легко обработать.
Получившееся дерево решений для определение подхода к взаимодействию с клиентом
После того, как подход с деревом решений показал свою эффективность у меня родилось две идеи.
Идея 1. Если логика проверок сложна и в неё вовлечено достаточно большое число параметров, использование дерева решений — это прекрасный способ поиска белых пятен в бизнес-логике и инструмент дальнейшей формализации алгоритма. Позднее, мы внутри команды договорились, что при появлении такого рода вариативных задач будем снова применять этот инструмент.
Идея 2. Если анализ в форме дерева решений помогает структурировать и формализовать выбор при множественности условий, который делает эксперт предметной области, то этот подход можно масштабировать на уровень метамодели. Здесь я имею в виду, что с помощью данного инструмента аналитик может формализовать правило выбора того или иного средства визуализации (визуальной модели) в своей работе. Некоторое время спустя я реализовал эту идею; для себя я назвал её метадеревом. Но это уже другая история.
Заключение
Давайте кратко зафиксируем основные выводы.
Не все средства визуализации одинаково полезны. Правильному выбору могут помочь ответы на вопросы: «Что именно я рассматриваю?», «На чём конкретно я хочу сфокусироваться?» и «Чья точка зрения мне сейчас важна?». А чтобы выбор был более богатый и осмысленный я рекомендую чтение профессиональной литературы и статей коллег по цеху, так как это позволяет развивать кругозор и насмотренность.
В некоторых ситуациях (например, если проектируемая система имеет сложную структуру взаимодействия) требуется одновременно более одного средства визуализации. Правильное их сочетание позволит проработать задачу со всех сторон и повысит шансы не упустить важные детали как вам, так и потребителям вашей документации.
Аналитику полезно относиться к своей деятельности тоже с позиции аналитика: полезно взять паузу, порефлексировать, порисовать, сформулировать логику выбора средства визуализации или иного инструментария; задуматься на предмет того, почему ты делаешь то, что ты делаешь, есть в этом ценность или это всего лишь инерция мышления. Другой важный вопрос:, а не породил ли ты артефакт настолько объёмный, что его никто не будет смотреть? Убеждён, что такие размышления могут помочь избавиться от ненужной работы и повысить эффективность своей деятельности и деятельности потребителей результатов ваших трудов.