Специфика разработки программного обеспечения
Ф. Брукс более 30-ти лет назад написал : «Программист, подобно поэту, работает почти непосредственно с чистой мыслью. Он строит свои замки в воздухе и из воздуха, творя силой воображения. Трудно найти другой материал, используемый в творчестве, который столь же гибок, прост для шлифовки или переработки и доступен для воплощения грандиозных замыслов». Некоторые психологи, которые работают с программистами, идут дальше и даже утверждают, что программирование — это высшая форма творчества .
Творчество в программировании начинается с определения целей программы и заканчивается только тогда, когда в ее коде, написанном на каком-либо языке программирования, поставлена последняя точка с запятой. Попытки разделять программистов на творческую элиту, архитекторов и проектировщиков, и нетворческих программистов-кодеров не имеют под собой объективных оснований. Даже если алгоритм программы строго определен математически, два разных программиста его закодируют по-разному, и полученная программа будет иметь разные потребительские качества.
Программирование было, есть и останется в обозримом будущем творческой деятельностью. Хочу отметить, что это утверждение вызывает, как правило, наибольшие дискуссии. Порой меня упрекают в том, что я «выделяю программирование, как вид супер-творческой деятельности, что негативно отражается не только на эффективности команд, фирм, компаний, но и на всей отрасли ИТ в целом и смежных отраслях». В защиту своей позиции могу сказать, что творчеству есть место и в приготовлении домашнего обеда. Все зависит от задачи, которую мы решаем. Творчество — это получение нового результата. Какова доля новых результатов и творчества в проектах разработки ПО? У меня таких данных нет. Есть личное ощущение, что очень большая. Косвенно об этом свидетельствуют высокая неопределенность при разработке программных систем, разброс производительности программистов на порядок и доля провальных программных проектов более 80%. А это уже объективные данные.
Существующее состояние Software Engineering напоминает мне большую поваренную книгу с многочисленными описаниями рецептов однажды успешно приготовленных блюд из ингредиентов, которых у меня никогда в будущем не будет. Завтра в моей новой системе будут другие вычислительные машины, технологии, языки программирования, инструменты и базовое ПО, новые проблемы взаимодействия с которыми мне обязательно придется решать.
Творчество — это интеллектуальная деятельность человека, законы которой нам не известны. Если бы мы знали законы творчества, то и картины, и стихи, и музыку, и программы уже давно бы создавали компьютеры. Творческое начало это то, что роднит программирование с искусством и наукой.
Программирование это не искусство, в том смысле, что оно не является «творческим отражением и воспроизведением действительности в художественных образах». Об искусстве в программировании можно и должно говорить только в смысле умения, мастерства, знания дела, как и в любой другой профессии. И как в любой другой профессии программистское мастерство может доставлять истинное эстетическое наслаждение, но только для людей, причастных к этой профессии.
Программирование это не наука. В программировании нет системы знаний о закономерностях создания программ. Наработки математиков в области логики, теории информации, численных методов, реляционной алгебры, теории графов и некоторых других дисциплинах на долю процента не покрывают многообразие программистских задач. Даже выдающиеся программисты не возьмут на себя смелость утверждать об архитектуре новой программной системы то, что она будет успешной. Хотя в программировании уже накоплен определенный опыт провалов, который может позволить искушенному программисту увидеть в архитектуре новой системы антипаттерны — источники серьезных будущих проблем. Но не более того.
Программирование — не искусство и не наука, это ремесло — «рукодельное мастерство, ручной труд, работа и уменье, коим добывают хлеб», © «Толковый словарь живого великорусского языка В.
Даля». Сегодня мы так же далеки от индустриальной разработки программ, как и 50 лет назад. Представляется, что до выхода из «детского» периода программированию еще очень далеко. Пока, на мой взгляд, сложность и масштаб программистских задач растет быстрее, чем взрослеет программное производство. А поскольку это ремесло, то человек, научившийся писать программы на C ++, будет также далек от профессионала, как ученик третьего класса средней школы, научившийся писать по-русски, от А. С. Пушкина или Ф. М. Достоевского. Путь к мастерству в ремесле лежит только через опыт. Нельзя научиться программированию, читая книги. Как нельзя по книгам научиться писать романы, картины, стихи, музыку. А еще программистам нужен постоянный труд самоусовершенствования и саморазвития. Поэтому далеко не все, кто пишет программы, становятся профессионалами. Производительность труда программистов с одинаковым уровнем знаний и опытом в обозримом будущем, по-прежнему, будет отличаться на порядок даже при решении сходных по сложности задач. Хотите, меряйте производительность в строках исходного кода, хотите — в функциональных точках. Творчество неразрывно связано с вдохновением, а это субстанция капризная и непредсказуемая. Помните знаменитый сон Д. И. Менделеева, про периодическую таблицу элементов его имени? Без вдохновения в программировании не обойтись. И, чем сложнее задача, тем труднее извлечь это вдохновение из подсознания. Иногда для этого требуются часы, а иногда недели.
Профессиональное творчество программиста принципиально отличается от творчества в науке и искусстве. Программистские задачи с каждым годом становятся все сложнее и объемнее, а сроки, за которые требуется решить эти задачи, наоборот, с каждым годом сокращаются. Поэтому современные программные системы создаются коллективами от нескольких до тысяч программистов, в то время как творческие деятели науки и искусства работают, в большинстве своем, в одиночку. Проблемы коллективного творчества, практически, остались без внимания у психологов и социологов.
Правда, существует еще прикладные науки, гражданское строительство, космическое машиностроение, авиастроение, автомобилестроение и другие высокотехнологичные отрасли промышленности, в которых над созданием новых изделий трудятся сотни тысяч человек. Очень велик соблазн провести аналогию с этими отраслями и говорить об индустриализации подхода к разработке ПО. Не получается.
Упрощенно, путь от идеи до ее реализации в этих отраслях выглядит следующим образом: научно-исследовательская работа (НИР), опытно-конструкторская работа (ОКР), производство. В верхней части этой пирамиды находятся отраслевые НИИ, которые производят идеи и занимаются проектированием новых изделий. На втором этаже пирамиды работают конструкторы в конструкторских бюро, в задачу которых входит реализация нового проекта в чертежах деталей и технологиях изготовления и сборки. На нижнем уровне находятся производственные мощности — заводы, на которых инженеры и рабочие воплощают «в железе» чертежи и технологии.
Если проводить аналогию, то программисты работают исключительно на вершине описанной пирамиды. Программирование — это идеи и проектирование. Роль конструкторского бюро для программного проекта выполняют компилятор и сборщик программ. А программистским аналогом завода, который переводит конструкторскую документацию в продукт, доступный потребителю, служит вычислительный комплекс, на котором развертывается и выполняется созданная программа.
А теперь давайте вспомним, сколько НИР так и остались на бумаге, не дойдя до ОКР, а сколько еще ОКР закончилось закрытием тематики. Я думаю, что процент инноваций, дошедших до производства, от общего числа исследовательских проектов, выполненных в отраслевых НИИ, будет сравним с процентом успешных программных проектов. И давайте еще учтем, что ученые в НИИ опираются на достаточно хорошо изученные законы математики, физики и химии, а программирование, как мы отмечали выше, пока остается лишь ремесленным производством.
Для коллективного программистского творчества скорее уместна аналогия с созданием художественного фильма, театрального спектакля или исполнения музыкального произведения оркестром.
Я полагаю, что количество провальных проектов в этих областях ничуть не меньше, чем в программировании. Дай Бог, если хотя бы пятая часть завершенных фильмов не «ложится на полку» после первого показа. И еще одна аналогия программных проектов с кинематографом. Наличие даже самых звездных актеров не обеспечивает успех фильма. Только талантливый режиссер способен организовать и вдохновить актеров на создание шедевра, открыть новые звезды. А талантливых режиссеров, как, впрочем, и талантливых менеджеров программных проектов, к сожалению, не так много, как хотелось бы.
Поэтому, в обозримом будущем большая часть проектов разработки ПО будет завершаться со срывами сроков и перерасходом бюджета, а часть проектов не будет завершена никогда. Бизнес должен помнить, что инвестиции в разработку ПО по-прежнему будут связаны с высокими рисками. Но эти риски компенсируются тем, что прибыли от одного успешного программного проекта могут порой покрыть убытки от десятков менее удачных.
Есть еще нечто, что отличает труд профессионального программиста от ученого, художника, композитора и поэта. Предметом деятельности ученых являются упрощенные модели, в которых они могут абстрагироваться от большинства деталей реального мира, не существенных для их целей. Математик, доказывая новую теорему о тензорах, не заботится ни о чем, кроме системы постулатов, положенных в основание дифференциальной геометрии. Физик, описывая динамику жидкости в трубе, абстрагируется от того, как движутся и сталкиваются молекулы и от того, как движутся планеты вокруг Солнца. Деятели искусства тоже во многом оперируют абстракциями. Поэту, композитору, художнику достаточно лишь сделать намек, абрис объекта творчества, и на этом его работа закончена. Остальное пусть додумывает читатель, слушатель, зритель.
Программист тоже работает с абстракциями, но ему приходится держать в голове гораздо больше абстракций, чем любому ученому. Абстракции сопутствуют программисту на всех уровнях разработки программы от описания ее целей до исполняемого машинного кода.
И этих уровней могут быть десятки. И на каждом уровне абстракций их деталей становится все больше и больше. «Я бы сказал, что отнесение программирования к "инженерным" дисциплинам сослужило ему плохую службу, создав иллюзию "вещности" и "объективности" результатов труда программистов. Тогда как по роду своему программы ближе всего к словам языка (к "Именам"), чем к традиционным объектам материального мира. И к конструкциям над этими словами — песням, сказкам, метафорам. И эта отнесенность касается всех уровней программирования: от системных библиотек до больших прикладных комплексов» .
Дополнительно к абстрактному мышлению, программист должен обладать сильно выраженным системным мышлением, чтобы удерживать многочисленные взаимосвязи, существующие на всех уровнях программистских абстракций, а также взаимосвязи между этими уровнями. Еще одной сложностью является то, что все эти абстракции и взаимосвязи между ними изменяются во времени, и программист обязан учитывать эту динамику.
Кроме того, программист должен обладать маниакальной усидчивостью, сосредоточенностью и упорством для перебора всех возможных вариантов поведения своих абстракций и доскональной проработки всех деталей. Проработка должна быть абсолютно точной и не содержать ни одной ошибки, неправильного, лишнего или отсутствующего символа исходного кода (а это сотни тысяч строк, а порой и миллионы). Инструменты программирования: синтаксические анализаторы, компиляторы и проч., — могут лишь незначительно облегчить эту работу.
Еще одна особенность, которая присуща программистскому творчеству, это постоянное обновление информационных технологий, которые программисту необходимо знать и успешно применять в своей работе. Поэтому профессиональный программист должен, как сказал один из наших прежних вождей, «учиться, учиться и учиться». Программист должен удерживать в голове, постоянно пополнять и активно применять на практике гигабайты профессиональной информации.
Это устройство компьютеров, компьютерных сетей и сетевые протоколы. Это операционные системы и языки программирования. Это программные интерфейсы промежуточного ПО и прикладных библиотек с особенностями и багами их реализации в конкретных версиях продукта. Это технологические стандарты, технологии разработки и инструменты, которые их поддерживают. Это архитектуры программных систем, паттерны и антипаттерны проектирования и много-много другой информации.
Еще в начале 70-х замечательный советский ученый академик А.П.Ершов сказал: «Программист должен обладать способностью первоклассного математика к абстракции и логическому мышлению в сочетании с эдисоновским талантом сооружать все, что угодно, из нуля и единиц. Он должен сочетать аккуратность бухгалтера с проницательностью разведчика, фантазию автора детективных романов с трезвой практичностью экономиста». Можно утверждать, что профессиональный программист обязан сочетать в себе легкость и полет таланта Моцарта с усидчивостью и скрупулезностью Сальери.