Лорд Палмерстон в программировании
From The Joel on Software Translation Project
В английском оригинале статья называется Lord Palmerston on Programming
Были времена, когда если вы прочли одну книгу Питера Нортона, вы знали все, что можно было знать о программировании IBM-PC. За последние 20 лет программисты во всем мире много проработали, выстраивая обобщение над обобщением на IBM-PC, чтобы сделать программирование легким и более мощным.
Но Закон Дырявых Абстракций гласит что, даже если кто-то выстраивает абстракции, призванные облегчить программирование, общее количество вещей, которые нужно знать, чтобы быть отличным программистом, все время растет экспоненциально.
Стать профессионалом, действительно профессионалом только в одной области программирования занимает годы. Конечно, множество умных тинэйджеров выучивают Delphi за одну неделю и Python за другую и Perl за третью и думают что они профессионалы. Они так еще и не поняли, как много они пропустили.
Я проработал с ASP и VBScript, с тех пор как они только появились. VBScript изящнейший язык на земле и ASP программирование состоит в изучении пяти классов, только два из которых используются достаточно часто. И только сейчас наконец я по видимому знаю лучший способ построения ASP/VBScript приложений. Я думаю, что узнал, наконец, где лучшее место размещения кода для доступа к базе данных, лучший способ использования ADO для получения наборов данных, лучший способ разделить HTML и код и так далее. И я наконец использую регулярные выражения вместо одноразовых функций работы со строками. Только на последней неделе я научился выгружать COM объекты из памяти, для того чтобы перекомпилировать их (без перезапуска всего COM сервера).
Fog Creek слишком мала, чтобы иметь узких специалистов, таким образом, когда мне понадобилось написать по-настоящему хороший инсталлятор для FogBUGZ, нашего основанного на ASP/VBScript продукта, мне понадобилось несколько лет опыта в C++/MFC и годы опыта с различными Windows API, а также хорошие навыки работы с Corel PhotoPaint для того чтобы нарисовать подходящую картинку в углу диалогового окна мастера. Тогда, для того чтобы FogBUGZ отлично работал с Unicode, мне понадобилось написать маленький ActiveX элемент управления с использованием C++ и ATL, для чего понадобились годы опытов в С++ и COM и неделя или около того обучения кодировкам символов в то время, как я реализовывал этот код для CityDesk.
Таким образом, когда мне встретилась непонятная ошибка, проявлявшаяся только в Windows NT 4.0, мне понадобилось только 3 минуты отладки, потому что я знал, как использовать VMWare, и у меня была чистая предустановленная NT 4.0 для VMWare, также я знал, как выполнять удаленную отладку в Visual C++ и я знал, что надо заглянуть в EAX регистр для получения возвращаемого функцией значения. Тот, кому все это в новинку, потратил бы не меньше часа, чтобы отладить ту же самую проблему, а я уже знал огромное количество “штучек”, которым учился, по существу, с 1982 года, когда я получил мой первый IBM-PC и ту самую книгу Питера Нортона.
Дырявые абстракции означают, что мы живем с очень резкой кривой обучения: вы можете выучить 90% того, что вы используете каждый день за неделю обучения. Но на то, чтобы разобраться в остальных 10%, уйдет еще пара лет. Это то, чем по-настоящему опытные программисты отличаются от людей, которые говорят ”не важно, что вы хотите, что бы я сделал, я могу открыть книгу и научиться делать это”. Если вы создаете команду, нормально иметь множество менее опытных программистов для написания больших участков кода с использованием обобщенных инструментов, но команда не удастся, если у вас нет нескольких по-настоящему опытных членов команды для выполнения действительно сложной работы.
Существует множество областей программирования, каждая из которых требует огромного количества знаний для настоящего профессионализма. Вот три из них, которые я сам знаю лучше всего:
- MFC/C++/Windows
- VBScript/ASP
- Visual Basic
Все, по существу, что вы могли бы назвать Windows программированием. Да, я писал Unix код и Java код, но не очень много. Моя квалификация в Windows программировании проистекает оттого, что я знаю не только базовые технологии, но и всю поддерживающую инфраструктуру. Таким образом, я утверждаю, что я действительно хорош в Windows программировании, потому что я также знаю COM, ATL, C++, 80x86 Ассемблер, различные Windows API, IDispatch (OLE Automation), HTML, DOM, объектную модель Internet Explorer, внутренности Windows NT and Windows 95, LAN Manager и сетевую работу в NT, включая безопасность (ACEs, ACLs, и все остальные вещи), SQL и SQL Сервер, Jet и Access, JavaScript, XML, и несколько других забавных фактов о площади гипотенузы. Когда я не смог добиться от StrConv функции того чего я хотел, я сварганил элемент управления COM, чтобы попасть в C++ с помощью ATL и вызвать MLang функции, не теряя ритма. Мне понадобились годы, чтобы достичь этого.
Существует множество других областей программирования. Скажем, люди, разрабатывающие для BEA Weblogic, которые знают J2EE, Oracle и всевозможные Java штучки, о которых я не знаю достаточно даже для того чтобы их перечислить. Или костяк разработчиков для Macintosh, которые знают CodeWarrior, MPW, Toolbox программирование in System 6 через X, Cocoa, Carbon, и даже такие такую милую устаревшую вещь как OpenDoc, которая не может больше помочь.
Очень немногие люди имеют достаточно знаний более чем в одной или двух областях, потому что там нужно так много всего узнать, даже что если вы проработали в одной из этих областей пару лет, вы все равно не разобрались во всем.
Но учиться вы должны.
Люди отчасти обижаются, когда они приходят на собеседование и получают отказ, потому что у них нет опыта работы с Win32 (или с J2EE, или в Mac-программировании, или чем-то еще). Или они раздражаются, потому что идиоты рекрутеры, которые не узнали бы MSMQ, даже если бы он пинал их под зад, звонят им и спрашивают «Есть ли у вас 5-летний опыт работы с MSMQ?».
До тех пор пока вы не посвятите Windows-программированию множество времени, вы можете думать, что Win32 — это всего-навсего библиотека, похожая на многие другие библиотеки, вы прочитаете книжку, выучите ее и будете вызывать, когда она вам понадобится. Вы можете думать, что основу программирования составляют ваши превосходные знания 90% C++, а различные API — это только 10-процентный пушок, в котором вы сможете разобраться за несколько недель. Этим людям я скромно подсказываю: времена изменились. Соотношение изменилось на противоположное.
Очень немного людей работает над низкоуровневыми C алгоритмами, которые только перемещают байты и не более того. Большинство из нас нынче проводит все время, вызывая различные API, а не перемещая байты. Каким бы превосходным C++ кодировщиком ни был человек без опыта в API, он знает только около 10% того, что он должен использовать каждый день для написания кода запускаемого на API. Когда дела в экономике идут хорошо, это не имеет значения. Вы все еще имеете работу и наниматели платят стоимость вашего обучения соответствующей платформе. Но когда в экономике царит неразбериха и 600 человек подают заявления на каждую открытую вакансию, наниматели могут позволить себе удовольствие выбирать программистов которые уже эксперты в интересующей их области. Например, программистов, которые могут назвать четыре способа заслать файл по FPT из кода на Visual Basic и слабые и сильные стороны каждого из них.
Огромные пространства всех этих областей ведут к бесцельному обмену язвительными посланиями в сети (flame wars) в попытках выяснить, чей мир лучше. Вот такой самодовольный комментарий сделал кто-то анонимно на моей доске обсуждений:
«Еще одна причина, почему мне нравится жить в ‘свободном мире’. Это практически полная свобода слова и свобода от засилья таких ужасных вещей, как установочные программы и реестр — я упомянул лишь немногие из них».
Я думаю, этот человек хотел сказать, что в мире Linux им не надо писать установочные программы. Что ж, ненавижу огорчать вас, но у вас есть кое-что не менее сложное: файлы imake, make, config и все эти штуки, и когда все готово, вы все равно должны поставлять с приложениями 20-килобайтный файл INSTALL, полный остроумных инструкций типа «Вам понадобится zlib» (что это?) или «Это может занять некоторое время. Сходите возьмите каких-нибудь сморчков (runts)» (это что-то вроде конфет, я думаю). А реестр — вместо одного большого организованного улья пар имя/значение, у вас тысячи разных файловых форматов, по одному на приложение, .whateverrc и foo.conf лежащих где попало. А emacs хочет, чтобы вы научились программировать на Лиспе, если вам нужно изменить настройки, а каждая оболочка (shell) принуждает вас изучать ее персональный диалект shell script, если вы захотите изменить настройки и так далее, и тому подобное.
Люди, которые знают только одну область программирования, становятся действительно ограниченными и всякий раз когда они слышат об усложнениях в других областях, это заставляет их думать, что их область не имеет усложнений. Но они есть. Вы минуете их потому, что умеете это делать. Эти области очень большие и сложные в сравнении с чем бы то ни было. Лорд Палмерстон: «Вопрос Шлезвига-Гольштейна настолько сложен, что только три человека в Европе вообще понимают его. Одним был принц Альберт, который умер. Вторым был немецкий профессор, который сошел с ума. Я третий, и я уже забыл все, что знал о нем». Различные области программного обеспечения настолько огромны и имеют настолько много аспектов, что когда я вижу других умных людей, пишущих в своих блогах что-нибудь пустое, вроде «Microsoft — это плохая операционная система», это, откровенно говоря, выглядит глупо. Вообразите попытку охватить миллионы строк кода с сотнями основных областей созданных тысячами программистов за одно или два десятилетия, тогда как нет ни одного человека, который мог бы разобраться даже в большей части этого. Я даже не защищаю Microsoft, я только говорю, что большие бездумные обобщения, сделанные с позиции глубокого невежества — это одна из самых больших трат времени в сети сегодня.
Постоянные читатели к этому времени заметили, что я думал о проблеме возможности выпуска приложений для Linux, Macintosh, и Windows без необоснованных затрат на Linux- и Macintosh-версии. Для этого вам нужна какая-нибудь кроссплатформенная библиотека.
Java предполагалась такой, но Sun не разобралась с пользовательским интерфейсом настолько, чтобы предложить действительно гладкие естественно ощущающиеся приложения. Подобно тому как инопланетяне из Стартрека смотрели на Землю в телескопы, они знали точно на что должна быть похожа человеческая еда, но не понимали, что она должна иметь вкус человеческой еды. У Java-приложений меню расположены в правильном месте, но все эти клавиатурные штучки работают в них не так, как в других Windows-приложениях. А их диалоги с закладками выглядят довольно страшно. И невозможно, как бы вы ни старались, заставить их меню выглядеть точно как меню в Excel. Почему? Потому что Java не дает вам достаточно хорошего способа обратится к родным возможностям платформы, когда абстракция не работает. Когда вы программируете в AWT, вы не можете выяснить HWND окна, вы не можете вызвать ни один из Microsoft API и вы естественно не можете перехватить WM_PAINT и обработать его по-своему. И Sun ясно показала, что если вы попытаетесь сделать это, то уже не будете Чисты. Вы будете Запятнаны, и черт с вами.
После нескольких общеизвестных неудач в построении пользовательского интерфейса на Java (т.е. Corel's Java Office suite и Netscape's Javagator), слишком многие решили держаться подальше от этого. Eclipse создал свою собственную оконную библиотеку с нуля, используя только родные элемент управления, таким образом, чтобы люди могли писать код на Java и при этом иметь приемлемый вид окон и ощущения от работы с ними.
Инженеры Mozilla предложили кроссплатформенное решение с помощью собственного изобретения, названного XUL. И я впечатлен. Mozilla, наконец, добралась до момента, где она на вкус как настоящая еда. Даже мое любимое пугало Alt+Space N для минимизации окна работает в Mozilla. Это заняло у них достаточно много времени, но они сделали это.
Mitch Kapor, который основал Lotus и создал 123, решил в своем следующем приложении использовать нечто, называемое wxWindows и wxPython для кроссплатформенности.
Что лучше — XUL, Eclipse SWT, или wxWindows? Я не знаю. Все это настолько крупные области, что я не могу по-настоящему попробовать их и сказать. Недостаточно просто прочитать описание. Вы должны кровью и потом проработать с этими приложением год или два, перед тем как вы узнаете, что оно достаточно хорошо, либо поймете, что как бы вы ни старались, вы не сможете придать вашему графическому интерфейсу вкус настоящей еды. К несчастью, для большинства проектов вы должны решить, какую область программирования вы будете использовать, перед тем как напишете первую строчку кода, а это уж точно момент, когда вы имеете меньше всего информации. В нашей предыдущей работе у нас была довольно плохая архитектура, потому что первые программисты учились программированию C++ и программированию под Windows в процессе работы над проектом. Старейший код был написан без всякого представления об управляемом событиями программировании. Базовый класс для представления строк (конечно, мы имели свой собственный класс) был взят из книжного примера и содержал все ошибки, которые вы можете сделать, проектируя C++ класс. В конце концов, мы вычистили и переработали множество этого старого кода, но он доставал нас время от времени.
Таким образом, теперь, мой совет следующий. Не начинайте нового проекта без как минимум одного архитектора программного обеспечения с несколькими годами реального опыта в языке, классах, различных API и платформах под которые вы строите приложение. Если у вас есть выбор платформ, используйте ту в написании кода, для которой ваша команда имеет больше опыта, даже если она и не самая модная и номинально не самая продуктивная. А когда вы разрабатываете обобобщения или программные инструменты уделите больше внимания проверке слабых мест.
---
