вторник, июня 05, 2007

Принцип DRY

Про принцип DRY все знают. Ну даже если кто-то и не знает самого сокращения, то уж смысл известен наверняка. Напомню, DRY расшифровывается как Don't Repeat Youself. То есть "Не повторяй самого себя". Первый раз с самим сокращением я столкнулся в книге The Pragmatic Programmer: From Journeyman to Master. На самом деле принцип все мы знаем очень давно, даже если не осознавали его как "принцип" или что-то глубоко умное и философское (в Википедии принцип относится к категории Software Development Philosophies).

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

Ну то есть пиши функцию (или класс) и пользуйся ею, а не пытайся сделать в разных местах одно и тоже заново.

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

Тем не менее, во многих случаях следование этому принципу сильно может облегчить жизнь программистам работающим над проектом. Сузим немного область применения принципа (авторы указывают что его можно применять буквально ко ВСЕМ составляющим ПО - не только исходному коду, но и документации, системам сборки, требованиям и так далее).

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

Откуда берутся такие ошибки? Кто в них виноват?

Программисту, которому необходимо добавить новое поле в диалог плюётся "Вот "@#$%^&*! Ну кто так пишет! И диалога два, и поведение в них чуть-чуть разное и по разным принципам они написаны, и сопутствующие классы разные!" После этого он открывает историю в системе контроля версий, смотрит фамилию предшественника и ... Ну сами понимаете. Тут уж предшественнику вполне может достаться по первое число. Зачем скопировал? Почему все то же самое, но чуть-чуть по-другому?

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

А потом наступает момент когда кому-то нужно добавить в диалог ещё одно поле.

Виноват ли наш гипотетический программист? Или может быть виноват "самый первый" программист - тот кто из одного диалога сделал два? Зачем он так сделал?

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

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

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

Поэтому в следующий раз, если увидите две разных реализации одного и того же не торопитесь ругать программиста.

Комментариев нет: