понедельник, 19 декабря 2011 г.

Стабы и моки

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

Это самый простой и эффективный способ тестирования, и любой толковый дизайн отталкивается от подобных классов, которые являются «строительными блоками» нижнего уровня, на основе которых затем уже строятся более сложные абстракции. Но количество классов, которые живут в такой «изоляции» не много по своей природе. Даже если мы по нормальному выделили всю логику по работе с базой данных (или сервисом) в отдельный класс (или набор классов), то рано или поздно появится кто-то, кто эти классы будет использовать для получения более высокоуровневого поведения и этого «кого-то» тоже нужно будет тестировать.

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

вторник, 29 ноября 2011 г.

Кто такой “хороший программист”?

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

Что отличает хорошего программиста от посредственного? И как самому стать хорошим программистом и заслужить среди друзей и коллег «почет и уважение»?

среда, 23 ноября 2011 г.

Идеальная архитектура

Существует много разных взглядов на разработку архитектуры и дизайна современных приложений. Некоторые архитекторы стремятся продумать все до мелочей, разрисовать use case-ы всех классов и модулей, проанализировать миллион возможных способов их использования, все их обязательно задокументировать и уже потом приступить к этапу кодирования.

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

среда, 9 ноября 2011 г.

Observable.Generate и перечисление списков

В библиотеке реактивных расширений (a.k.a. Rx – Reactive Extensions) существует вспомогательный метод Observable.Generate, который позволяет генерировать простые observable-последовательности.

IObservable<string> xs = Observable.Generate<int, string>(     
initialState: 0, // начальное значение
     condition: x => x < 10, // условие завершения генерации
     iterate: x => x + 1, // изменение значения
     resultSelector: x => x.ToString() // преобразование текущего значения в результат
     ); xs.Subscribe(x => Console.WriteLine("x: {0}", x));

четверг, 3 ноября 2011 г.

Повторная генерация исключений

Обработка исключений появилась в mainstream языках программирования вот уже более трех десятилетий назад, но сегодня все еще можно встретить разработчиков, которые боятся их использовать. Некоторые считают, что генерация исключений в конструкторе повредит их хрупкой карме и их настигнет кара в виде поддержки кода двадцатилетней давности, написанного стадом безумных индусов. Некоторые все еще застряли в эпохе языка С и даже в языке C# интенсивно используют коды возврата в виде магических чисел или даже строк, считая, что исключения придумали трусы, а настоящие самураи могут обойтись и без них. (Хотя мы-то с вами знаем, что настоящие самураи следуют “Принципу самурая” и никаких кодов возврата не используют).

Дополнительную сложность добавляют конкретные платформы и языки программирования. Сегодня на собеседовании C# разработчика, когда речь заходит об обработке исключений, обязательно прозвучит вопрос: “А в чем отличие “проброса” исключения с помощью конструкций throw; и throw ex;?”. И хотя, это страшный баян и большинство разработчиков давно знают правильный ответ на этот вопрос, в реальном коде встретить “некошерный” вариант очень даже просто.

Особенность платформы .NET заключается в том, что в ней не существует (а точнее, как мы вскоре увидим – не существовало) способа перехвата исключения в одном месте и последующего его генерирования в другом. Если разработчик бизнес-приложения или библиотеки сталкивался с такой задачей, то решалась она очень простым способом: исходное исключение заворачивалось в другой объект в виде вложенного исключения и пробрасывалось уже новое исключение.

среда, 26 октября 2011 г.

Проблемы передачи списка перечислений или Почему абстракции «текут»

Все нетривиальные абстракции дырявы
Джоэл Спольски – Закон дырявых абстракций

А иногда дырявятся и довольно простые абстракции
Автор этой статьи

Большинство современных разработчиков знакомы с «законом дырявых абстракций» по знаменитой заметке Джоэла Спольски с одноименным названием. Заключается этот закон в том, что как бы ни был хорош протокол взаимодействия, фреймворк или набор классов, моделирующих предметную область, рано или поздно нам приходится спускаться на уровень ниже и разбираться с тем, как же эта абстракция устроена. Внутреннее устройство абстракции должно быть проблемой самой абстракции, но возможно это только в наиболее общих случаев и лишь до тех пор, пока все идет хорошо (*).

