То, чего делать нельзя (Things You Should Never Do)
От: BreQwaS Россия  
Дата: 09.09.05 18:06
Оценка: 20 (4)
Собственно, тут
Автор: BreQwaS
Дата: 09.09.05
я спрашивал, есть ли перевод сабжа. Теперь — есть

Это моя первая попытка перевести что-то большое, так что помимо прочего буду рад послышать ругань на тему качества результата.

Оригинал тут.

То, чего делать нельзя, часть I.

Джоэль Спольски
Четверг, 6 апреля 2000 года

Наконец-то вышла первая публичная бета-версия Netscape 6.0. Версии 5.0 не существовало никогда. Последний крупный релиз, 4.0, вышел почти три года назад. Три года – это до неприличия большой срок по меркам интернета. Всё это время Netscape беспомощно наблюдал за тем, как его доля рынка утекает как песок сквозь пальцы.

Это, наверное, не очень хорошо с моей стороны – критиковать их за такие большие паузы. Они ведь не специально это делали, разве нет?

Ну, на самом деле — нет. Они делали это из-за одной-единственной стратегической ошибки, самой худшей, которую может сделать софтверная компания.

Они решили переписать код с нуля.

Netscape был не первой компанией, совершившей эту ошибку. Borland прокололся на этом в первый раз, когда купил Arago и пытался переделать его в dBase для Windows — кошмарный проект, который занял так много времени, что Microsoft Access уже очень основательно занял освободившуюся нишу, — и во второй раз, когда переписал заново Quattro Pro, изумивший всех своим мизерным количеством фич. Microsoft тоже разок почти попалась в эту ловушку, попытавшись переписать Word for Windows – этот проект, называвшийся Pyramid, был остановлен, стыдливо спрятан в дальний угол и забыт как страшный сон. К счастью для Microsoft, они никогда не переставали работать со старым материалом, и у них всегда была возможность что-то выпускать. Это превратило глобальную катастрофу во всего лишь финансовую.

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

Есть одна причина, по которой программисты всегда хотят выбросить старый код и начать сначала: они всегда считают, что старый код ужасен. По моим наблюдениям, они, возможно, неправы. Считать этот код ужасным их заставляет глубокий, фундаментальный закон программирования:

Читать код сложнее, чем писать его.


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

Следствие из этой аксиомы: спросите первого попавшегося программиста, ковыряющего чужой код, как он ему нравится, и он с очень больной долей вероятености ответит: «Да там сам чёрт ногу сломит! Лучшее, что с ним можно сделать – это выкинуть и написать заново!»

А в чём, собственно, дело?

«Да вы только посмотрите на эту функцию – она занимает аж две страницы! Тут всё совсем не то – я даже не представляю, зачем нужны все эти библиотечные вызовы!»

Когда Borland выпустил свой новый редактор электронных таблиц, пресса часто цитировала Филиппа Канна (Philippe Kahn), основателя Borland, довольно колоритного персонажа: он активно похвалялся тем, что Quattro Pro будет гораздо лучше, чем конкурирующий MS Excel, потому что продукт Borland был переписан заново. Ах, как классно — совершенно новый код! Как будто бы исходники ржавеют.

Уверенность в том, что новый код лучше старого, абсурдна по определению. Старый код использовался. Он тестировался. Куча багов была найдена, и они были исправлены. С ним всё в порядке! В нём не появится ошибок только оттого, что он лежит у вас на винчестере. Всё как раз наоборот! Или по-вашему софт похож на старый москвич, ржавеющий от стояния в гараже? Или на плюшевого мишку, который уже далеко не так хорош, если он не совсем новый?

Возвращаясь к той двухстраничной функции: да, я знаю, что это простенькая функция, которая показывает окошко. Но она почему-то основательно вздулась, и никто не знает, в чём дело. Хотите я скажу в чём? Это багфиксы. Один из них исправляет баг, который вылез, когда какой-то умник попытался установить нашу программу на систему, где не было Internet Explorer. Другой – отслеживает нехватку памяти, из-за которой программа падала на слабых машинах. Третий – отслеживает ситуацию, когда юзер выдёргивает дискетку посреди операции. Вон тот вызов LoadLibrary выглядит криво, но зато позволяет коду нормально раотать на ранних версиях Win95.

Каждая из этих ошибок была найдена после недель реального использования программы. Программисту могло потребоваться несколько дней, чтобы её воспроизвести и исправить. Может быть исправить пришлость строчку-две или даже несколько символов – как это обычно и бывает с багами – но на эти символы была порачена масса времени и сил.

Когда вы выбрасываете код и начинаете с нуля, вы выбрасываете и все эти знания. Все эти заботливо собранные багфиксы. Годы кропотливого труда.

Вы выбрасываете своё лидерство на рынке. Вы делаете своим конкурентам подарок в виде двух-трёх лет форы, и – поверьте мне – это большой срок в нашей отрасли.

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

Вы тратите дикое количество денег на написание кода, который уже написан.

А есть ли альтернатива? Есть мнение, что код старого Netscape был действительно плох. Может оно и так, но знаете что? Он работал чертовски хорошо на диком количестве реальных машин.

Когда программисты говорят, что им приходится работать с отвратительным кодом (а они всегда так говорят), то это может означать три вещи.

Во-первых, там могут быть архитектурные проблемы. Код скомпонован неверно. Модуль работы с сетью выплёвывает из ниоткуда собственные диалоговые окна, которым место в модуле UI. Такие проблемы могут быть решены поочерёдно аккуратным перенесением кода, рефакторингом, изменением интерфейсов. Одного аккуратного программиста, проверяющего все свои изменения, будет достаточно, и никого не придётся отвлекать. Даже очень серьёзные архитектурные изменения можно делать не выбрасывая код. Работая над Juno мы потратили на это несколько месяцев: мы просто переставляли местами куски кода, «прилизывали» их, делали осмысленные базовые классы, сочиняли хорошие интерфейсы между модулями и пр. Но мы делали это аккуратно, на базе уже существующего кода, так что мы не наплодили новых багов и нам не пришлось ничего выбрасывать.

Во-вторых, программисты могут считать, что код неэффективен. По слухам, рендеринг в Netscape работал очень медленно. Но это влияет только на очень маленькую часть проекта, которую вы можете оптимизировать или даже переписать. Вам не нужно переписывать всё. Когда вы оптимизируете что-нибудь на скорость, то 1% работы даст 99% эффекта.

В третьих, код может быть очень уродливым. В одном проекте, над которым я работал, был класс FuckedString. В другом сначала использовалось соглашение, по которому члены классов начинались с подчёркивания, а потом – с «_m». Поэтому половина названий начиналась с “_”, а другая – с «m_», и это выглядело некрасиво. Вообще-то, такие вещи решаются с помощью макроса в Emacs, а не с помощью переписывания всей программы с нуля.

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

Старая поговорка про «сделай первый раз, чтобы выбросить» опасна, когда её применяют к крупномасштабным коммерческим приложениям. Если вы пишете экспериментальный код, вы можете выкинуть функцию, которую вы написали на прошлой неделе, потому что вы придумали алгоритм получше. Это нормально. Вы можете захотеть прорефакторить какой-нибудь класс, чтобы его было легче использовать. Это тоже нормально. Но выбрасывание целой программы – это опасная глупость, и будь Netscape «под присмотром взрослых» с хорошим опытом в софтверной индустрии, они не наступили на эти грабли.
WinAmp играет: Jethro Tull — Weathercock
http://livejournal.com/users/breqwas
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.