среда, 29 июня 2011 г.

Паттерны поведения

(Эта заметка является завершением серии постов, в которую вошли «Технический долг», «Синдром рефакторинга» и «Эффект второй системы»)

В чем польза паттернов проектирования? (*) Это, прежде всего, повторное использование проверенных архитектурных решений, а также упрощение коммуникаций между разработчиками. Но ведь помимо паттернов проектирования существует и масса других паттернов: существуют паттерны кодирования, тестирования, модификации кода (a.k.a. рефакторинг), существуют архитектурные паттерны и многие другие. Поскольку мы, на самом деле, редко делаем что-либо по-настоящему новое, то проверенные типовые решения существуют для огромного количества областей. И поскольку большинство проблем, с которыми сталкиваются команды разработчиков, также не отличаются разнообразием, то и поведение этих людей также весьма однообразно.

«Технический долг», «синдром рефакторинга» и «эффект второй системы» - это типовые ситуации, с которыми периодически сталкивается команда разработчиков. И главная польза от них как раз и заключается в том, чтобы увидеть проблему и доказать ее существование нужным людям. Если вы сами поняли, что технический долг проекта слишком велик, то используя денежную метафору будет уже значительно проще доказать важность этой проблемы менеджеру или заказчику. А затем взвешенно показать ему альтернативные пути развития событий: (1) оставить все, как есть; (2) уменьшить технический долг путем разумного рефакторинга или (3) переписать все нафиг.

понедельник, 13 июня 2011 г.

Эффект второй системы

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

И хотя в классическом понимании «эффект второй системы» немного отличается от паталогической нелюбви к чужому коду и постоянному его переписыванию, оба эти случая имеют и что-то общее, так что имеет смысл оба эти симптома рассмотреть совместно.

четверг, 26 мая 2011 г.

Синдром рефакторинга

arch2 Бытует мнение, что программные системы, будучи объектом не совсем материальным, не поддаются старению. И если говорить о старении физическом, то действительно, шансы на то, что буковка “o” в имени класса вдруг от старости ссохнется и превратится в букву “c” – действительно малы. Но вместо старения физического, программные системы стареют морально.  Со временем накапливается груз ошибок за счет неточностей в исходных требованиях, непонимания требований самим заказчиком, архитектурных ошибок или неудачных компромиссных решений; да и ошибки поменьше, типа слабопонятного кода, его высокой связности, отсутствия юнит-тестов и комментариев делают свое черное дело. Все это приводит к накоплению технического долга (о котором шла речь в прошлый раз), из-за которого при добавлении новой возможности в систему приходиться платить «проценты» в виде более высокой стоимости реализации и более низкого качества получаемого результата.

среда, 18 мая 2011 г.

Технический долг

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

При этом самым сложным при выборе того или иного решения является «коммуникация» своего выбора непосредственному руководителю, чтобы он смог принять взвешенное решение. А поскольку с точки зрения большинства руководителей «взвешивание» заканчивается сразу же после того, как он услышит сроки реализации, то «коммуникация» заканчиваются примерно через 37 секунд после ее начала (обычно именно столько времени нужно руководителю, чтобы узнать ответ на очень простой вопрос, выражаемый одним словом: «Когда?»)

Не удивительно, что многие простые программисты, матерые лиды и архитекторы, а иногда даже ПМ-ы, которые понимают, что им самим придется расхлебывать проблемы «близоруких» решений, с таким подходом не согласны. И совершенно не удивительно, что с подобной проблемой сталкивались и другие известные и не очень люди, которые придумали типовые «паттерны», описывающие подобную ситуацию. Одним из таких паттернов, является метафора технического долга, впервые описанная Вардом Каннингемом (Ward Cunningham) (*) без малого двадцать лет назад.

пятница, 13 мая 2011 г.

О книге Марка Руссиновича “Zero Day: A Novel”

В прошлом обзоре новинок компьютерной литературы помимо чисто компьютерных книг была и одна художественная. Это было связано с тем, что автором этой книги является небезызвестный товарищ в компьютерном мире по имени Марк Руссинович (Mark Russinovich), Microsoft Technical Fellow, основатель компании Sysinternals, автор нескольких книг, множества статей по WinAPI и компьютерной безопасности, да и вообще известный парень в не таких уж и узких кругах.

За время, прошедшее с той публикации, я познакомился с творением Марка поближе, так что теперь я могу рассказать о его кибер-триллере более подробно.

вторник, 10 мая 2011 г.

DynamicXml: “динамическая” оболочка для работы с XML данными

Я уже однажды писал о том, что, несмотря на мою любовь к статической типизации, в некоторых сценариях преимущества от той свободы, которую дает динамическая типизация, может превосходить связанные с ней недостатки. В прошлый раз шла речь о Dynamic LINQ, а в этот раз речь пойдет об использовании новой возможности C# 4.0 под названием dynamic, для работы с такими исходно слаботипизированными данными, как XML.

ПРИМЕЧАНИЕ
Исходный код библиотеки DynamicXml, рассматриваемой в данной статье, доступен на
github.

Введение

Начиная с версии 4.0, в языке C# появилась поддержка динамического программирования, благодаря новому статическому типу под названием dynamic. По сути, применение этого ключевого слова говорит компилятору сгенерировать весь необходимый код, чтобы процесс привязки (binding) и диспетчеризации вызовов (dispatch operations) производился во время выполнения, вместо определения всех этих характеристик во время компиляции. При этом компилятор генерирует весь необходимый код с помощью библиотеки DLR – Dynamic Language Runtime (*), которая была изначально создана при проектировании языка программирования Iron Python и впоследствии вошла в состав .Net Framework 4.0, как основа для реализации динамических языков программирования, а также для взаимодействия между ними.

четверг, 28 апреля 2011 г.

Дизайн ревью

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

Постановка задачи

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

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