Когда-то давно, в «небольшой» мелкомягкой компании решили, а почему бы нам не «абстрагироваться» от местоположения объекта и сделать сам факт того, является ли объект локальным или удаленным, лишь «деталью реализации». Так появились технологии DCOM и ее наследник .NET Remoting, которые скрывали от разработчика, является ли объект удаленным или нет. При этом появились все эти «прозрачные прокси», которые позволяли работать с удаленным объектом, даже не зная об этом. Однако, со временем выяснилось, что эта информация архиважна для разработчика, поскольку удаленный объект может генерировать совершенно другой перечень исключений, да и стоимость работы с ним несравнимо выше, чем взаимодействие с локальным объектом.

среда, 12 октября 2011 г.

Доклады по асинхронному и реактивному программированию

На следующей неделе я проведу два семинара (или доклада, если хотите) в Киеве.

вторник, 27 сентября 2011 г.

Dispose pattern

“Не стоит следовать некоторой идиоме только потому, что так делают все или так где-то написано”
Мысли автора статьи во время чтения и рефакторинга чужого кода

Ни для кого не будет секретом, что платформа .NET поддерживает автоматическое управление памятью. Это значит, что если вы создадите объект с помощью ключевого слова new, то вам не нужно будет самостоятельно заботиться о его освобождении. Сборщик мусора определит «достижимость» объекта, и если на объект не осталось корневых ссылок, то он будет освобожден. Однако, как только речь заходит о ресурсах, таких как сокет, буфер неуправляемой памяти, дескриптор операционной системы и т.д., то сборщик мусора, по большому счету, умывает руки и весь головняк по работе с такими ресурсами ложится на плечи разработчика.

А как же финализаторы? – спросите вы. Ну, да, есть такое дело, финализаторы действительно предназначены для освобождения ресурсов, но проблема в том, что время их вызова не детерминировано, а это значит, что никто не знает, когда они будут вызваны и будут ли вызваны вообще. Да и порядок вызова финализаторов не определен, поэтому при вызове финализатора некоторые «части» вашего объекта уже могут быть «разрушены», поскольку их финализаторы уже были вызваны. В общем, финализаторы – они-то есть, но это скорее «страховочный трос», а не нормальное средство управления ресурсами.

понедельник, 19 сентября 2011 г.

Google+

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

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

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

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

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

P.S. Ну, а кто на гуглоплюсе еще не зарегистрирован и нужен инвайт (там, кажется, он все еще нужен) – пишите, вышлю.

вторник, 13 сентября 2011 г.

Принцип самурая

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

Еще одной метафорой, или скорее принципом разработки, является «принцип самурая», призванный описать «контракт» между функцией и вызывающим ее кодом и заключается в следующем. Любая функция, реализующая некоторую единицу работы должна следовать тому же кодексу чести «бусидо», по которому живет любой самурай. Так, самурай не будет выполнять никаких заданий, противоречащих его «кодексу чести» и если к нему подойти с «непристойным» предложением, то он снесет вам башку раньше, чем вы успеете глазом моргнуть. Но если уж самурай возьмется за дело, то можно быть уверенным в том, что он доведет его до конца (**).

понедельник, 5 сентября 2011 г.

Вы, конечно, шутите, мистер Фейнман

feynman_schytite_317_449_1

Мое знакомство с мистером Фейнманом началось с перевода статьи Эрика Липперта «Что бы сделал мистер Фейнман». В этой замечательной заметке в виде шуточного рассказа приведены ответы на «нестандартные вопросы», так любимые некоторыми «мелкомягкими» компаниями при отборе кандидатов на работу. А поскольку мистер Фейнман всегда любил «нестандартные вопросы» и давал на них еще менее «стандартные ответы», то интервью получилось веселым и, как я узнал позднее, очень похожим на неопубликованную главу из книги «Вы, конечно, шутите, мистер Фейнман».

Сама же книга представляет собой сборник забавных и трогательных историй о жизни «простого» человека, по имени Ричард Филлипс Фейнман, самым незначительным достижением которого (по его собственному разумению) было получение Нобелевской премии по физике. Это книга о замечательном человеке, умном, талантливом, упрямом; человеке, у которого жажда познаний, экспериментов и решения разных головоломок была практически безграничной.

понедельник, 29 августа 2011 г.

Wanted! Старые хиты Эрика Липперта

Если вы, вдруг не знали, то помимо всякой ерунды, публикуемой на этом блоге, я еще и занимаюсь переводом блога Эрика Липперта (Eric Lippert) Fabulous Adventures in Coding на русский язык. В русскоязычном варианте этот блог носит название Невероятные приключения в коде.

Занимаюсь я этим делом вот уже полтора года и не разу не пожалел потраченного времени. Я надеюсь, что чтение статей Эрика на русском языке доставляет хоть малую толику того удовольствия, которое я получаю при переводе!

Но сегодня я не об этом. Точнее не совсем об этом. Мы начали публиковать переводы, датированные апрелем 2009-го года, но, как это ни удивительно, до этого Эрик писал не менее часто и не менее интересно. Посему я предлагаю вернуться к его старым хитам и восстановить, так сказать, справедливость и перевести на русский язык и их.

четверг, 25 августа 2011 г.

Неявно типизированные поля в C#

Сегодня на кывте был задан очередной весьма интересный вопрос о том, почему в языке C# существуют неявно типизированные локальные переменные (implicitely-typed local variables) a.k.a. var, но нет неявно типизированных полей?

На самом деле, такое положение дел вовсе не случайно; так что давайте рассмотрим несколько причин, почему компилятор ведет себя именно так, а не иначе.

Во-первых, возможность использовать var, для объявления неявно типизированных локальных переменных, никогда не была самостоятельной возможностью. При разработке языка C# никто не ставил перед собой цели создать полностью неявно типизированный язык программирования, типа F#; неявная типизация была лишь одной составляющей (пусть и немаловажной) более общей концепции, известной сегодня под аббревиатурой LINQ.

вторник, 23 августа 2011 г.

О книге “MS Visual C++ 2010 в среде .NET. Библиотека программиста”

Если посмотреть на мои обзоры книг (*), то может возникнуть подозрение в предвзятости, поскольку отзывы либо положительные, либо восторженные. Объясняется эта ситуация довольно просто: прежде чем браться за чтение книги разумно совершить «разведку боем» и выяснить, насколько чтение той или иной книги полезно и актуально. Если отзывы на книгу хорошие, автор внушает доверие, а тема интересна, то есть все шансы на то, что и вы не пожалеете о потерянном времени. Если же отзывы сугубо отрицательные и за версту тянет стилем изложения «Для чайников» в самом плохом смысле этого слова, то и время на такую книгу тратить не стоит.

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

среда, 17 августа 2011 г.

Effective Concurrency от Герба Саттера

Герб Саттер, если вдруг кто не знает, это гуру С++ и многопоточности, автор нескольких весьма популярных книг и сотни известных статей, главный дизайнер языка C++/CLI и всяких там многопоточных расширений, в общем, крут парень, ничего не скажешь.

Но именно в данном случае интересно не это. Сегодня я отправил Гербу мыло с просьбой разрешить перевод и публикацию у себя в блоге его серии статей Effective Concurrency, и получил от него ответ через 40 (!) минут. То что ответ был отрицательным, это уже второе, но сам факт, что такие люди отвечают столь оперативно не может не радовать.

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

Так что у нас, как всегда, две новости: одна хорошая, другая – не очень. Хорошая новость заключается в том, что Герб отличный парень и у нас скоро будет его новая книга, ну а плохая – что это “скоро” наступит не раньше следующего года.

Дополнительные ссылки

понедельник, 15 августа 2011 г.

Гарантии безопасности исключений

Ошибки в обработке ошибок являются наиболее распространенным источником ошибок
Бредня, пришедшая в голову при написании этой статьи

Основные баталии по поводу того, что лучше использовать при программировании на C# – исключения или коды возврата для обработки, ушли в далекое прошлое (*), но до сих пор не утихают баталии другого рода: да, хорошо, мы остановились на обработке исключений, но как же нам их обрабатывать «правильно»?

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

Существует множество «за» и «против» такого способа перехвата и обработки исключений, но сегодня я хочу рассмотреть несколько другую тему. А именно тему обеспечения согласованного состояния приложения в свете возникновения исключения – три уровня безопасности исключений.

понедельник, 1 августа 2011 г.

О синглтонах и статических конструкторах

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

-------------------------

