понедельник, февраля 12, 2007

Feedburner

С недавних пор я перевёл все RSS фиды на FeedBurner. Поэтому просьба к тем, кто подписан не через feedburner - переподпишитесь пожалуйста. Так что вот:

P.S. Если подписаться на фид комментариев, то можно отслеживать комментарии к старым постам блога

пятница, февраля 09, 2007

Quick and Dirty?

Есть такой специальный вид исправления ошибок, название которого (если исключить вопросительный знак) вынесено в заголовок. "Quick and dirty fix" - это такое исправление или решение, которое исправляет проблему в каком-то частном, узком конкретном случае, а не решает её целиком. Примеров подобных решений каждый программист может найти в своей практике множество. Предполагается, что такое вот временное решение будет существовать недолго, а как только появится возможность будет заменено на "правильное". Последнее иногда случается, а иногда нет - как повезёт.

Вот только "quick and dirty" бывают не только исправления проблем в условиях сжатых сроков. Иногда "quick and dirty" бывают сами решения. Ну просто нужно что-то сделать, а времени остаётся мало, и вещи делаются как попало, так, как тому кто их делает кажется в данный момент быстрее. И вот такие-то вещи как раз почти всегда остаются в коде навсегда.

Два подхода

Вообще, есть два подхода к написанию программ.

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

Другой же подход всегда прибавляет к имеющимся условиям первого подхода ещё одно: что программа должна быть при этом написана "правильно". Под "правильностью" адепты второго подхода понимают обычно разные вещи, в большинстве своём плохо формализованные. Тем не менее, как и во многие других вопросах программирования здесь также хорошо помогает "программистская" интуиция. "Правильными" программами, я например, считаю программы, обладающие примерно таким набором признаков:

  • Код программы написан в "понятном" стиле
    "Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям."М.Фаулер

  • Программа содержит в себе только необходимые элементы, ничего лишнего, "устаревшего", не использующегося и так далее

  • Код в программе подчиняется принципу DRY (DO NOT REPEAT YOURSELF), то есть каждая часть функциональности существует в единственном экземпляре, нет раскопированных кусков кода, которые делают одно и тоже

  • Все материалы, относящееся к данной версии программы, находится в системе контроля версий:
    • исходный код
    • картинки
    • документация - как пользовательская, так и техническая, включая документы по архитектуре и так далее
    • и так далее

  • Связи между независимыми компонентами программы минимизированы

  • Любую версию программы (в том числе и предыдущие) можно построить при помощи запуска одного скрипта
Этот список конечно же не полон, и другие, гораздо более знаменитые люди уже давно составили подобные списки. К тому же, как я уже говорил, на самом деле эти списки ни к чему - программист интуитивно понимает "правильно" ли написана программа, на которую он смотрит или нет (это конечно исключая ситуации, когда хочется поспорить и попридираться - разумный человек может придираться к чему угодно, при желании).

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

Поэтому срежем углы. Сделаем сейчас так. Соберём версию как получится, без автоматизированных процедур которые нужно неделю отлаживать. Напишем одну функцию на 25 экранов, пусть она заработает, а уж потом будем выделять логические компоненты. И так далее. Ведь если мы не сделаем продукт к сроку, то все остальное уже неважно.

Эта аргументация вполне понятна. Но, как и любая аргументация, она имеет границы применимости. Дело в том, что аргументация смотрит вперёд на один ближайший выпуск продукта. И с точки зрения этого ближайшего выпуска, она оптимизирует время так, чтобы ближайший выпуск состоялся вовремя.

А что если посмотреть вперёд? Будут ведь и ещё выпуски? Сколько их будет? Рассмотрим пример. Допустим, что для создания работающей автоматизированной процедуры построения продукта требуется 1 неделя (5 рабочих дней). После этого для сборки продукта будет требоваться 2 часа - время работы процедуры. Допустим также, что для того, чтобы собрать продукт руками опытному разработчику, знакомому с процедурой сборки требуется 1 день. Ясно, что в критериях измерения только "к ближайшему выпуску" предпочтение следует отдавать "ручному варианту". А что если впереди планируется ещё 10 выпусков? Давайте считать. Отлаженная процедура займёт 20 часов ( то есть три дня). "Ручная" же сборка займёт 10 дней. Заметим, при этом, что сборка обычно не происходит один раз - обязательно обнаруживается та или иная ошибка, продукт пересобирается и так далее. В "ручном" режиме это каждый раз трата одного дня.

Кроме того "процедура" автоматической сборки, будучи один раз отлаженной имеет гораздо больше шансов сработать и в последующие запуски, чем процедура "ручной" сборки. Также "ручная" сборка страдает тем, что её успешность привязана к конкретному человеку, который может в нужный момент отсутствовать, может заболеть или даже уволиться. И в этой ситуации придется заново "изобретать" процедуру ручной сборки.

Все зависит от критериев

На самом деле подход один. Понятно что всем хочется написать программу "получше". Просто вопрос в критериях качества. Считаем ли мы возможность удобной поддержки программы в будущем подобным критерием или нет? Думаем ли мы о том, что потом наш код увидят и должны будут в нем разобраться другие программисты (или мы сами через год - что почти тоже самое :-) ) ? Если мы пишем однодневку - то один подход, если мы смотрим в будущее, то другой. "Я так думаю"(с) Мимино.

P.S. Если мы в будущее смотрим, но времени у нас на "правильное" программирование не хватает - то это называется неправильным планированием. Тот, кто был ответственен за планирование не до конца все просчитал и не заложил больше времени.

P.P.S. (вольный перевод отсюда, имеет смысл только для программистов): Мы тратим большую часть жизни на разработку программ - стоит ли заниматься этим спустя рукава?

четверг, февраля 01, 2007

Intentional Software

Все ведь знают имя Charles Simonyi? Билл Гейтс называет его "одним из величайших программистов всех времён". В его честь венгерская нотация получила название венгерской (поскольку сам Simonyi родом из Будапешта, Венгрия и это именно он привнёс тот способ именования переменных в программе, который теперь известен как венгерская нотация). Он работал во всемирно известном исследовательском центре Xerox в Palo Alto (Xerox PARC). В то время (Simonyi пришёл в PARC в 1972 году) был разработан легендарный, опередивший свое время персональный компьютер Alto, обладавший поразительными возможностями: графическим пользовательским интерфейсом, сетевым интерефейсом (Ethernet), мышью:
А также, специально для Alto, под руководством Simonyi, был разработан совершенно невиданный для того времени текстовый процессор под названием Bravo. Bravo предложил совершенно новую концепцию текстового редактора - концепцию, при которой пользователь видел на экране компьютера ровно то, что оказывалось распечатанным на принтере. Эта концепция получила название Wysiwyg - "What you see is what you get!". По сути, он изменил индустрию программного обеспечения для пользователя, введя уровень абстракции между ними и текстовым редактором.

После работы в Xerox PARC Simonyi работал в Microsoft и занимался Microsoft Office. В настоящее время он основал собственную компанию и снова хочет изменить мир.

Новая компания называется Intentional Software. Компания была организована в 2002 году, с целью разработать совершенно новые методы программирования, которые позволяли бы программистам не тратить свое время на рутинное, и подверженное ошибкам написание кода, а на то, чтобы определять цели, которых должно добиваться программное обеспечение, а уж специальный генератор будет по сформулированным целям генерировать исходный код программы на каком-либо из традиционных языков программирования.

Именно ради построения таких методов Simonyi ушёл из Microsoft и основал на собственные деньги компанию. Работа на самом деле началась чуть раньше, когда он ещё работал в Microsoft Research, но условия ухода из MS запрещали использование уже написанного кода а разрешали только использовать идеи, поэтому весь код пришлось переписывать заново.

Идея Simonyi состоит в том, чтобы полностью изменить мир программирования. По его представлению, в будущем программы будут писать не программисты, а эксперты в конкретной предметной области, причём пользуясь терминологией и конструкциями, принятыми не в в программировании, а в данной предметной области. Сама программ будет записываться как некоторое "дерево намерений" (intentional tree), которое в свою очередь будет транслироваться в код, например на С++. При желании изменить программу, необходимо будет изменить дерево намерений, и пересоздать код на C++.

Вообще, если честно все это жутко похоже на популярную сейчас концепцию DSL - domain specific languages, с той разницей что Simonyi утверждает что его intentional programming будет существенно шире, что бы это не значило. Сейчас компания, насколько я понимаю, не имеет ни готового продукта, ни каких-либо клиентов, а живёт только за счёт миллионов её создателя (заработанных, естественно в Microsoft).

Тем не менее по поводу всего этого была поднята довольно большая шумиха поскольку
в недавнем выпуск Technology Review была опубликована большая статья, откуда я собственно и узнал про существование Intentional Software.

Идея выглядит привлекательной, но уж больно сомнительной, с точки зрения практического её выполнения:

  • Что ни говори, а эта штука - кодогенератор, соотв. возникают стандартные для этого типа программного обеспечения вопросы:
    • как сопровождать этот код?
    • Что делать, если сгенерированый код слишком медленный или содержит ошибки?
    • Насколько абстрактным будет продукт: действительно ли эксперты предметной области смогут написать программу?
  • Что делать с пользовательским интерфейсом? Можно себе представить эксперта, разрабатывающего бизнес-процессы и структуры данных, но ведь необходим пользовательский интерфейс. Как его предполагается формулировать в рамках "намерений"?
  • Не будет ли язык формулирования "намерений" ещё более сложным чем то, с чем intentional software пытается бороться - чем традиционные языки программирования?
  • Ну и наконец: непонятно, нужен ли на самом деле ещё один уровень абстракции?
Создатель языка С++, Бьярн Страуструп, в одном из своих последних интервью сказал:

"Software developers have neutralized the astounding performance of modern computer hardware by adding layer upon layer of overelaborate [software] abstractions."

Может быть он прав?