Глава 1. Зачем мне математика? Главная проблема современного программирования

Опять скажу: никто не обнимет необъятного!

Козьма Прутков, афоризм 160.

Появление языка моделирования Unified Modeling Language (UML) в конце 1990-х гг. – одно из наиболее важных событий в эволюции методов разработки программного обеспечения (ПО). Именно в это время создание программных систем переходит в новое качество, перерастает из алгоритмики, «программирования в малом» в инженерию разработки ПО - «программирование в большом».

Глубина этих перемен столь велика, что даже изначально фундаментальное, предопределившее само возникновение компьютерного программирования понятие абстрактной и формальной (т.е. математической) модели приобретает качественно новый смысл. Программирование – по-прежнему, род математического моделирования. Но теперь моделирование понимается уже не только как «схематическое описание», но и «средство минимизации (снижения) будущих рисков». В главном, это и отличает современную разработку ПО от прежнего программирования.

Для осознания преемственности и различий - вспомним. Формирование в течение всего 19 века трудом многих поколений математиков понятия математической модели было реакцией на проблемы, связанные с появлением т.н. нестандартных теорий. Первым и важнейшим примером такой теории была нестандартная геометрия Н.И. Лобачевского. В то время они воспринимались как внутренние проблемы построения надежных оснований самой математики. Этот важнейший для дальнейшего возникновения компьютерного программирования этап завершился в начале 20 века

· формальным определением понятия алгоритм в качестве абсолютно надежного математического метода (тезис Черча-Тьюринга) и

· признанием невозможности решать все проблемы математики лишь такими методами (результаты о неразрешимости, теорема Геделя о неполноте).

Спустя век, мы снова говорим о проблемах надежности моделирования, но теперь уже – с точки зрения их внешних последствий. Для понимания того, о каких именно рисках теперь идет речь, вспомним ставший уже классикой пример о разнице в подходах к построению собачьей конуры и небоскреба от авторов UML [Booch,Jacobson,Rumbaugh]. Первое возможно лишь при понимании на уровне некой общей идеи, интуиции – второе требует фиксации технологии, самого серьезного отношения к организации работ. Мыслить устройство конуры мы можем сколь угодно изощренным – суть не в этом. Цена неудачи при строительстве жилого дома выше. Намек прозрачен. Строя абстрактные схемы – нужно заранее думать о тех людях, на головы которых могут обрушиться построенные нами дома и созданные нами программные системы.

Какие бы мощные (а потому более сложные в освоении) средства и инструменты мы при этом не использовали сами для выполнения этой тяжелой работы, главной целью остается долгосрочное облегчение жизни всех людей. Однако, как учит история - вопреки начальным ожиданиям, цель эта постоянно оказывается крайне труднодостижимой. Потому – спеши медленно. Подход UML подкрепляет эту древнюю мудрость крайне полезными на практике рекомендациями.

Следуя этому принципу сам, автор решил отказаться от описания конкретной программной среды поддержки UML. Роза пахнет розой – хоть розой назови ее, хоть нет [1]. Во-первых - потому, что для рассматриваемых здесь игрушечных задач подойдет любая среда программирования, с которой читатель вполне может освоиться самостоятельно. Во-вторых - потому, что перед использованием программной среды нужно тщательно разобраться в том, что нового можно от нее ожидать – и что ждать бесполезно.

В знак уважения к пионерам (впереди идущим), достаточно сказать, что первой UML-средой стала Rational Rose компании Rational (впоследствии – IBM Rational), за которой последовал целый ряд все более мощных и специализированных инструментов под общим названием Rational знаменитой компании IBM. Ну и конечно – качественные программные продукты других, не менее знаменитых компаний и менее известных разработчиков, в том числе и свободно распространяемые.[2]

Как и в случае появления принципиально новых языковых средств программирования до него, создание UML обозначило некий новый комплексный подход к решению проблемы масштабирования, т.е. UML стал

· реакцией на качественно возросшую сложность (кризис разработки больших программных систем 1970+ гг.) в виде

· формализации - фиксации в языке уже хорошо оправдавших себя на практике способов распределения сложности труда разработчиков ПО,

· отражающих по мере возрастания сложности все более высокие уровни абстрагирования.

Проще говоря, методы программирования с возрастанием сложности разработки ПО математизируются. И это не столько новая, своеобразная математика. Просто серьезные разработчики – довольно своеобразные математики. С этим своеобразием нам и предстоит познакомиться.

Но все же UML – язык моделирования, а не язык программирования. Его цели более опосредованы, общи и многофункциональны. Объединив результаты предыдущих и своих собственных усилий, авторы UML Гради Буч, Джеймс Рамбо и Ивар Якобсон стремились в достаточно компактной форме вобрать и развить лучшее из богатого опыта формального моделирования. Как пишут сами авторы в [Booch,Jacobson,Rumbaugh],

UML - это язык.

[В частности,]

Это язык для

· визуализации,

· специфицирования,

· конструирования и

· документирования

артефактов программных систем.

Здесь:

Артефакт (от латинского artefactum) — искусственно созданное, сделанное, любой результат труда людей. Термин дает нам недвусмысленный намек на то, что программный код – целевой, но далеко не единственный результат разработки.

А также – намек на специфику профессии. По всей видимости, термин пришел в IT из археологии. Археолог изучает исторические пласты - следы, оставленные предыдущими эпохами. Он видит в статике динамику, в последовательности следов (трасса, trace) – «застывшее» время. Программист – то же.