Любая реализация паттерна Синглтон в общем случае преследует две цели: во-первых, реализация должна быть потокобезопасной, чтобы предотвратить создание более одного экземпляра в многопоточном мире .Net; а во-вторых, эта реализация должна быть «отложенной» (lazy), чтобы не создавать экземпляр (потенциально) дорого объекта раньше времени или в тех случаях, когда он вообще может не понадобиться. Но поскольку основное внимание при прочтении любой статьи про реализацию Синглтона отводится многопоточности, то на «ленивость» зачастую не хватает ни времени не желания.

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

О вреде изменяемых значимых типов

Большинство программистов, которых нелегкая судьба свела с платформной.Net знают о существовании значимых типов (value types) и ссылочных типов (reference types). И довольно многие из них прекрасно знают, что помимо названия, эти типы имеют и другие различия, такие как расположение объектов оных типов в памяти, а также в семантике.

Что касается первого различия (о котором стоит упомянуть как минимум ради полноты изложения), то оно заключается в том, что экземпляры ссылочных типов всегда располагаются в управляемой куче, в то время как экземпляры значимых типов по умолчанию располагаются в стеке, но могут мигрировать в управляемую кучу вследствие упаковки, будучи членами ссылочных типов, а также при использовании их в хитрых экзотических конструкциях языка C#, типа замыканий (*).

Хотя это отличие является очень важным и именно благодаря нему значимые типы существуют и используются, у этой пары типов есть еще одно, не менее важное семантическое различие. Значимые типы, как подсказывает название, являются значениями, которое копируется каждый раз при передаче в функцию или при возвращении из нее. А поскольку при копировании, как, опять же, подсказывает название, передается и возвращается не исходный вариант, а копия, то все попытки изменений приведут к изменению копии, а не исходного экземпляра.

четверг, 7 июля 2011 г.

Семинар по асинхронному программированию в .Net

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

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

Семинар, по сути, был основан на основе двух моих статей по асинхронному программированию: “Асинхронное программирование и AsyncEnumerator” и “Знакомство с асинхронными операциями в C# 5”, а также статьи про внутреннее устройство итераторов: “Итераторы в языке C#”. Реактивные расширения, которые я тоже собрался рассмотреть, решительно не влезли; на рассмотрение только лишь RX-ов двух часов будет мало, так что я решил не распыляться.

В результате получилась презентация на 50 слайдов, примерно со следующей структурой:

среда, 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# мы отложим на следующий раз, а сейчас сосредоточимся исключительно на дизайне.

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

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

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

воскресенье, 17 апреля 2011 г.

С юбилеем, RSDN!

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

- Ничего, Серега, еще годик-другой поработаешь, и отношение к работе у тебя изменится.

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

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

Классические книги по C#/.NET

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

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

понедельник, 11 апреля 2011 г.

Как не надо писать код

По статистике мы значительно чаще читаем код, чем пишем новый. Этот код может быть своим, а может быть чужим, это может быть ревью чужого кода пред коммитом, а может быть вам дали задачу добавить новую возможность, пофиксить багу или просто разобраться в логике существующей системы. Отношение к коду, как чему-то очень важному совсем не ново, об этом написаны десятки книг и, наверное, сотни статей; но практика показывает, что обилие информации по этой теме никак не влияет на качество существующего кода в реальных системах. На практике все чаще слышишь, «вот дали бы побольше времени, вот тогда бы я все сделал как нужно, никакого г#$@о-кода бы не было» или «ладно, вот эту заплатку я делаю последний раз, а вот потом я вернусь и все исправлю».

Недавно на rsdn.ru был задан вопрос, а точнее поднято обсуждение того, как не нужно писать код, и автор этого обсуждения привел пример, который это отлично демонстрирует. Поскольку я потратил некоторое время на написание ответа, то решил его немного облагородить и добавить некоторые мысли, которые посещают мою голову, когда я сам сталкиваюсь с подобным кодом, и выложить все это дело здесь.

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

Рецензия на книгу Джона Скита “C# in Depth”, 2nd Edition

CSharp_In_Depth

В последнее время я все чаще и чаще слышу от своих коллег о том, что язык C# двигается куда-то не туда. Новые возможности в нем появляются слишком быстро, мы тут, дескать, предыдущие еще не освоили, а бравые ребята из Редмонда успели новые навыдумывать, да еще и парадигмы новые к нему прикручивают. Фич в языке уже столько, что их ни в одну нормальную голову уже не впихнуть; мало того, что их много, так с некоторыми еще и без бутылки (без спецификации) не разобраться. Да и вообще, какой-то второй С++ получается, осталось добавить undefined behavior в десяток мест спецификации и мы получим чудище, аналогичное детищу Страуступа.

И хотя во всех этих высказываниях некоторая доля правды все-таки есть, зачастую такие вопросы возникают из-за отсутствия в голове целостной картины и понимания того, чем является и чем не является язык C#, какие в нем существуют возможности и как они взаимодействуют с другими возможностями языка; какие существуют идиомы и типичные способы использования тех или иных языковых конструкций.

воскресенье, 3 апреля 2011 г.

О книге Барта де Смета “C# 4 Unleashed”

C# 4.0 Unleashed Знаете ли вы парня по имени Барт де Смет (Bart de Smet)? Нет? Напрасно. Это автор весьма популярного (*) блога B# .NET BLOG, в котором он пишет всякие умности по разным темам, связанным с языком C# и платформой .Net, причем делает это очень подробно, углубляясь в такие дебри, из которых не всегда удается выбраться, не повредив свое хрупкое ментальное здоровье. Зная его стиль изложения, каково же было мое удивление, когда я обнаружил, что этот парень написал книгу по языку C#. Нет, сам факт написания книги таким человеком меня ни сколько не удивил, меня удивило сочетание двух не слишком совместимых до этого понятий: объема в 1650 (!) страниц и глубины изложения. Я, конечно, понимаю, что товарищ Кнут накрапал побольше, да и фундаментальность темы с глубиной изложения у него не подкачали, но, во-первых у него ушло на это несколько десятков лет, ну а во-вторых, сравнивать кого бы то ни было с Кнутом вообще не честно.

суббота, 2 апреля 2011 г.

Visual C# MVP

MVPLogo Я честно вчера хотел рассказать о новой замечательной книге по языку C#, о которой я упоминул в конце предыдущего поста, но мой провайдер отлично пошутил и вырубил интернет на полдня.  Ну а вечером, когда интернет появился, я получил письмо от Майкрософт, в котором говорилось, что я получил MVP Award в разделе Visual C# (сегодня я все еще могу залогиниться на сайт www.mvpaward.com, значит это была не первоапрельская шутка). Так что рассказ об этой таинственной книге по языку C# откладывается еще на день.

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

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

UPDATE: ссылка на мой профиль

-------------------------------------

(*) Да, я знаю, что уже накомпилось пять сообщений Эрика, которые нужно перевести. Но перевод даже не злых с точки зрения лексики статей требует не малого количества времени, но на этих выходных я их обещаю добить.

среда, 30 марта 2011 г.

[ANN]ounce книг 3’2011

Уже прошло достаточно времени с момента последнего книжного анонса, так что за это время накопилось достаточно новинок, о которых мне бы хотелось рассказать, а широкой общественности, надеюсь, об этом услышать. Формат анонса остается неизменным, я подобрал несколько книг, выпущенных отечественными и иностранными издательствами за последнее время, с которыми я немного познакомился. Степень моего знакомства с этими книгами, как обычно может отличаться в значительных пределах, от «я редактировал перевод этой книги на русский язык, так что я знаком с ней очень хорошо» до, «вот блин, классная тема книги и отзывы отличные, обязательно добавлю в свой бесконечный список книг, которые я хочу прочитать». Так что по каждой конкретной книге принимать решение вам самим, но можно с уверенностью сказать, что каждая из приведенных ниже книг, как минимум, достойна вашего внимания.

Фриман и др. Паттерны проектирования. Питер 2011

untitled

(Оригинал: Freeman et al. Head First Design Patterns. O’Reilly Media, 2004)

понедельник, 28 марта 2011 г.

Проблемы запуска .Net приложений под 64-битными ОС

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

Итак, программирование на платформе .Net делает еще один шаг по отделению прикладного программиста от всяких низкоуровневых платформенно-зависимых вещей типа размеров указателя, выравнивания, размеров целочисленных типов данных и других проблем, характерных для программирования на неуправляемых С/С++. Теперь все становится значительно проще и компиляторы таких языков программирования как C# или VB.Net не генерируют ассемблерные инструкции напрямую (хотя такая возможность и присутствует), вместо этого, результатом компиляции является код на промежуточном языке программирования, который затем компилируется во время выполнения JIT-компилятором в набор инструкций для конкретной платформы.

понедельник, 21 марта 2011 г.

Визуализация деревьев выражений с помощью TeX

Для затравки. Хотите узнать, как из вот такого выражения на языке C#:

Expression<Func<double>> bondPriceValueExpression = 
    () => C * ((1 - Math.Pow(1 + i, -n)) / i) + M / Math.Pow(1 + i, n);

Получить вот такую картинку:

BondPrice

Если это так, то милости прошу под кат.

понедельник, 14 марта 2011 г.

Частичные классы

Частичные классы (partial classes) (*) – это весьма простая конструкция языка C#, которая позволяет определить один класс в нескольких файлах (**). Это далеко не rocket science, но существует пара интересных сценариев их применения, которые являются не столь очевидными с первого взгляда. Но об этом позже, а начнем мы лучше с простого объяснения, что это такое и с чем его едят.

Общие сведения

Давайте вспомним старые добрые дни C# 1.0, когда спецификация языка была вдвое тоньше, возможностей языка было на порядок меньше, да и не было никаких LINQ-ов и всех остальных dynamic-ов (и вопросов на собеседовании, соответственно, тоже). Но даже тогда компилятор языка старался скрасить наши с вами серые будни и усердно выполнял всякую унылую работу, но делал он это не втихаря, путем генерации всяких там анонимных классов или методов, а путем генерации C# кода с помощь дизайнеров. И все бы ничего, но с этим подходом зачастую приходили и некоторые проблемы, которые, в основном сводились к ярому желанию разработчика расширить этот код и к ярому сопротивлению этого кода от подобного ручного вмешательства. Другими словами, внесение любых изменений в автосгенерированный код всегда вели к беде, ибо тут же прибивались компилятором при повторной генерации.

понедельник, 28 февраля 2011 г.

this == null в языке C#?!

Несмотря на то, что язык C# во многих вопросах шагнул на несколько шагов вперед по сравнению со старым добрым С++, в них все еще осталось достаточно много общего. В языке C#, как и в С++, экземлярный метод класса отличается от статического благодаря неявной передаче указателя на экземпляр этого класса (a.k.a. this). Этот анахронизм хорошо спрятан от глаз, но все же он иногда проявляет себя, особенно при работе с делегатами с помощью рефлексии, когда для вызова статического метода мы передаем null, в качестве одного из параметров, а для вызова экземплярного метода, мы передаем некоторый объект, чей экземплярный метод мы хотим вызвать.

Поскольку каждый экземплярный метод все еще неявным образом получает ссылку на текущий объект (в виде неявного параметра this), то возникает вопрос, а может ли быть ситуация, когда этот самый параметр this при вызове экземплярного метода равен null, и, соответственно, насколько логично такая проверка в экземплярном методе?

четверг, 24 февраля 2011 г.

Что такое WCF?

Недавно на rsdn.ru был задан интересный вопрос, что такое WCF? Вопрос весьма интересный, на который ответить в форуме достаточно сложно, но я все же постарался это сделать, а здесь я хочу привести несколько облагороженный вариант своего ответа.

Общие сведения

Если в двух словах, то WCF (a.k.a. Windows Communication Foundation) — это очередной фреймворк для построения распределенных приложений и межпроцессного взаимодействия, который является логическим развитием предыдущих подобных технологий компании Майкрософт, в частности Веб-сервисов, .Net Remoting и DCOM. И если предшественники были заточены на выполнение какого-то конкретного круга задач, то WCF - это скорее мультипарадигменная технология, вобравшая в себе все лучшее от своих предшественников, добавив при этом, конечно же, кое-каких собственных проблем.

Существенным отличием WCF от .Net Remoting является то, что WCF — это, прежде всего, технология для построения сервис-ориентированной архитектуры приложений (SOA — Service-Oriented Architecture), что позволяет абстрагироваться от конкретной технологи, на которой этот сервис реализован и пользоваться им из других приложений, написанных на любой другой платформе, языке, технологии; главное, чтобы реализация клиента отвечала определенным правилам. Кроме того, логика самого сервиса и его реализация полностью отделена от коммуникационной составляющей, и мы можем декларативно изменять способ взаимодействия с сервисом путем изменения конфигурационного файла. Мы можем изменить протокол взаимодействия, адрес, настроить максимальное количество подключений, ограничить размер пакетов и тайм-аут подключения к сервису, тайм-аут выполнения операции, надежность доставки и многое другое.

