97 этюдов для программистов. Опыт ведущих экспертов - Пит Гудлиф
Мастерство растет постепенно, а не возникает скачком после 10-тысячного часа! Однако 10000 часов — это серьезно: примерно 20 часов в неделю в течение 10 лет. Требуется такое упорство, что вы можете усомниться, получится ли из вас эксперт.
Получится. Величие есть по преимуществу вопрос сознательного выбора. Вашего выбора. Исследования последних двадцати лет показывают, что главным фактором приобретения компетенции является время, потраченное на целенаправленную тренировку. Врожденные способности — не главный фактор. Вот что пишет Мэри Поппендик:
Многие исследователи высших профессиональных достижений сходятся в том, что врожденный талант является всего лишь фиксированной отправной точкой: нужны какие-то минимальные природные способности, чтобы начать заниматься спортом или определенной профессиональной деятельностью. Начиная с этого порогового значения, преуспевают те, кто трудится упорнее всего.
Нет смысла осознанно практиковаться в том, что вы и так умеете делать мастерски. Осознанной тренировкой мы развиваем то, что умеем недостаточно хорошо. Питер Норвиг пишет:
Ключ [к достижению мастерства] — осознанная практика: не просто многократное повторение одного и того же, но смелость взяться за задачу, которая несколько превышает ваши нынешние способности, попытаться ее решить, анализировать эффективность своих действий во время и после работы над решением, а также исправить допущенные ошибки.
А Мэри Поппендик пишет:
Осознанная практика — это не повторение того, что вы уже умеете; это выбор сложной задачи, попытка заняться тем, в чем вы не вполне компетентны. Нельзя рассчитывать, что это будет приятное времяпрепровождение.
Осознанная практика — это учеба, которая изменяет вас, изменяет ваше поведение. Удачи.
Предметно-ориентированные языки
Микаэль Хунгер
Если прислушаться к разговору экспертов в какой-либо области, будь то игроки в шахматы, воспитатели детского сада или страховые агенты, можно заметить, что их лексика существенно отличается от повседневной. Отчасти такова причина появления предметно-ориентированных языков (domain specific language, DSL): у каждой предметной области есть собственный специализированный словарь для описания явлений, присущих этой области.
Если говорить о программировании, DSL представляют собой выполняемые выражения на языке, присущем предметной области. Выражения языка строятся на ограниченном словаре и грамматике, так что специалисты в данной предметной области способны читать и понимать выражения на этом языке, а в идеале еще и писать собственные. Языки DSL, ориентированные на разработчиков и ученых, существуют уже довольно давно. Достаточно древними примерами могут послужить «малые языки» настроечных файлов UNIX, а также языки на базе мощных макросов LISP.
Обычно DSL делятся на встроенные и независимые:
Встроенные DSL
Создаются на универсальных языках программирования, синтаксис которых подогнан под структуры естественного языка. Проще всего делать это с языками, предоставляющими широкие возможности для синтаксического украшательства и гибкого форматирования (например, Ruby и Scala), тогда как с другими все сложнее (например, Java). Большинство встроенных DSL — суть обертки существующих API, библиотек и бизнес-логики. Они снижают входной порог применения уже существующей функциональности. Приложения на встроенных DSL можно запускать как обычные приложения. В зависимости от реализации и предметной области они могут использоваться для наполнения структур данных, описания зависимостей, запуска процессов или задач, сообщения с другими системами или проверки корректности вводимых пользователями данных. Синтаксис встроенного DSL ограничен возможностями базового языка. Существует множество шаблонов — например построитель выражений, цепочка методов, аннотация — для подгонки базового языка к нужному DSL. Если базовый язык не требует перекомпиляции, встроенный DSL при тесном взаимодействии с экспертом в предметной области можно создать достаточно быстро.
Независимые DSL
Представляют собой текстовое или графическое описание языка, причем текстовые DSL встречаются чаще графических. Текстовые выражения могут проходить обработку в цепочке, включающей в себя лексический анализатор, анализатор синтаксиса, преобразователь модели, генераторы и любые другие средства постобработки. Как правило, выражения не независимых DSL преобразуются во внутренние модели, служащие основой для дальнейшей обработки. Полезно определить грамматику (например, в виде РФБН[10]). Грамматика служит отправным пунктом для создания элементов инструментальной цепочки (например, редактора, визуализатора, генератора анализаторов синтаксиса). Для простых DSL может оказаться достаточно анализатора синтаксиса, созданного вручную — например, на основе регулярных выражений. Если требования к анализатору синтаксиса достаточно сложны, созданный вручную анализатор синтаксиса может стать слишком громоздким, и следует обратить взор на такие инструменты для работы с грамматиками и DSL, как openArchitectureWare, ANTLR, SableCC, AndroMDA. Довольно часто независимые DSL определяют в виде диалектов XML, но с чтением в этом случае могут быть сложности, особенно у неспециалистов.
Всегда следует принимать во внимание целевую аудиторию вашего DSL. Из кого она состоит — из разработчиков, менеджеров, клиентов или конечных пользователей? В зависимости от целевой аудитории нужно выбирать технический уровень языка, доступные пользователю функции, инструмент для подсказки по синтаксису (например, IntelliSense), средства ранней валидации, визуализации и представления. Скрывая технические детали, DSL отдает власть пользователям, предоставляя им возможность адаптировать системы к собственным потребностям, не прибегая к помощи разработчиков. DSL позволяет еще и увеличить скорость разработки благодаря распределению задач после того, как создан начальный каркас языка. Язык может развиваться постепенно. Существуют также различные способы перевести существующие языки и грамматики на новый DSL.
Не бойтесь что-нибудь сломать
Майк Льюис
Каждый поработавший в нашей отрасли наверняка встречался с проектом, код которого внушал опасения. Части такой системы сильно взаимосвязаны, и изменение кода одной функции почему-то приводит к нарушению работы совсем другой. При добавлении нового модуля приходится ограничиваться минимальными изменениями и, затаив дыхание, ждать последствий. Это все равно что играть в дженгу перекрытиями небоскреба — однозначно ведет к катастрофе.
Внесение изменений так изматывает нервы только потому, что система больна. Она нуждается в лечении, иначе ее состояние будет лишь ухудшаться. Вы знаете, в чем пороки системы, но боитесь принять решительные меры. Опытный хирург знает, что необходимо сделать разрезы, чтобы провести операцию, но он знает также, что разрезы временные и потом заживут. Результат операции оправдывает перенесенные страдания, и состояние пациента должно стать лучше, чем до хирургического вмешательства.
Не бойтесь своего кода. Кому какое дело, что код не работает в процессе работы над ним? Именно боязнь перемен и привела ваш проект к нынешнему жалкому состоянию. Потраченное на рефакторинг время многократно окупится в течение жизненного цикла вашего проекта. Да к тому же переработка нездоровой системы