Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
В книге «Идеальная работа. Программирование без прикрас» легендарный Роберт Мартин (Дядюшка Боб) создал исчерпывающее руководство по хорошей работе для каждого программиста. Роберт Мартин объединяет дисциплины, стандарты и вопросы этики, необходимые для быстрой и продуктивной разработки надежного, эффективного кода, позволяющего испытывать гордость за программное обеспечение, которое вы создаете каждый день. Роберт Мартин, автор бестселлера «Чистый код», начинает с прагматического руководства по пяти основополагающим дисциплинам создания программного обеспечения: разработка через тестирование, рефакторинг, простой дизайн, совместное программирование и тесты. Затем он переходит к стандартам — обрисовывая ожидания «мира» от разработчиков программного обеспечения, рассказывая, как часто различаются эти подходы, и помогает вам устранить несоответствия. Наконец, он обращается к этике программиста, давая десять фундаментальных постулатов, которым должны следовать все разработчики программного обеспечения.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 352
Veröffentlichungsjahr: 2023
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Переводчик И. Рузмайкина
Роберт Мартин
Идеальная работа. Программирование без прикрас. — СПб.: Питер, 2022.
ISBN 978-5-4461-1910-3
© ООО Издательство "Питер", 2022
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Я помню, как познакомилась с Дядей Бобом весной 2003 года, вскоре после того, как нашей команде специалистов по информационным технологиям рассказали о методологии Scrum. Как скептически настроенный Scrum-мастер, я слушала рассказы Боба о TDD и инструменте FitNesse и думала: «Зачем вообще писать изначально провальные тесты? Разве тестирование не должно идти за написанием кода?» Я часто уходила в недоумении, как и многие члены моей команды. Но стремление Боба к профессионализму в написании кода не могло не поражать. Я помню, как однажды, просматривая наш журнал ошибок, он в лоб спросил, с какой стати мы принимаем настолько неверные решения в отношении программных систем, не являющихся нашей собственностью: «Это активы компании, а не ваши личные активы». Его энтузиазм вызывал любопытство, и через полтора года мы провели рефакторинг, обеспечив 80-процентное автоматизированное покрытие тестами и чистую кодовую базу, что значительно упростило процедуру изменения бизнес-модели и целей компании, сделав намного счастливее как клиентов, так и сотрудников. После этого, вооружившись определением «сделано надежно, как броня», мы молниеносно выстроили защиту от непрерывно охотящихся на уязвимости черных хакеров; в сущности, мы научились защищаться от самих себя. Со временем мы с теплотой начали относиться к Дяде Бобу, который стал для нас настоящим дядей — добросердечным, решительным и смелым человеком, учившим нас стоять за себя и поступать правильно. В то время как другие дяди учили своих племянников кататься на велосипеде или ловить рыбу, наш Дядя Боб учил нас хранить верность своим принципам. Умение и желание в любой ситуации проявлять смелость и любопытство были лучшим, чему я научилась за все время моей профессиональной деятельности.
Я следовала советам Боба, когда начала работать Agile-коучем, и быстро заметила, что лучшие команды разработчиков владели умением подбирать под конкретный контекст и конкретных клиентов лучшие из практик, принятых в отрасли. Я вспоминала уроки Боба, обнаружив, что лучшие в мире инструменты разработки хороши ровно настолько, насколько успешно люди умеют найти им оптимальное применение. Я поняла, что иногда высокий процент покрытия модульными тестами достигается исключительно для того, чтобы поставить галочку и соответствовать метрике, а на деле большинство этих тестов ненадежно. Достижение заданных метриками значений не приносило никакой пользы. При этом лучшим командам не приходилось заботиться о метриках; у них была цель, они были дисциплинированными, гордыми, ответственными — и показатели в каждом случае говорили сами за себя. Книга «Идеальная работа» сплетает все эти уроки и принципы в практические примеры кода и опыт, иллюстрирующие разницу между работой, преследующей единственную цель — уложиться в срок, и реальным созданием систем, стабильных в долгосрочной перспективе.
Книга напоминает, что никогда не нужно соглашаться на меньшее, что нужно делать свое дело с бесстрашной компетентностью. Она, как старый друг, напомнит о том, что имеет значение, что работает, а что нет, что увеличивает риск, а что снижает его. Это уроки на все времена. Возможно, в процессе чтения вы обнаружите, что уже практикуете некоторые из описанных в книге техник. Но готова держать пари: вы найдете и новое или, по крайней мере, то, от чего когда-то отказались, например, поскольку не успевали завершить проект в запланированные сроки или по какой-то другой причине. Для новичков в мире разработки, специализирующихся как в бизнесе, так и в технологиях, эта книга — шанс поучиться у одного из лучших специалистов. И даже самые опытные практики найдут здесь способы что-то для себя улучшить. Возможно, эта книга поможет вам снова обрести энтузиазм, возродить желание совершенствоваться в своей профессии, сколько бы препятствий ни стояло на вашем пути.
Разработчики программного обеспечения правят миром, и Дядя Боб в очередной раз хотел бы напомнить людям, обладающим такой властью, о профессиональной дисциплине. Он продолжает повествование с того места, на котором закончил книгу «Чистый код». Поскольку разработчики в буквальном смысле слова пишут правила для всех людей, Дядя Боб напоминает о необходимости соблюдать строгий этический кодекс, напоминает, что именно они отвечают за то, что делает написанный ими код, за то, как люди его используют, и за то, где он выходит из строя. Ошибки в программном обеспечении могут лишить как средств к существованию, так и жизни. ПО влияет на наш образ мыслей, на принимаемые нами решения, а благодаря искусственному интеллекту и предсказательной аналитике — еще и на социальное и стадное поведение. Поэтому разработчики должны чувствовать свою ответственность и действовать с большой осторожностью и эмпатией, ведь от их действий зависит здоровье и благополучие людей. Дядя Боб помогает нам выстоять перед лицом этой ответственности и стать профессионалами, которые нужны обществу.
Поскольку на момент написания этого предисловия приближается двадцатая годовщина с момента создания Манифеста гибкой разработки программного обеспечения, данную книгу можно считать прекрасной возможностью вернуться к основам: своевременным и скромным напоминанием о постоянно растущей сложности мира ПО, а также о том, что перед человечеством и перед собой мы обязаны практиковать этичную разработку. Не торопитесь быстрее прочитать «Идеальную работу». Позвольте принципам укорениться внутри вас. Практикуйте их. Улучшайте их. Учите им других. Держите эту книгу на своей книжной полке. Пусть она станет вашим верным другом — вашим Дядей Бобом, вашим проводником, — пока вы с любопытством и отвагой прокладываете себе путь в этом мире.
Стася Хаймгартнер Вискарди (Stacia Heimgartner Viscardi), наставник по CST и Agile
Прежде чем вы приступите к чтению, нужно обсудить пару моментов, чтобы убедиться, что вы, мой любезный читатель, понимаете, в какой системе отсчета существует эта книга.
Начало XXI века отмечено терминологическими спорами. Индустрия программного обеспечения внесла в эти дискуссии свою лепту. Термин, который часто считают недостаточно полно описывающим суть, — мастер своего дела (craftsman).
Я довольно много думал над этим вопросом, разговаривал с людьми, придерживающимися различных мнений, и пришел к выводу, что лучшего термина для использования в контексте этой книги нет.
Я рассматривал и такие альтернативы, как «специалист», «умелец», «ремесленник», но ни одна из них не имела нужной исторической весомости. А мне было очень важно подчеркнуть ее.
Словосочетание «мастер своего дела» вызывает в памяти человека, обладающего глубокими знаниями и опытом в профессиональной деятельности. Человека, который свободно оперирует своими инструментами и применяет свои профессиональные навыки. Который гордится результатами своего труда, и поэтому можно быть уверенным в том, что он будет вести себя с достоинством и профессионализмом в соответствии со своим призванием.
Возможно, кто-то из вас не согласится с моим выбором. Я понимаю почему. Но надеюсь, что вы не истолкуете выбранный мной термин как попытку подчеркнуть исключительность в каком-либо смысле. Подобное ни в коем случае не входит в мои намерения.
В процессе чтения этой книги может возникнуть ощущение, что здесь описан единственный возможный путь к мастерству. Но я всего лишь описал собственный путь, а для вас он может оказаться совсем другим. Выбор только за вами.
Нужен ли вообще один правильный путь? Я не знаю. Возможно. Потребность в строгом определении профессии программиста растет. К цели можно идти разными путями, в зависимости от важности создаваемого программного обеспечения. Но как вы скоро убедитесь, отделить критически важное ПО от неважного не так-то просто.
В одном я уверен. Времена «судей»1 прошли. Сейчас уже недостаточно того, что каждый программист поступает так, как считает правильным. Появляются определенные практики, стандарты и этика. Предстоит решить, будем ли мы, программисты, определять их для себя сами или они будут навязаны нам теми, кто нас не знает.
Эта книга написана для программистов и для их руководителей. И одновременно для всего нашего общества. Ведь именно мы, программисты, невольно оказались в самом его центре.
Программистам с многолетним стажем, вероятно, знакомо чувство удовлетворения, наступающее после развертывания системы. Вы испытываете определенную гордость за то, что приложили к этому руку. Вы счастливы от осознания успешно завершенной работы.
Но гордитесь ли вы тем, как вы достигли такого результата? Чем вызвана ваша гордость? Самим фактом завершения работы или это гордость за ваше мастерство? Вы гордитесь тем, что система была развернута? Или тем, как вы ее построили?
Придя домой после тяжелого рабочего дня, вы смотрите в зеркало и говорите: «Сегодня я отлично поработал»? Или чувствуете желание принять душ?
Слишком многие из нас в конце дня ощущают себя грязными. Слишком многие считают, что им приходится выполнять некачественную работу. Слишком многим кажется, что низкое качество — закономерный результат гонки за высокой скоростью. Слишком многие думают, что производительность обратно пропорциональна качеству.
В данной книге я пытаюсь сломать такие ментальные установки. Это книга о том, как работать качественно. Она описывает дисциплины и практики, которые должен знать каждый программист, чтобы работать быстро, продуктивно и каждый день гордиться результатами своего труда.
В XXI веке впервые в истории человечества выживание общества стало зависеть от технологии, практически лишенной какого-либо подобия дисциплины или контроля. Программное обеспечение вторглось во все аспекты современной жизни, от заваривания утреннего кофе до вечерних развлечений, от стирки одежды до вождения автомобиля, от соединения людей во Всемирную сеть до социального и политического разделения. В современном мире мало жизненных аспектов, на которые бы не оказывало влияние ПО. При этом те, кто его создает, представляют собой всего лишь сборище разношерстных ремесленников, едва имеющих представление о том, что они делают.
Если бы мы, программисты, лучше понимали, что делаем, может быть, не было бы сбоя голосования в Айове в 2020-м? Не погибли бы 346 человек в двух авариях 737 Max? Не потеряла бы финансовая фирма Knight Capital Group 460 миллионов долларов за 45 минут? Не погибли бы 89 человек из-за внезапного ускорения автомобилей Toyota?
Каждые пять лет число программистов в мире удваивается. При этом их практически не обучают. Им показывают инструменты, дают разработать несколько несложных проектов, а затем бросают в работу, чтобы удовлетворить экспоненциально растущий спрос на новое программное обеспечение. С каждым днем шаткая конструкция, которую мы называем ПО, все глубже проникает в нашу инфраструктуру, наши институты, наши правительства и нашу жизнь. И с каждым днем растет риск катастрофы.
Какую катастрофу я имею в виду? Это не крах нашей цивилизации и не внезапное исчезновение всех программных систем одновременно. Готовый обрушиться карточный домик состоит не из самих программных систем. Скорее под угрозой находится хрупкая основа общественного доверия.
Слишком много происшествий с самолетами 737 Max, с самопроизвольным ускорением автомобилей Toyota, с претензиями к автомобилям Volkswagen со стороны California EPA или со сбоем голосования, как это получилось в Айове. Еще немного громких случаев сбоев программного обеспечения или злоупотреблений — и отсутствие у разработчиков дисциплины и этики, а также нехватка стандартов прикуют к себе внимание недоверчивой и разгневанной общественности. И тогда начнется регулирование, нежелательное для любого из нас. Регулирование, которое лишит нас возможности свободно исследовать и расширять мастерство разработки ПО; которое наложит серьезные ограничения на рост технологий и экономики.
Эта книга написана не для того, чтобы остановить безудержное стремление ко все большему внедрению программного обеспечения. Не ставлю я целью и снижение темпов его создания. Тем более что это была бы пустая трата сил. Обществу нужно ПО, и оно в любом случае его получит. Попытка подавить эту потребность не остановит надвигающуюся катастрофу общественного доверия.
Скорее своей книгой я пытаюсь убедить разработчиков программного обеспечения и их руководителей в необходимости дисциплины, а также научить практикам, стандартам и этике, эффективно повышающим умение создавать надежные, отказоустойчивые продукты. Только изменив способ работы программистов, повысив их дисциплину, научив их правильным практикам, этике и стандартам, можно укрепить карточный домик и предотвратить его обрушение.
Книга состоит из трех частей, описывающих три уровня: практики, стандарты и этику.
Первая часть, посвященная различным практикам, описывает самый низкий уровень и носит прагматичный, технический и предписывающий характер. Ее будет полезно прочитать и понять программистам всех мастей. Я дал несколько ссылок на видеоролики, в реальном времени демонстрирующие ритм разработки через тестирование и рефакторинг. В тексте я тоже попытался дать представление об этом ритме, но ничто не способно сделать это так же хорошо, как видео.
Вторая часть посвящена стандартам. Это средний уровень. Здесь я знакомлю вас с ожиданиями, которые окружающий мир возлагает на нашу профессию. Это хороший материал для руководителей, позволяющий им понять, чего ожидать от профессиональных программистов.
Информация высшего уровня — это часть, посвященная этике. Здесь в форме клятвы или набора обещаний я описываю этический контекст профессии программиста. В этой части вы встретите множество исторических и философских дискуссий. Ее имеет смысл читать как программистам, так и их руководителям.
Страницы этой книги содержат много полезной информации. Но они наполнены и множеством технических деталей, которые вам, скорее всего, не нужны. Поэтому я советую читать начало каждой главы и прекращать чтение, когда начинается описание ненужных вам технических подробностей.
Обязательно изучите часть II «Стандарты» и часть III «Этика». И обязательно прочтите введение в каждую из пяти практик.
1 Отсылка к Книге Судей Израилевых.
Спасибо моим мужественным рецензентам: Деймону Пулу (Damon Poole), Эрику Кричлоу (Eric Crichlow), Хизер Кансер (Heather Kanser), Тиму Оттингеру (Tim Ottinger), Джеффу Лангру (Jeff Langr) и Стасе Вискарди (Stacia Viscardi). Они спасли меня от множества неверных шагов.
Кроме того, я очень благодарен Джули Файфер (Julie Phifer), Крису Зану (Chris Zahn), Менке Мехте (Menka Mehta), Кэрол Лаллье (Carol Lallier) и всем сотрудникам издательства Pearson, которые неустанно совершенствуют выпускаемые книги.
Как всегда, огромное спасибо моему творчески одаренному и талантливому иллюстратору Дженнифер Конке (Jennifer Kohnke). Ее картинки всегда вызывают у меня улыбку.
И конечно же, спасибо моей прекрасной жене и замечательной семье.
Роберт С. Мартин, также известный как Дядя Боб (Uncle Bob), написал первую строку кода в возрасте 12 лет в 1964 году. Работает программистом с 1970 года. Сооснователь компании cleancoders.com, предлагающей видеоуроки для разработчиков программного обеспечения, и основатель компании Uncle Bob Consulting LLC, оказывающей консультационные услуги и услуги по обучению персонала крупным корпорациям. Был ведущим специалистом в консалтинговой фирме 8th Light, Inc. в городе Чикаго.
Опубликовал десятки статей в специализированных журналах и регулярно выступает на международных конференциях и выставках. Создатель популярной серии обучающих видео на сайте cleancoders.com.
Мартин написал несколько книг, еще для некоторых он выступил редактором:
• Designing Object-Oriented C++ Applications Using the Booch Method;
• Patterns Languages of Program Design 3;
• More C++ Gems;
• Extreme Programming in Practice;
• Agile Software Development: Principles, Patterns, and Practices2;
• UML for Java Programmers;
• Clean Code3;
• The Clean Coder4;
• Clean Architecture: A Craftsman’s Guide to Software Structure and Design5;
• Clean Agile: Back to Basics6.
Как лидер в сфере разработки программного обеспечения, Мартин три года был главным редактором журнала C++ Report и первым председателем группы Agile Alliance.
2Мартин Р.С. Быстрая разработка программ: Принципы, примеры, практика.
3Мартин Р.С. Чистый код: Создание, анализ и рефакторинг. — СПб.: Питер.
4Мартин Р.С. Идеальный программист: Как стать профессионалом разработки ПО. — СПб.: Питер.
5Мартин Р.С. Чистая архитектура: Искусство разработки программного обеспечения. — СПб.: Питер.
6Мартин Р.С. Чистый Agile. Основы гибкости. — СПб.: Питер.
Обучающие видеоролики, ссылки на которые дает автор, — на английском языке. Срок бесплатного доступа к ним ограничен и составляет десять дней.
Ваши замечания, предложения, вопросы отправляйте по адресу [email protected] (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
Мечта летать, наверное, так же стара, как само человечество. Древнегреческий миф о Дедале и Икаре датируется примерно 1550 годом до нашей эры. В последующие тысячелетия в погоне за этой мечтой множество смелых, но безрассудных людей привязывали к себе несуразные приспособления и прыгали со скал и башен навстречу неизбежной смерти.
Ситуация изменилась примерно 500 лет назад. Машины, эскизы которых нарисовал Леонардо да Винчи, не могли летать, но, по крайней мере, подход к их проектированию был логичным. Именно да Винчи понял, что полет возможен, поскольку сопротивление воздуха работает в обе стороны. Сопротивление, возникающее, когда на воздух давят сверху, создает такую же подъемную силу. Этот принцип стал основой создания всех современных самолетов.
Про идеи да Винчи забыли до середины XVIII века. А затем начались лихорадочные изыскания возможности летать. XVIII и XIX века стали временем упорных исследований и экспериментов в сфере воздухоплавания. Строились, тестировались, отбрасывались и совершенствовались безмоторные прототипы. Начала формироваться такая наука, как аэронавтика. Появились определения подъемной силы, сопротивления, тяги и гравитации. Смельчаки стали предпринимать попытки полетов.
Некоторые падали и погибали.
С конца XVIII века в течение почти 50 лет отец современной аэродинамики сэр Джордж Кейли (George Cayley) строил экспериментальные установки, прототипы и полноразмерные модели. Кульминацией его усилий стал первый пилотируемый полет планера.
А смельчаки продолжали падать и погибать.
Затем наступила эпоха паровых машин, которая принесла с собой возможность управляемых полетов. Были построены десятки прототипов и проведены множество экспериментов. Летный потенциал стали исследовать многочисленные ученые и энтузиасты. В 1890 году Клеман Адер (Clement Ader) на двухмоторной паровой машине пролетел 50 метров.
Но все равно оставались те, кто падал и погибал.
Двигатель внутреннего сгорания полностью изменил правила игры. Вероятнее всего, первый контролируемый полет совершил Густав Уайтхед (Gustave Whitehead) в 1901 году. Первый же по-настоящему управляемый полет на оснащенном двигателем аппарате тяжелее воздуха выполнили 17 декабря 1903 года в местечке Килл-Девил-Хиллз штата Северная Каролина братья Райт (Wright Brothers). Но даже тогда хватало и тех, кто падал и погибал.
Тем не менее всего за одну ночь мир изменился. Одиннадцать лет спустя, в 1914 году, над Европой шли воздушные бои на бипланах. И хотя в этих боях многие разбивались и погибали, столько же разбилось и погибло при попытках научиться летать. Принципы полета были более-менее понятными, а вот как полет осуществляется технически, люди почти не понимали.
Спустя еще два десятилетия грозные истребители и бомбардировщики несли смерть и разрушения городам Франции и Германии. Эти самолеты летали очень высоко, были оснащены пулеметами и обладали огромной разрушительной силой.
За время Второй мировой было потеряно 65 тысяч американских самолетов. Но из них только 23 тысячи были потеряны в боях. Куда чаще летчики гибли потому, что толком не умели летать.
Следующее десятилетие ознаменовалось появлением реактивных самолетов, преодолением звукового барьера и взрывным ростом количества коммерческих авиалиний и гражданских авиаперевозок. Начался век высоких скоростей, и состоятельные люди получили возможность за считаные часы перемещаться между городами и странами.
Количество авиакатастроф при этом ужасало, так как мы еще многого не понимали в самолетостроении и пилотировании. Тем не менее к концу 1950-х пассажирские самолеты Боинг 707 уже летали по всему миру. А к концу 1960-х появился первый широкофюзеляжный реактивный самолет Боинг 747. Воздушные путешествия стали самым безопасным7 и эффективным средством передвижения в истории. Но это потребовало много времени и человеческих жертв.
Чесли Салленбергер (Chesley Sullenberger) родился в 1951 году в городе Денисон, штат Техас. Настоящее дитя века высоких скоростей. Он научился летать в шестнадцать и в конце концов начал пилотировать сверхзвуковые истребители F-4 Phantom. В 1980 году перешел на работу в гражданскую авиацию и стал пилотом US Airways.
Пятнадцатого января 2009 года, сразу после вылета из аэропорта Ла-Гуардия пилотируемый Салленбергером Airbus A320, на борту которого находились 155 человек, столкнулся со стаей гусей и потерял оба реактивных двигателя. Благодаря опыту, приобретенному за более чем 20 тысяч часов воздушных полетов, Салленбергеру удалось развернуть выведенный из строя лайнер и приводниться на поверхность реки Гудзон. Сто пятьдесят пять человек были спасены, поскольку командир воздушного судна Салленбергер был настоящим мастером своего дела.
Мечта о быстрых и точных вычислениях и управлении данными тоже, похоже, существует столько же времени, сколько и человечество. Тысячи лет назад люди использовали для счета пальцы, палочки, бусины. Более четырех тысяч лет назад появились счеты. Около двух тысяч лет назад создали механические устройства для предсказания движения звезд и планет. А около 400 лет назад изобрели логарифмическую линейку.
В начале XIX века Чарлз Бэббидж (Charles Babbage) начал строить механические вычислительные аппараты, которые приводились в действие специальными рукоятками. Это были настоящие вычислительные комплексы с памятью и арифметической обработкой. Но их производство затруднял низкий уровень металлообработки. Бэббидж построил несколько прототипов, но коммерческого успеха они не имели.
В середине 1800-х годов у него возникла идея гораздо более мощного программируемого вычислительного устройства, которое в итоге стало прообразом современного цифрового компьютера. Свое творение Бэббидж назвал аналитической машиной.
Дочь лорда Байрона Ада, графиня Лавлейс, переводя на английский язык лекцию Бэббиджа, записанную по-французски, пришла к неожиданному выводу, что со временем такая машина не будет ограничена работой с числами, а сможет обрабатывать любые объекты. Поэтому Аду часто называют первым в мире настоящим программистом.
Из-за отсутствия финансирования и низкого уровня технологий того времени аналитическая машина Бэббиджа так и не была построена. На много десятилетий прогресс в области цифровых компьютеров остановился. Впрочем, то была золотая пора механических аналоговых счетных машин.
В 1936 году Алан Тьюринг (Alan Turing) показал, что не существует общего способа доказать решаемость произвольного диофантового уравнения8. Для этого математик воспользовался моделью в виде простого, хотя и бесконечного цифрового компьютера, и доказал существование невычислимых чисел. В процессе работы над этим доказательством были изобретены конечные автоматы, машинный язык, язык символов, макросы и примитивные подпрограммы. Тьюринг изобрел то, что сегодня мы бы назвали программным обеспечением.
Почти в то же время Алонзо Черч независимо от Тьюринга сформулировал и доказал эту же задачу, попутно разработав лямбда-исчисление — основную концепцию функционального программирования.
В 1941 году Конрад Цузе (Konrad Zuse) построил первый электромеханический программируемый цифровой компьютер Z3. Он состоял из более чем 2000 реле и работал с тактовой частотой от 5 до 10 Гц. Машина использовала двоичную арифметику, длина машинного слова составляла 22 бита.
Во время Второй мировой войны Тьюринга пригласили помочь экспертам из Блетчли-парка (центра британской разведки), которые бились над расшифровкой кодов немецкой «Энигмы». Она представляла собой электромеханическую роторную машину, которая случайным образом меняла символы текстовых сообщений, транслируемых по радиотелеграфу. Тьюринг помог создать устройство для расшифровки кодов «Энигмы».
После войны он сыграл важную роль в создании и программировании одного из первых в мире ламповых компьютеров — Automatic Computing Engine (ACE). Первоначальный прототип содержал 1000 электронных ламп и обрабатывал двоичные числа со скоростью миллион бит в секунду.
В 1947 году, написав несколько программ для этой машины и изучив ее возможности, Тьюринг прочитал лекцию, во время которой прозвучали следующие пророческие заявления:
Нам потребуется большое количество способных математиков для преобразования задач в форму, подходящую для машинной обработки.
Одной из трудностей станет необходимость придерживаться определенных практик, позволяющих не терять из виду то, что делаем.
И за одну ночь мир изменился.
За несколько лет была изобретена память на магнитных сердечниках. Появилась возможность за микросекунды получать доступ к сотням тысяч, если не к миллионам битов памяти. А массовое производство электронных ламп привело к появлению более дешевых и надежных компьютеров. Становилось реальностью мелкосерийное массовое производство. К 1960 году фирма IBM продала 140 компьютеров модельного ряда 70x. Это были огромные машины на электронных лампах стоимостью в миллионы долларов.
Тьюринг использовал для написания программ двоичный код, но все понимали, что это непрактично. В 1949 году Грейс Хоппер (Grace Hopper) придумала слово компилятор, а к 1952 году создала его первую версию A-0. В конце 1953 года Джон Бэкус (John Backus) представил первую спецификацию языка FORTRAN. К 1958 году появились ALGOL и LISP.
Первый работающий транзистор был создан Джоном Бардином (John Bardeen), Уолтером Браттейном (Walter Brattain) и Уильямом Шокли (William Shockley) в 1947 году. В 1953 году был введен в эксплуатацию первый транзисторный компьютер. Переход с электронных ламп на транзисторы изменил все. Компьютеры стали меньше, быстрее, дешевле и намного надежнее.
К 1965 году IBM выпустила 10 тысяч компьютеров модели 1401. Они сдавались в аренду за 2500 долларов в месяц, что было вполне доступно среднему бизнесу. Предприятия нуждались в программистах, соответственно, спрос на них стал расти.
Кто программировал все эти машины? Университетских курсов не существовало. В 1965 году не было возможности поступить в высшее учебное заведение, чтобы научиться программировать. Поэтому программистов брали из бизнеса. Это были зрелые люди в возрасте от 30 до 50 лет.
К 1966 году IBM ежемесячно производила 1000 компьютеров серии System/360. Бизнесу этого было мало. Это были машины с объемом памяти 64 Кбайт и выше, умеющие выполнять сотни тысяч инструкций в секунду.
В том же году в Норвежском вычислительном центре в процессе работы над операционной системой Univac1107 Оле-Йохан Даль (Ole-Johan Dahl) и Кристен Нюгор (Kristen Nygard) изобрели Simula 67, который можно считать объектным расширением языка ALGOL. Это был первый объектно-ориентированный язык.
И все это всего через два десятка лет после лекции Алана Тьюринга!
Через два года, в марте 1968-го, Эдсгер Дейкстра (Edsger W. Dijkstra) написал в журнал Communications of the ACM (CACM) свое знаменитое письмо. Редактор озаглавил его «О вреде оператора goto»9. Так родилось структурное программирование.
В 1972 году в лабораториях Белла в штате Нью-Джерси Кен Томпсон (Ken Thompson) и Деннис Ритчи (Dennis Ritchie) в промежутке между работой над собственными проектами выпросили у коллег из соседней группы время на компьютере PDP 7 и изобрели операционную систему UNIX и язык программирования C.
После этого события стали развиваться с почти головокружительной скоростью. Посмотрите на этот перечень ключевых дат. Задайте себе вопрос: сколько в мире компьютеров? А сколько программистов? Откуда они все взялись?
1970 — с 1965 года корпорация Digital Equipment Corporation продала свыше 50 тысяч компьютеров PDP-8.
1970 — Уинстон Ройс (Winston Royce) написал статью «Управление разработкой больших программных систем», в которой описывалась каскадная модель разработки.
1971 — фирма Intel выпустила микропроцессор 4004.
1974 — фирма Intel выпустила микропроцессор 8080.
1977 — фирма Apple выпустила первый серийный персональный компьютер Apple II.
1979 — фирма Motorola выпустила 16-битный микропроцессор 68000.
1980 — Бьёрн Страуструп (Bjarne Stroustrup) разработал язык программирования C, добавив к нему возможность работы склассами (чтобы сделать похожим на язык Simula).
1980 — Алан Кей (Alan Kay) изобрел объектно-ориентированный язык Smalltalk.
1981 — фирма IBM выпустила первый массовый персональный компьютер IBM PC.
1983 — фирма Apple выпустила первый персональный компьютер Macintosh, имеющий 128 Kбайт памяти.
1983 — Бьёрн Страуструп переименовал C с классами в C++.
1985 — Министерство обороны США приняло каскадную модель в качестве официального стандарта разработки программного обеспечения (стандарт DOD-STD-2167A).
1986 — издательство Addison-Wesley выпустило книгу Бьёрна Страуструпа «Язык программирования C++».
1991 — издательство Benjamin/Cummings выпустило книгу Гради Буча (Grady Booch) «Объектно-ориентированный анализ и проектирование с примерами приложений».
1991 — Джеймс Гослинг (James Gosling) изобрел язык Java (изначально называвшийся Oak).
1991 — Гвидо ван Россум (Guido Van Rossum) придумал язык Python.
1995 — издательство Addison-Wesley выпустило книгу «Приемы объектно-ориентированного проектирования. Паттерны проектирования», написанную Эрихом Гаммой (Erich Gamma), Ричардом Хелмом (Richard Helm), Джоном Влиссидесом (John Vlissides) и Ральфом Джонсоном (Ralph Johnson).
1995 — Юкихиро Мацумото (Yukihiro Matsumoto) создал язык программирования Ruby.
1995 — Брендан Эйх (Brendan Eich) создал язык JavaScript.
1996 — компания Sun Microsystems выпустила первую официальную версию языка Java.
1999 — компания Microsoft придумала язык C# (сначала называвшийся Cool) и платформу .NET.
2000 — проблема 2000 года.
2001 — написан Agile Manifesto (манифест гибкой разработки программного обеспечения).
За период с 1970 по 2000 год тактовая частота компьютеров увеличилась на три порядка, плотность упаковки данных — на четыре, дисковое пространство, как и объем оперативной памяти, — на шесть-семь порядков. Причем если раньше за доллар можно было купить один бит оперативной памяти, то теперь — гигабит. Немыслимо представить, как изменилось аппаратное обеспечение, но даже если просто суммировать все вышеупомянутые мной вещи, можно сказать, что наши возможности возросли примерно на 30 порядков.
И все это чуть более чем через полвека после лекции Алана Тьюринга.
Сколько сейчас программистов? Сколько строк кода написано? Насколько хорош этот код?
Попытайтесь сравнить это с историей становления авиации. Видите сходство? Видите, как постепенно развивалась теоретическая часть, как энтузиасты шли на приступ и, бывало, терпели поражение, как понемногу рос профессионализм? Как десятилетиями люди не совсем понимали, что делают?
И теперь, когда от наших навыков зависит само существование нашего общества, есть ли среди нас Салленбергеры, которые сейчас так нужны? Подготовлены ли программисты, столь же квалифицированные, как современные пилоты авиакомпаний? Есть ли у нас профессионалы, в которых наверняка будет нужда?
Мастерство — это доскональное знание того, как получить отличный результат. Оно появляется как следствие хорошего обучения и богатого опыта. До недавнего времени в индустрии программного обеспечения не хватало ни того ни другого. Как правило, программисты недолго занимались написанием программ, поскольку рассматривали это занятие всего лишь как ступеньку на пути к руководящей работе. Соответственно, не многие из этих людей приобретали достаточный опыт, чтобы обучать программированию других. В довершение всего, количество новичков удваивается примерно каждые пять лет, в результате чего доля опытных программистов остается чрезвычайно низкой.
При таком подходе большинство программистов не осваивают принятые практики, стандарты и этику, то есть вообще не знакомятся с вещами, отвечающими за профессионализм. Все относительно короткое время их работы эти люди остаются необученными новичками. Неудивительно, что большая часть написанного ими кода не соответствует стандартам, плохо структурирована, небезопасна, содержит ошибки и в основном находится в ужасном состоянии.
В этой книге я хочу рассказать о стандартах, принятых практиках и этических нормах, то есть о вещах, которые, по моему мнению, должен знать и соблюдать каждый программист, чтобы постепенно приобрести необходимые в его профессии знания и навыки.
7 Если не брать в расчет Боинги 737 Max.
8 Уравнение с целыми коэффициентами.
9Dijkstra E.W. Go To Statement Considered Harmful // Communications of the ACM. 1968. № 3.
Что такое принятая практика? Это набор правил, состоящий из обязательной и произвольной частей. Обязательная часть — это то, что делает практику действенной; это причина ее существования. Произвольная часть придает практике форму и содержание. Без произвольной части практика существовать не может.
Например, хирург перед операцией моет руки. Понаблюдав за этим процессом, вы увидите, что мытье рук выполняется особым образом. Хирург не просто намыливает их под проточной водой, как это делает любой из нас. Он следует ритуальной процедуре, которая выглядит примерно так:
• взять соответствующее мыло;
• взять подходящую щетку;
• для каждого пальца сделать:
• десять движений по верхней стороне;
• десять движений по левой стороне;
• десять движений по тыльной стороне;
• десять движений по правой стороне;
• десять движений под ногтем;
• и т.д.
Обязательная часть практики должна быть очевидной. Хирург обязан иметь очень чистые руки. Но обратили ли вы внимание на произвольную часть? Почему движений десять, а не восемь или двенадцать? Зачем делить палец на пять областей? Почему не на три или на семь?
В данном случае все эти числа выбраны произвольно. Просто считается, что этого будет достаточно.
В этой книге я расскажу вам о пяти практиках профессиональной разработки программного обеспечения. Одним из них уже полвека. Другим всего пара десятков лет. Но все они показали свою полезность. Без них в сфере создания ПО было бы практически немыслимым само понятие профессионального мастерства.
Каждая из этих практик имеет собственные обязательные и произвольные элементы. В процессе чтения вы можете столкнуться с тем, что некоторые из этих практик покажутся вам необоснованными или ненужными. В этом случае попытайтесь понять, какие элементы — обязательные или только произвольные — вызывают это чувство. Не позволяйте произвольным элементам сбить вас с толку. Как только вы поймете сущность каждой практики, влияние произвольных элементов, скорее всего, уменьшится.
Скажем, в 1861 году Игнац Земмельвейс (Ignaz Semmelweis) опубликовал статью о необходимости мытья рук для врачей. Результаты его исследований ошеломляли. Он смог показать, что в случаях, когда перед осмотром беременных врачи тщательно мыли руки водным раствором хлора, смертность от родильной горячки, от которой в то время умирала каждая десятая женщина, падала практически до нуля.
Но врачи того времени, рассматривая предложенную Земмельвейсом практику, не смогли отделить обязательную часть от произвольной. Водный раствор хлора был произвольной частью. Суть практики заключалась в самом факте мытья рук. Но мыть их хлорной водой было неудобно, поэтому врачи отвергли саму идею.
Прошло много десятилетий, прежде чем они стали это делать.
В 1970 году, после статьи Уинстона Ройса каскадная разработка стала общепринятой практикой. Исправление этой ошибки заняло почти 30 лет.
К 1995 году специалисты в сфере программного обеспечения начали рассматривать другой, более поэтапный подход. Была предложена к рассмотрению методология Scrum, разработка, управляемая функциональностью (feature-driven development, FDD), метод разработки динамических систем (dynamic systems development method, DSDM) и методология Crystal. Но в целом в отрасли мало что изменилось.
В 1999 году издательство Addison-Wesley выпустило книгу Кента Бека Extreme Programming Explained10. Предложенная Беком концепция базировалась на идеях из вышеперечисленных подходов, добавляя к ним кое-что новое, а именно практики разработки.
Следующие два года энтузиазм по отношению к экстремальному программированию рос экспоненциально. Именно это и привело к Agile-революции. Экстремальное программирование по сей день остается наиболее определенным и наиболее полным из всех Agile-методов. Эта глава посвящена принятым в нем практикам разработки.
На рис. 1.1 вы видите жизненный цикл Рона Джеффриса, содержащий перечень практик XP. Я расскажу вам о четырех практиках, расположенных в центре, и об одной крайней слева.
Рис. 1.1. Практики экстремального программирования
В центре находятся такие практики, как разработка через тестирование (test-driven development, TDD), рефакторинг, простота проектирования и парное программирование (которое мы будем называть совместным программированием). В крайней левой позиции располагается наиболее технически и инженерно-ориентированная из коммерческих практик XP — пользовательское тестирование.
Это основополагающие практики профессиональной разработки программного обеспечения.
Разработка через тестирование — ключевая дисциплина. Без нее все остальные практики невозможны или бесполезны. Именно поэтому две следующие главы, в которых она описывается, занимают почти половину книги и наполнены техническими деталями. Такой подход может показаться вам несбалансированным. Более того, мне тоже так кажется. Я изо всех сил пытался понять, как с этим быть, но пришел к выводу, что подобный перекос возник как следствие ситуации в нашей отрасли. К сожалению, с этой практикой хорошо знакомо слишком маленькое количество программистов.
Практика разработки через тестирование определяет действия программиста вплоть до секунд. Ее невозможно применить заранее или постфактум. Ее нельзя не заметить, поскольку она пронизывает весь процесс. Ее не получится придерживаться частично. Вы или практикуете разработку через тестирование, или нет.
Суть TDD очень проста. Все начинается с маленьких циклов и тестов. Причем тесты всегда оказываются на первом месте. Они первыми пишутся. Они первыми приводятся в порядок. Они предшествуют любой задаче. При этом все задачи разбиты на мельчайшие циклы.
Время цикла измеряется не в минутах — в секундах. Оно измеряется в символах, а не в строках. Цикл обратной связи замыкается, едва открывшись.
Цель TDD — создать набор тестов, которому можно полностью доверять. Если этот набор тестов пройден, значит, при развертке кода можно чувствовать себя в безопасности.
Разработка через тестирование — самая обременительная и сложная из всех практик. Она обременительна, поскольку влияет на все остальные аспекты. С нее вы начинаете и ею заканчиваете. Она накладывает ограничения на все действия. Она поддерживает темп работы, невзирая на давление окружающей среды.
Сложность разработки через тестирование обусловлена сложностью кода. Для каждого варианта кода существует соответствующий вариант TDD. При этом тесты должны соответствовать коду, но не быть с ним связаны, должны охватывать почти все аспекты кода, но при этом выполняться за секунды. Разработка через тестирование — скрупулезно нарабатываемый и сложный навык, который осваивается с большим трудом, но дает потрясающие результаты.
Рефакторинг — это практика, позволяющая писать чистый код. Она трудно реализуема, а порой и невозможна без TDD11. Соответственно, получить чистый код без TDD сложно или невозможно.
Рефакторинг превращает плохо структурированный код в код с лучшей структурой, не меняя его поведения. Последняя часть здесь — самая важная. Именно неизменность поведения кода гарантирует, что даже после изменения его структуры он останется безопасным.
Хотя программные системы и деградируют со временем, в них предпочитают не вмешиваться из страха повлиять на их поведение. Наличие безопасного способа очистки позволяет привести код в порядок, остановив деградацию.
Как гарантировать, что улучшения не повлияют на поведение? С помощью тестов.
Практика рефакторинга также очень сложна, поскольку существует множество способов создания плохо структурированного кода, а значит, и множество стратегий его очистки. Более того, каждая из этих стратегий должна плавно и согласованно вписываться в цикл разработки через тестирование. Как видите, эти практики настолько тесно переплетены, что практически неразделимы. Сложно представить рефакторинг без TDD, а TDD без рефакторинга.
Жизнь на земле можно описывать на разных уровнях. Высший уровень — это экология, изучающая взаимодействие в рамках биосистем. Ниже находится физиология, изучающая внутреннюю механику жизни. Еще ниже — микробиология, рассматривающая клетки, нуклеиновые кислоты, белки и другие макромолекулярные системы. Те, в свою очередь, описываются химией, которая базируется на квантовой механике.
Если таким же способом рассматривать программирование, то TDD окажется аналогом квантовой механики. Рефакторинг будет соответствовать химии, а простота проектирования — микробиологии. На уровне физиологии у нас окажутся принципы SOLID, объектно-ориентированное проектирование и функциональное программирование, а на уровне экологии — архитектура.
Простота проектирования практически невозможна без рефакторинга. Ведь именно она выступает конечной целью рефакторинга, в то время как сам он является единственным практическим средством для достижения этой цели. Именно рефакторинг позволяет получить проект, состоящий из простых атомарных фрагментов, хорошо вписывающихся в более крупные структуры программ, систем и приложений.
Простота проектирования базируется на четырех несложных правилах, так что придерживаться данной практики легко. Однако, в отличие от TDD и рефакторинга, это неточная дисциплина. Здесь приходится опираться на рассуждения и опыт. Первый признак, по которому можно отличить выучившего правила новичка от понимающего принципы специалиста, — отличный результат. Майкл Физерс (Michael Feathers) назвал это чувствовать проект.
Практика совместного программирования отражена в искусстве работы в команде. Она включает в себя такие вещи, как парное или групповое программирование, анализ кода и мозговые штурмы. Совместное программирование предполагает участие вообще всех членов команды — как программистов, так и всех остальных. Это основной способ поделиться знаниями, обеспечить согласованность работы и объединить команду в функционирующее целое.
Совместное программирование — наименее техническая и наименее директивная из всех практик. Но порой она оказывается самой важной, поскольку создать эффективную команду очень непросто, и это большая ценность.
Практика пользовательского тестирования связывает команду разработчиков программного обеспечения с его заказчиками. Перед разработчиками стоит цель — обеспечить поведение системы в соответствии с данной заказчиками спецификацией. Для проверки этого соответствия пишутся тесты. Успешное их прохождение означает, что система ведет себя так, как указано в требованиях.
Представители заказчика должны иметь возможность прочитать и понять эти тесты и внести в них коррективы. Наблюдение за процессом тестирования и участие в нем позволяют заказчикам убедиться, что программное обеспечение делает именно то, что от него требуется.
10Бек К. Экстремальное программирование. — СПб.: Питер.
11 Существуют и другие практики, так же хорошо, как TDD, способствующие выполнению рефакторинга. Например, предложенная Кентом Беком концепция TCR (test && commit || revert). Впрочем, на момент написания данного текста она не получила широкого распространения и интересна исключительно с академической точки зрения.
Рассказ о TDD занял у меня две главы. Сначала я подробно, с множеством технических деталей опишу вам основы данной разработки. В текущей главе вы пошагово познакомитесь с этой практикой. Вы найдете здесь множество фрагментов кода и ссылки на видеоролики.
В следующей главе я расскажу о ловушках и непонятных ситуациях, с которыми сталкиваются новички в TDD; я упомяну в том числе написание тестов для низкоуровневых компонентов, таких как базы данных и графические пользовательские интерфейсы. Вы познакомитесь с принципами и шаблонами проектирования тестов и узнаете о некоторых интересных и серьезных теоретических возможностях.
Ноль — очень важная цифра. Это значение равновесия. Когда оба плеча весов в равновесии, стрелка показывает ноль. Атом, в ядре которого количество электронов совпадает с количеством протонов, имеет нулевой заряд, то есть оказывается электрически нейтральным. Равна нулю и сумма сил, приложенных к находящемуся в состоянии покоя объекту. Ноль — число баланса.
Вы когда-нибудь задумывались, почему состояние расчетного счета в банке называют балансом? Дело в том, что это состояние представляет собой итог всех транзакций, всех снятий денег со счета и внесений их на счет. При этом в транзакции принимают участие две стороны, между которыми происходит перемещение денег.
Схематично это можно представить следующим образом: на ближней стороне ваш банковский счет, а на дальней — счет второго участника транзакции. Если на ближней стороне деньги вносятся на счет, значит, где-то на дальней стороне эта сумма снимается со счета. Каждый раз, когда вы выписываете чек, с вашего счета снимаются деньги и вносятся на какой-то другой. Сумма всех транзакций по счету и есть баланс. Сумма всех ближних и дальних сторон, участвовавших в транзакциях, должна быть равна нулю.
Две тысячи лет назад Гай Плиний Секунд, известный как Плиний Старший, реализовал эту формулу бухгалтерского учета, придумав принцип двойной записи. Этот принцип веками совершенствовался каирскими банкирами, а затем венецианскими купцами. В 1494 году друг Леонардо да Винчи монах-францисканец Лука Пачоли (Luca Pacioli) впервые подробно описал принцип двойной записи в своей книге. Печатный станок уже был изобретен, и это способствовало распространению информации.
В 1772 году, когда Европа столкнулась с суровой рецессией, Джозайе Веджвуду (Josiah Wedgwood) пришлось изрядно побороться за успех. Продукция его завода керамики перестала пользоваться спросом. Веджвуд ввел на предприятии бухгалтерский учет с двойной записью, чтобы понять, где рождается прибыль и как ее увеличить. Это позволило предотвратить надвигающееся банкротство и построить бизнес, который дожил до наших дней.
Веджвуд был не одинок. Индустриализация радикально изменила экономическую ситуацию в Европе и Америке. Как следствие, все больше и больше фирм начали использовать эту практику для управления денежными потоками.
Вот что писал в 1795 году Иоганн Вольфганг фон Гете в своем романе «Годы учения Вильгельма Мейстера»:
— Отбрось ее, швырни в огонь! — возопил Вернер. — Идея ее отнюдь не похвальна; этот опус претил мне с самого начала, а на тебя навлек неодобрение отца. Стихи, может, и складные, но изображение фальшивое. До сих пор помню твою дряхлую, немощную колдунью — олицетворение ремесла. Верно, ты набрел на этот образ в какой-нибудь убогой мелочной лавчонке. О торговом деле ты тогда понятия не имел; я же не знаю человека, чей кругозор был бы шире, должен быть шире, нежели кругозор настоящего коммерсанта. Сколь многому учит нас порядок в ведении дел! Он позволяет нам в любое время обозреть целое, не отвлекаясь на возню с мелочами. Какие преимущества дает купцу двойная бухгалтерия! Это одно из прекраснейших изобретений ума человеческого, и всякому хорошему хозяину следует ввести ее в свой обиход.
Сегодня двойная запись используется практически во всех странах. Эта практика в значительной степени лежит в основе профессии бухгалтера.
Но обратите внимание, какими словами Гете описывает так ненавистные ему средства «коммерции»:
До сих пор помню твою дряхлую, немощную колдунью — олицетворение ремесла. Верно, ты набрел на этот образ в какой-нибудь убогой мелочной лавчонке.
Вы когда-нибудь видели код, подходящий под это описание? Уверен, что да. У меня тоже есть такой опыт. И если вы работаете так же долго, как я, то вам явно доводилось в изобилии наблюдать такой код. И так же как я, вы написали огромное количество такого кода.
Теперь еще раз обратимся к словам Гете:
Сколь многому учит нас порядок в ведении дел! Он позволяет нам в любое время обозреть целое, не отвлекаясь на возню с мелочами.
Примечательно, что этими словами Гете описывает огромное преимущество, которое дает простая практика двойной записи.