понедельник, 21 февраля 2011 г.

Виртуальные события в языке C#

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

Итак, события в языке C# по сути являются реализацией известного паттерна publish/subscribe и содержат всего пару методов add и remove, для подписки и отписки от события, и закрытое поле с мультикаст делегатом, который, собственно, этих самых подписчиков и содержит. А раз событие – это по сути методы, а методы могут быть виртуальными, можно сделать вывод, что события тоже могут быть виртуальными (тем более что свойства ведь могут быть виртуальными и этот факт не вредит ничьему ментальному здоровью). Итак, теоретически – с виртуальными событиями все должно быть нормально, однако это как раз тот случай, когда теория с практикой несколько расходятся.

понедельник, 24 января 2011 г.

[WCF] Декларативное использование NetDataContractSerializer-а

Я уже неоднократно писал о проблемах известных типов (Known Types) в WCF и о нескольких способах ее решения. При этом я также упоминал, что одним из наиболее радикальных способов решения этой проблемы является использование сериализатора NetDataContactSerializer, вместо DataContractSerializer, используемого по умолчанию. Основное отличие первого класса от второго заключается в том, что NetDataContractSerializer сохраняет информацию о CLR-типе в сериализированный поток байтов, передаваемый между сервисом и его клиентом. Такое поведение нарушает ключевой принцип сервис-ориентированной архитектуры (SOA, Service-Oriented Architecture), который гласит о том, что сервисы и их клиенты не должны ничего знать о тех платформах, языках или технологиях, на которых они работают. Однако иногда мы можем себе позволить пойти на такие жертвы, когда четко знаем, что наша система предназначена только для платформы .Net, а другие языки и технологии использоваться не будут.

Наиболее популярным в сети способом использования NetDatacontractSerializer-а заключается в создании custom-атрибута, которым нужно пометить все методы сервиса или сам сервис целиком (этот способ я описывал в одной из предыдущих заметок и именно его я использовал на практике), однако появились сведения, что в некоторых случаях это может привести к проблемам, поскольку в этом случае производится изменение поведения (operation behavior) уже после вызова метода OpenHost, и в некоторых случаях может привести к непредсказуемому поведению. Другим, не менее важным недостатком того подхода является то, что вам нужно захардкодить ваше решение прямо в коде (путем добавления этих атрибутам к классам и/или методам) и нельзя перейти от одного решения к другому без перекомпиляции приложения. Кроме того, этот вариант не работает совместно с получением информации о сервисе посредством mex (Metadata Exchange Endpoints), поскольку в этом случае будут сгенерированы классы и интерфейсы без этого атрибута и попытка их использования ни к чему хорошему не приведет. В данном случае клиент будет использовать сериализатор DataContractSerializer, а сервис NetDataContractSerializer, и хотя данные сериализованные первым сериализатором могут быть десериализированы вторым, в обратном направлении это работает не всегда.

понедельник, 17 января 2011 г.

О вреде метода Thread.Abort

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

Давайте в качестве примера рассмотрим различные сопособы прекращения работы созданного вручную потока. Если вы начали знакомство с многопоточностью, с таких чудесных библиотек как WinAPI и не менее чудесных языков программирования как С и С++, то вы наверняка очень быстро поняли, что завершать выполнение потока с помощью вызова функции TerminateThread мягко говоря не стоит. Вызов функции TerminateThread гарантировано приводит к утечкам ресурсов, памяти, некорректному состоянию объектов ядра операционной системы и еще десятку других напастей, после которых корректное состояние приложения – мало вероятно. Вызов этой функции достаточно быстро завоевал дурную славу у разработчиков (благо даже в официальной документации на эту функцию в MSDN черным по английскому сказано, что вызывать ее не стоит) и большинству разработчиков пришлось искать другие способы завершения работы потока, начиная от уведомление рабочего потока с помощью событий (events), заканчивая применением булевого флага, который проверяется рабочим потоком и устанвливается в true для его завершения.

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

Ретроспектива 2010 года

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

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