19
Вопросы моделирования
"Хороший инструмент для разработки - это тот инструмент, который не замедляет мою работу". Программист осторожно посмотрел на коробку весом почти 40 кг, в которой находилась новейшая и лучшая среда разработки на С++. "Мне нужен такой инструмент, который даст мне возможность программировать так, как я хочу. После этого на основе кода такой инструмент должен составить эти дурацкие схемы, которые требует от меня начальник". Думаю, что сейчас, наверное, самое время поговорить об этих дурацких схемах.
Многие разработчики - особенно те, которые ломают головы над созданием микрокомпьютеров и рабочих станций, - имеют очень смутное представление о структурных схемах, диаграммах объектных коммуникаций, схемах информационных потоков и блок-схемах. Довольно многие из них никогда не рисовали функциональных иерархий и растерялись бы, обнаружив такие схемы на своем столе. Увидев Booch-грамму, они подумали бы, что это какая-нибудь плохая новость, доставленная на желтой бумаге курьером из компании Booch Telecommunications.
Многим сегодняшним волшебникам в области программного обеспечения эти прямоугольники и овалы, окружности и стрелки кажутся иероглифами, которые оставили исчезнувшие служители культа. Такие значки рассматриваются ими как наследие отживающих свой век методов, таких как структурный анализ и проектирование, которые уступили дорогу ус-
коренной объектно-ориентированной разработке программ на основе создания прототипов. Схемы и диаграммы не находят своего места в быстро меняющемся мире скороспелых микроприложений, разрабатываемых с помощью методов визуального программирования и быстрого создания приложений. "У нас нет времени на рисование картинок. Нас поджимают жесткие сроки выпуска новой версии!" "Зачем вообще рисовать схемы, если можно просто писать код?" Это хороший вопрос. Для чего нужны эти рисунки?
Конечно, структурные схемы и другие классические модели проектирования и анализа были разработаны не для того, чтобы замедлить процесс программирования, так же, как они не были созданы для того, чтобы удовлетворить нужды суетливых потребителей или осчастливить во все вмешивающихся руководителей. Большинство этих методов разработчики придумали для собственных нужд - чтобы упростить и ускорить свою работу. Время, затраченное на обдумывание программ с помощью моделей, - это время, которое экономится при программировании и отладке. Модели проектирования и анализа сокращают время разработки, так как позволяют моделировать программы без необходимости их кодирования и облегчают принятие замысловатых решений для сложных задач. Все это хорошо известно. Хороший план сокращает время разработки; хорошие модели проектирования упрощают планирование.
На практике не все графические модели работают таким образом. Некоторые, например HIPO-схемы и их вспомогательные методы от компании IBM, вполне заслуженно канули в лету. Другие страдают от громоздкости и сложности обозначений или механизмов их рисования. Первоначально CASE-инструменты появились как специальные инструменты рисования, облегчающие создание схем. Со временем они превратились в более комплексные средства, облегчающие разработку программного обеспечения.
Изобразите это
Разработчики программного обеспечения рисуют картинки перед созданием самих программ по тем же причинам, что и архитекторы, рисующие поэтажные планы и вертикальные профили перед тем, как приступить к строительству дома. Тем не менее здания не всегда строились с помощью планов и рисунков. Если схема здания достаточно проста и знакома, строители могут работать без помощи моделей, ведя проектирование в процессе строительства. Сельским общинам на рубеже веков не требовались чертежи, чтобы построить сарай. В те времена сараи имели простую конструкцию, а в их строительстве применялись несложные методы. Каждый знал, как выглядит сарай, как он строится и что для этого требуется. Большинство членов общины уже занималось этим, а новички могли научиться, внимательно наблюдая за тем, что делают другие, и делая то же самое. Но если перейти от хижин и сараев к домам в колониальном стиле с четырьмя спальнями или высотным квартирным комплексам, то все становится сложнее.
То же самое можно сказать и о компьютерных программах. В те времена, когда 64 Кбайт оперативной памяти было пределом, а в качестве операционной среды использовалась СР/М, было вполне возможно и разумно удерживать всю программу в своей голове. Но тот, кто говорит, будто сможет запомнить все детали в сотнях тысяч строк программы на С, говорит неправду - если не вам, то себе. Именно здесь возникает необходимость в моделях проектирования.
Обратите внимание, что мы говорим о моделях, а не о схемах, о проектировании, а не о документировании. Для многих разработчиков эти странные картинки - все равно что китайская грамота. В лучшем случае это еще одна часть документации, которую нужно держать в папочке потому, что это требуется по контракту. Действительно, проектные модели могут быть полезными в качестве документации. Чертежи вашего дома не только нужны для строителей, но и могут помочь определить, где пробить стену, чтобы добраться до трубы с горячей водой (и не задеть ее). Структурные схемы и диаграммы взаимодействия между блоками могут показать, где нужно искать те или иные процедуры, или помочь отследить потоки движения информации, или понять, как организована система в целом. Однако основное назначение моделей проектирования - помогать проектировать.
Управление сложностью
Модель, по крайней мере любая разумная модель, проще того, что она моделирует. С помощью хорошей системы обозначений основные элементы и характеристики очень сложной системы можно отобразить в виде сравнительно небольшой и простой схемы.
Моделирование - это интеллектуальный инструмент. Если вы знаете, что означают символы и применяемый язык, модель может стать способом описания и осмысления сложных задач, особенно с точки зрения взаимосвязей между ее компонентами. В коде или тексте такие взаимосвязи неочевидны; слово или метка здесь могут относиться к тому, что находится совсем в другом месте. В большинстве графических моделей взаимосвязи наглядно представлены в виде линий и стрелок, соединяющих разные части схемы. Хорошие графические модели дают ясное представление о системе, которое невозможно получить при прочтении (или написании) страниц кода.
Конечно, многие люди создают только мысленные модели тех задач, над которыми они работают. Некоторые опытные разработчики могут даже отчетливо представлять системы с помощью структурных схем, которые они держат в своей голове. Однако схемы на бумаге или на экране монитора все же имеют преимущество, поскольку позволяют облечь внутренние мысленные модели в конкретную внешнюю форму. Во внешнем представлении модели становятся устойчивыми, и их можно обдумать или сравнить с другими моделями. Такую модель можно отложить в сторону или рассмотреть позже, на свежую голову. Зачастую, если вы видите что-либо, представленное в виде прямоугольников и линий, это изменяет способ вашего мышления об этом. Появляются другие варианты или возможность понять ошибки или упущения. Кроме того, никто не может увидеть модель, которую вы держите в голове. Но если модель вывешена на стене или имеется в хранилище CASE-инструмента, то вся команда, работающая над проектом, сможет изучать ее и развивать.
Хорошие инструменты моделирования также позволяют делать своего рода эскизы, которые трудно выполнить в коде. Языки программирования точны и детальны, а компиляторы упрямо требуют наличия точного синтаксиса и законченных конструкций. Чистая доска не имеет таких ограничений. Разработчик или вся группа могут подойти к ней и "поиграть" с картинками. Они могут передвигать элементы по схеме, отслеживая сложные взаимосвязи между распределенными областями системы. Словом, модели проектирования позволяют разработчикам программного обеспечения действовать подобно настоящим инженерам, проверяя и сравнивая альтернативные варианты организации программ без необходимости переложения идей в код.
Почти любой аспект программного обеспечения можно моделировать графически: алгоритм, структуру данных, взаимосвязи, композицию, динамику. В каждой из этих и других областей могут применяться десятки конкурирующих систем обозначений и представлений. Однако одна модель не обязательно так же хороша, как и другая. Системы обозначения могут существенно различаться по своим возможностям передачи смысла. Важна форма фигур и то, куда показывают стрелки.
Как же отличить хорошую модель от плохой, а плохую от безобразной? Оставайтесь с нами.
Из журнала Software Development, том 2, № 2, февраль 1994 г.
20
Свет мой, зеркальце
"Свет мой, зеркальце, скажи, да всю правду доложи: я ль на свете всех милее"? Злой королеве из "Белоснежки" достаточно было посмотреть в зеркало, чтобы получить точную картину. Разработчики программного обеспечения тоже должны иметь такую возможность. Им нужны хорошие зеркала, которые просто и точно отражают создаваемое программное обеспечение. Злая королева могла быть недовольна тем, что видела в зеркале; тем не менее ее зеркало давало достоверную и понятную картину.
Именно это предлагает хорошая система моделирующих обозначений - ясное, однозначное и легко понимаемое отображение программного обеспечения. В отличие от зеркала, хорошая система моделирующих обозначений не может дать детальную картину, "один к одному" соответствующую ее коду. Хорошая модель - это точное, но все же избирательное изображение программы, то есть ее намеренно упрощенное описание. Эффективность системы моделирующих обозначений для изображения задач и их программных решений зависит от того, каким образом достигается это упрощение. Сама суть преобразований между средой программирования и средой моделирующих обозначений должна быть простой, непосредственной, логичной и легко запоминаемой.
К сожалению, многие из существующих систем обозначений для программного анализа и проектирования не отвечают этим фундаментальным требованиям. Они чрезмерно сложны, непоследовательны и неясны. Их трудно запомнить и интерпретировать. А еще их слишком много.
Полное моделирование программного обеспечения - это сложный процесс. Он включает в себя рассмотрение множества статических и динами-ческих аспектов: структура и композиция информации, суть алгоритмов и их реализация в виде процедур, разбиение на составные части и взаимосвязи между частями. Если модель данных, процедурная модель, модель коммуникаций, модель состояния и функциональная структура программы слиты в единую схему с одной всеобъемлющей системой обозначений, то результат принимает причудливую форму, становится непонятным и визуально перегруженным.
Получение картины
Модели разработки программного обеспечения во многом служат той же цели, что и зеркало злой королевы. Системы обозначений должны делать ясным различие между прекраснейшими решениями и теми, которые всего-навсего прекрасны. Рассматривая модель, разработчики хотят знать, является ли их замысел здравым или глупым. Модель проектирования программного обеспечения - это не просто место хранения пока еще нереализованных идей. Такая модель позволяет разработчикам найти упущения и ошибки в замысле, а также сравнить разные подходы и выяснить, какой из них лучше. Вот почему хорошие разработчики рисуют картинки перед тем, как приступить к кодированию, - создать "бумажную" модель дешевле, чем создать программное обеспечение. Кроме того, хорошие модели помогают увидеть самый подходящий способ решения задачи.
Хорошая система обозначений предполагает простой, непосредственный и понятный способ преобразований модель-код, то есть позволяет писать код на основе модели или составить модель на основе существующего кода. Небрежная, неясная и неточная система обозначений приводит к небрежному, неясному и неточному преобразованию. Каждый визуальный элемент в системе обозначений должен соответствовать конкретному и существенному аспекту моделируемого программного обеспечения. Каждый важный элемент кода должен иметь возможность быть выраженным в системе обозначений.
Хорошая система обозначений позволяет создавать картины, которые можно интерпретировать аналитически, с помощью тщательного изучения деталей, и понять интуитивно как гештальт, то есть как целое, представляющее общий характер системы. Сложные схемы должны выглядеть сложнее, чем простые. Хорошая архитектура должна быть визуально привлекательнее, чем плохая. Другими словами, хорошая система
.
обозначений позволяет разработчикам использовать оба полушария мозга; она помогает думать о проектируемой системе как с позиций логики, так и на основе интуиции.
Для точного и достаточно простого отображения программ хорошая система обозначений выделяет важные элементы и скрывает несущественные. Главные части и основные компоненты выделяются крупно, в то время как менее значимые детали становятся примечаниями или комментариями или совсем не обозначаются на схеме.
Картина сохраняет простоту, так как не отображает внутренних деталей. Компонент программы, который по сути является "черным ящиком", становится простым прямоугольником, нарисованным на экране или бумаге без отображения внутренних деталей. Здесь речь идет о целых программных блоках, а не об их внутреннем содержимом.
В идеале мы хотели бы получить такой инструмент контроля отображения, который достижим только с помощью компьютерных средств. Например, мы хотели бы просматривать схему коммуникаций между объектами, пробегая глазами мелкие элементы, а затем увеличивать масштаб, чтобы изучить взаимосвязи в какой-то одной части схемы. Мы могли бы увеличить какой-нибудь объект, чтобы узнать, какие методы он поддерживает. Делаем двойной щелчок мышью и видим код С++, определяющий данный метод. Или же мы могли бы переключиться в режим, в котором сценарий взаимодействия с пользователем совмещен со схемой коммуникаций между объектами, причем объекты, участвующие в данном сценарии, выделены или подсвечены.
Система обозначений и юзабилити
Систему обозначений можно легко разработать самому; очень многие так и поступают. Однако хорошую систему обозначений придумать трудно. Многие системы, которые встречаются в наших журналах, не в полной мере подходят для моделирования.
Разработка хорошей системы обозначений подобна разработке хорошего графического интерфейса. Целью здесь является сокращение нагрузки на человеческую память. Великий закон юзабилити утверждает, что система должна быть доступной для использования человеком, который знает о ее назначении, но не знаком с ее программным обеспечением. При этом не должно возникать необходимости в обучении, помощи или руководствах (Constantine, 1991 [14]). Таким образом, по-настоящему хорошая система обозначений - это такая система, которую опытный разработчик, знающий, как проектировать и писать программы, сможет интуитивно понять без шпаргалок и недельных курсов обучения. Вы не должны запоминать разные условные обозначения (например, то, что прямоугольник с двойной рамкой означает динамический объект, а прямоугольник с флажком в углу - компонент библиотеки).
Все должно выглядеть так, как оно есть. Формы символов или стили линий не могут быть какими угодно. Они не должны противоречить интуиции. Например, базовую основу, на которой с помощью наследования и повторного использования выстраиваются другие компоненты, необходимо изображать с помощью сплошных, строго очерченных элементов, а не эфемерными облаками.
Сильные связи между частями должны выглядеть, как сильные связи; слабые связи должны выглядеть, как более слабые. Устойчивые объекты должны быть показаны сплошными фигурами, а динамические объекты должны выражать смысл активности или изменяемости. Например, наследование одним классом свойств и характеристик другого класса означает, что подкласс в большой степени зависит от родительского класса - подобно тому как генетические особенности ребенка сильно зависят от особенностей обоих родителей. Для точного отражения характеристик программного обеспечения, использующего наследование, этот механизм должен быть показан более четко, чем передача сообщения объекту или ссылка на него как на атрибут (Page-Jones, Constantine и Weiss, 1990 [57]).
Сделать систему обозначений интуитивно понятной и простой в изучении помогут небольшие детали. В системе обозначений для объектно-ориентированных программ, разработанной Джекобсоном (Jacobson и др., 1992 [44]), те объекты, которые взаимодействуют с внешним окружением, на одной стороне имеют символ (- в качестве визуального ключа, обозначающего это взаимодействие. Динамические объекты, которые управляют последовательностью действий, снабжены стрелкой, входящей в границу, что означает цикл или итерацию. В нескольких системах обозначений внутренние элементы компонентов, которые доступны извне, показаны в виде расширений границы компонента.
Кроме того, хорошая система обозначений основана на том, что разработчики уже знают. Главным образом в ней применяются обозначения, знакомые разработчикам. Другими словами, не следует использовать новые символы для давно известных понятий, а старые обозначения - для новых и несовместимых идей. На самом деле чаще всего нам и не нужны новые обозначения. Наши усилия следует направить в основном на стандартизацию и упорядочивание того, что уже имеется, с применением разумных принципов моделирования и человеческого мышления.
Подумайте об этом.
Из журнала Software Development, том 2, № 3, март 1994 г.