Визуализация – наглядное представление, ориентированное на максимально широкий круг людей, в большей или меньшей степени отвечающих за процесс разработки (аналитик, архитектор, разработчик, тестер,… заказчик, пользователь). В данном случае – диаграммы UML.

Специфицирование – уточнение начала разработки – согласование постановки задачи в более строго формализованной (по возможности и необходимости) форме. См. далее анализ.

Конструирование – подготовка продолжения разработки – схем решения «верхнего уровня» (логики решения). Включая возможность частичной автоматизации (например - генерации программного кода по UML диаграммам). См. далее проектирование.

И все же один менее очевидный для «технически мыслящих» специалистов, но крайне важный для понимания момент в использовании UML я хотел бы подчеркнуть особо - его социальную функцию. Любой язык предназначен для общения. UML – не регламент работ и не свод жестких правил, предписывающий людям те или иные роли, те или иные алгоритмы поведения. В первую очередь, это язык для рабочего общения между людьми в процессе разработки ПО – весьма полезный, хотя и не строго обязательный.

Принципиально новым на современном этапе развития IT становится постепенный перенос внимания с множества ситуаций типа «человек-компьютер» (разработчик-компьютер, пользователь-компьютер и т.п.) на поддержку организации деятельности больших коллективов. По сути своей, UML и есть результат первой серьезной попытки создать цельную картину – мозаику из множества таких кусочков. Зачем?

Создание больших программных систем требует больших коллективов (команд) и специализации - разделения труда, «распределения ролей» - обязанностей, связанных с решением тех или иных задач, выполнением тех или иных функций. В конечном счете, это – распределение ответственности. Что порождает проблемы взаимопонимания – как внутри самой команды, так и в ее общении с окружением. Ответы на эти старые проблемы нужно искать в более современных подходах к организации взаимодействия людей, в существенной степени опирающихся на самоорганизацию. Они-то и лежат «за схемами» UML.

Словом – предмет разговора настолько серьезен, что трудно обойтись без шутки. Никто не идеален – в том числе сам UML. Но есть предельно простой способ проверки эффективности применения подхода UML - до знания деталей самого UML! Если данный подход не помогает поддержанию нормальной температуры (36.6°) в команде (не придает дополнительных стимулов участников к плодотворной совместной работе, а лишь вызывает горячие конфликты и охлаждение отношений) – то, скорее всего, он понимается и используется неверно. Во всяком случае, тогда UML «не работает».

Рекомендация. Тщательно выбирай аксиомы совместного существования. Не противопоставляй изначально «они и мы», особенно - «мы и эти». Говори сначала – «мы все [решим проблему лишь сообща]». Эту тему мы – по умолчанию - и выберем в качестве «сквозной нити» нашего рассказа о UML.

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

Пособие не содержит полного описания UML и практического руководства по его использованию – но лишь общее виденье основных проблем и принципов разработки, дающих начальную мотивацию к более глубокому изучению предмета. Ссылки на полезные для этой цели ресурсы читатель найдет в тексте самого пособия и списке литературы.

Лучше сделать меньше, да лучше – так надежнее. Нельзя объять необъятное - нельзя на заведомо небольших примерах быстро научиться качественно разрабатывать большие долгосрочные проекты. Больше того - заранее предопределить для другого решения проблем до возникновения этих проблем в его собственной практике не просто невозможно. Такие «благие намерения» чаще оборачиваются «медвежьей услугой» - не упрощая, но запутывая суть дела. Особенно в разработке ПО, где смена концепций сегодня еще часто путается со сменой обозначений.

Автор – без претензий на большой практический опыт и доскональное знание области - видит свою задачу скромней. Он хотел бы показать читателю, что некоторые мелкие неудобства (дискомфорт), которые мы встречаем в своей индивидуальной работе уже сегодня - не придавая им особого значения - рискуют обернуться крупными неприятностями. Завтра. Но чтобы завтра было не хуже, чем сегодня - стоит заметить их уже сейчас. Словом, выбор прост и однозначен, хотя и далеко не легок в реализации. Строить сегодня конуру нужно вдумчиво, терпеливо и тщательно, как если бы мы строили небоскреб. Не наоборот. Даже (особенно!) когда речь идет о программных системах – небоскребах как бы не настоящих, а «виртуальных», т.е. находящихся в нашей голове.

Главная проблема современного программирования – проблема надежности ПО. Общие и профессиональные подходы к ее решению реализуются теми или иными специальными методами программирования – локальными, частными, в том числе формальными и отчасти автоматизируемыми (инструментарием). Впрочем, и самые специальные методы имеют в своей основе вполне общечеловеческое происхождение и цену.

Надежное (reliable) ПО – это ПО, создаваемое надежными людьми. Надежен (reliable) тот, на кого можно положиться, кто оправдывает возложенные на него надежды. И надежный не может все знать и уметь. Но он точно знает, что «серебряной пули» – универсального способа быстрого и окончательного решения всех проблем – не существует. Узкий специалист знает частные профессиональные решения, но берется за все – в надежде на то, что инструменты сделают за него главное. Надежный профессионал знает и общие проблемы. Он благодарен другим людям за инструменты – но берется делать лишь то, за что впоследствии сможет ответить сам. Именно поэтому надежные тебя не подведут. На них можно положиться, на них можно надеется.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: