Saturday, January 24, 2009

Москва

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

Можно по-разному относится к Москве, как к городу. Кто-то скажет, что Москва - очень красивый город, особенно летом, особенно возле Кремля :) Город с развитой инфраструктурой, большими возможностями, богатой историей. Кто-то возразит, что сейчас город заметно сдал, везде развешана реклама, идет снос старинных зданий, и что вообще ему далеко до Питера. Да и вообще, понаехали тут... Я же скажу, что для меня Москва - это прежде всего один из древнейших на Руси городов, и бывшая столица нашей некогда необъятной родины. Москва всегда была коммерческим, торговым городом, а потом ей еще и не повезло, когда она стала столицей сначала Российской империи, а потом - СССР и России. Это во-многом определило судьбу города, его застройку и дух. Тому же Питеру в этом плане, на мой взгляд, повезло чуть больше. Питер намного моложе, но его расцвет пришелся на расцвет Российской империи, а потом он не попал под жернова столичной жизни. Наверно, поэтому и сохранился как исторический и культурный памятник намного лучше. Ну да хватит сравнивать - сегодня мы поем оду Москве :)

Я никогда не был в Москве долго. Зато уже 4 раза был там проездом :) И скажу честно, 2 года назад город мне не очень понравился. Не смотрелся он по сравнению с Питером, да и с Киевом тем же, откровенно говоря, тоже. Но с каждым следующим приездом я все больше убеждался, что в Москве есть что-то особенное, какая-то своя неповторимая изюминка. Москва поражает не только размахом и шиком, но и своим внутренним духом, который еще не успел исчезнуть под давлением свалившихся буржуазно-демократических отношений. Да, самые красивые для глаза места - это стандартный набор: Кремль, Красная площадь, храм Христа Спасителя, Воробьевы горы, Новодевичий монастырь, Арбат, Царицыно, и др. Но там вы не почувствуете атмосферу города. Это все в основном для туристов. Лучше отойти в сторону от всего этого, убежать в обычные московские кварталы, погулять там. Вот там можно прочувствовать, как и чем живут обычные москвичи, понять их. А может, даже соприкоснуться с духом этого великого во всех отношениях города.

А пока несколько фотографий Москвы образца 2008 года:

 Picture 509 Picture 523 Picture 522

  IMG_8971Picture 558 Picture 554

Picture 563 Picture 529

Доклад на харьковской UNETA. Материалы

Вчера прошел мой первый доклад на харьковской встрече UNETA. Я попытался разобраться с производительностью Linq to SQL и Entity Framework, взяв в качестве бенчмарка производительность аналогичных запросов в чистом ADO.NET, а также дать какие-то советы по их улучшению. Надеюсь, тем, кто пришел, было не очень скучно :)

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

Как я и обещал, выкладываю материалы доклада:

Скачать тестовое приложение и презентацию можно отсюда:

Тестовое приложение: http://data-access-orm-comparison.googlecode.com/files/DataAccessPerformanceTest_v2.zip

Презентация: http://data-access-orm-comparison.googlecode.com/files/L2S%20and%20EF%20performance%20analysis.zip

Постоянная ссылка проекта: http://code.google.com/p/data-access-orm-comparison/

Для запуска тестового приложения вам понадобится лишь поставить базу данных Northwind и изменить строки подключения. Приложение достаточно расширяемо, так что вы можете добавить туда свои собственные тестовые провайдеры, например, для работы с NHibernate или LLBLGen Pro.

Список полезных ссылок есть в конце доклада, так что здесь я его не привожу.

Удачи в ваших исследованиях!

Sunday, January 4, 2009

Domain Driven Design: введение

Пару месяцев назад мне в руки попала книжка по Domain Driven Design (DDD). Отдельную рецензию на нее я напишу позже, когда дочитаю до конца. А пока что хотелось бы поделиться мыслями, которые у меня возникли в процессе прочтения.

Для начала я бы сказал, что DDD переворачивает взгляд на архитектуру приложения. Слабее, чем это делает MVC, но все же. Как нас учили проектировать в университетах, какие были наши первые проекты в реальной жизни, как программируют в 80-90% случаев в программистких конторах? Очень просто и прямолинейно. Есть у нас требования, анализируем предметную область (domain), находим сущности, анилизируем их поведение, действия, создаем высокоуровневую архитектуру, выбираем технологии, если нужно, строим UML-диаграммы. А дальше проектируем базу данных и от нее уже пляшем: слой доступа к данных (data access layer), слой бизнес-логики (business logic layer), слой представления (presentation layer), сервисы, etc. Т.е. снизу вверх. Все создаваемые таблицы в базе данных, как правило, мапятся на объекты предметной области как один-к-одному (с небольшими исключениями). Далее создаются сущности приложения, которые, как правило, подчиняются структуре сущностей в базе данных для удобства дальнейшей работы (опять же, могут быть исключения). Даже если мы используем какой-нибудь ORM (тот же Entity Framework или NHibernate), но генерируем сущности по базе данных, то мы все равно выходим на т.н. Data Driven Design, когда структура данных диктует нашу объектную модель. Да, это работает для решения многих задач, но не всех.

Domain Driven Design - совершенно другой зверь. Как следует из названия, это просто еще один способ проектирования, который фокусируется прежде всего на предметной области, на объектах реального мира, их поведении и взаимодействии, то есть фокусируется на модели и бизнес-логике, а не на структуре данных. Результатом подобного смещения приоритетов становится то, что мы стараемся перевести объекты предметной области и их поведение сразу в сущности приложения, пытаясь передать в них не только свойства и атрибуты этих объектов, но и поведение. Например, сущность "автомобиль" в DDD будет обладать не только атрибутами марка, цвет, цена, скорость и др., но и, по-возможности, каким-то поведением, связями с другими объектами. При этом проблема сохраняемости этих объектов куда-либо (например, в базу данных) отходит на второй план. Мы об этом не думаем, таким образом достигая сразу нескольких целей:

  1. Откладывание реализации слоя сохранения (persistence layer или data access layer) позволяет реализовать его тогда, когда доменная модель уже спроектирована и реализована, то есть когда она устаканилась. Сколько раз в начале разработки приложения вы добавляете или убираете колонки в таблицах или даже целые таблицы? Сколько при этом приходится переписывать кода слоя доступа к данным? Хорошо еще, если вы используете ORM.
  2. Слой сохранения реализуется как всего лишь один из инфраструктурных инструментов, а не как жизненно важный слой приложения. Акцент смещается на модель, а не на базу данных (или что у вас там) и слой доступа к ней. Это дает намного более сильный уровень независимости ваших классов от слоя сохранения (т.н. persistence ignorance), который дает возможность быстро поменять базу данных или перейти с нее на XML или вообще какие-нибудь внешние сервисы. По сути, это снижение связанности (decoupling).
  3. Persistence ignorance дает еще одну полезную возможность. За счет того, что ваш код может жить и без слоя сохранения, его можно намного проще протестировать. Более того, в начале разработки вообще можно забить как на слой сохранения, так и на слой представления и написать сначала модель (по сути, слой бизнес логики), которую покрыть модульными тестами. Причем тесты здесь выполняют уже не столько роль парашюта на будущее, сколько роль клиентского кода более верхнего или того же слоя, при помощи которого вы можете отточить API классов модели, а также быстро поправить дизайн классов при необходимости. Слой же сохранения в таком случае можно для начала просто закрыть мок-объектами. Если пойти дальше, то в случае необходимости можно написать даже слой представления над моделью, еще даже не начав писать слой сохранения.
  4. Из предыдущего пункта вытекает то, что если вы апологет TDD, то DDD - это точно ваше. Более подходящий для TDD способ проектирования и разработки приложений сложно себе представить.

Кроме всего прочего, Domain Driven Design стимулирует проектировать Rich Domain Model, то есть сущности, которые обладают не только состоянием, но и поведением. В результате разработки посредством Data Driven Design, мы очень часто получаем приложение, разработанное с использованием т.н. анемичной модели (Anemic Domain Model), в которой наши "бизнес" объекты на самом деле являются всего лишь сущностями для передачи данных из базы данных клиенту (UI, сервисы) и назад, т.е. обладают состоянием, но не поведением. Причем получаем мы это не потому что по-другому в Data Driven Design нельзя, а просто потому что в голове у нас это все те же записи из базы данных, просто переведенные на уровень кода. И как записи в базе данных не обладают никаким поведением, так и наши сущности, полученные оттуда, тоже сложно научить этому постфактум. Можно долго спорить о том, хороша ли анемичная модель или нет - это глупо. Просто как и у любого другого инструмента или подхода, у этого также есть свои положительные и отрицательные стороны и своя сфера применения. В приложениях, ориентированных лишь на CRUD операции, анемичная модель работает отлично. В приложениях, где много бизнес логики - уже не так хорошо. Бизнес логику приходится выносить в отдельные классы, которые будут оперировать объектами, хотя очень часто она по сути своей она принадлежит объектам.

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

А что вы используете при проектировании приложений?

Дополнительно почитать о DDD можно в умных книжках:

  1. Eric Evans. Domain-Driven Design: Tackling Complexity in the Heart of Software
  2. Jimmy Nilsson. Applying Domain-Driven Design and Patterns: With Examples in C# and .NET
  3. Tim McCarthy. .NET Domain-Driven Design with C#: Problem - Design - Solution (Programmer to Programmer)

И в онлайне:

  1. http://domaindrivendesign.org/
  2. http://hinchcliffe.org/archive/2005/03/20/189.aspx
  3. http://www.emxsoftware.com/Domain+Driven+Design/
  4. http://www.infoq.com/articles/ddd-in-practice
  5. http://www.udidahan.com/2007/03/06/better-domain-driven-design-implementation/

Wednesday, December 31, 2008

Немножко об уличных фонарях

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

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

Полтава

Picture 098  Picture 117

 Picture 115

Киев

Picture 119 Picture 063

Днепропетровск

Picture 016

Коломыя

IMG_2706

Львов

IMG_2584

Санкт-Петербург

IMG_4988 IMG_5416

Москва

Picture 509 Picture 558

Иркутск

Picture 470

И наконец, Харьков

IMG_8279 IMG_2966 IMG_3217 

Picture 077 IMG_3210

IMG_3210_kvadrat_bw

Еще раз поздравляю всех с Новым годом и Рождеством! :)

Tuesday, December 30, 2008

Разминка мозга №1. Числа и Новый год

Думаю, ни для кого ни секрет, что программирование заключается не столько в знании какой-то технологии, сколько в умении составлять алгоритмы для решения сложных задач. У кого-то из вас, возможно, даже есть какой-то опыт олимпиад по программированию, где эти задачи, мягко говоря, бывают очень даже и очень :) Да, они зачастую абстрактны и оторваны от жизни, но это же не их основная задача. А основная их задача в том, чтобы развивать голову и не давать мозгам ржаветь. Вот и я вам предлагаю размять мозги перед встречей новогодних праздников :)

Задачка изначально была совсем не новогодняя, но я решил, что надо ее видоизменить в связи с праздниками, а заодно и запутать вам возможность поиска ответа в великом и ужасном ;)

Итак, представьте себе: Жил да был на свете Дед Мороз (он же – Санта Клаус). Да, это тот самый дедушка, который на Новый год приносят хорошим деткам конфеты и мандарины, а взрослым – iPod’ы и Wii. Что, вам не принесли? Ну, значит плохо себя вели ;)

Так вот, у Деда Мороза есть олени, много оленей (N). Чтобы не запутаться в них, он их пронумеровал положительными целыми числами, причем так, что нет двух оленей с одинаковыми номерами. Правда, номера могут начинаться не с 1 и иметь пропуски в числах. И вот стоят эти олени в длинном хлеву в стойлах, один за другим, без какой-либо последовательности (номера идут в произвольном порядке). Дед Мороз может ходить мимо этих стойл только в одном направлении, то есть заходит с одной стороны и идет до самого конца, потом обходим хлев снаружи и заходит снова со входа. И вот у нашего дедушки появился новый олень (Снегурочка подарила на день рождения, например). И захотел дедушка наконец-то навести порядок в своих оленях и присвоить новому оленю самый маленький номер из тех, что у него нет. Ну, чтобы заполнить пробелы. То есть ему нужно обойти своих подопечных (только в одну сторону, сколько угодно раз), определить минимальный положительный номер, которого нет у существующих оленей, и присвоить его новоприбывшему.

Однако, дедушка стар, и ваша задача – помочь ему найти это число за минимальное количество проходов по хлеву. На беду, у дедушки еще одна проблема – у него не очень хорошая память, он может запомнить лишь несколько чисел (для определенности положим не больше 5), а писать он не умеет. Зато дедушка умеет считать :) Складывать, вычитать, умножать и делить. Думаю, он умеет еще извлекать корни и решать интегральные уравнения третьего порядка, но к нашей задаче это отношения не имеет :)

Вот, собственно, и все. Прошу алгоритмы в комментарии, товарищи программисты и не только. Чур, код не писать, покажите, на что вы способны без компилятора ;)

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

Monday, December 22, 2008

Доклад на харьковской UNETA

Судя по всему, я буду одним из докладчиков на следующей харьковской UNETA, которая ориентировочно будет в начале-середине января. Тема у меня будет не совсем обычная, она будет связана с производительностью ORM. Точно будут L2S и EF, возможно, добавлю что-то еще, если хватит времени. Так как тема не связана с какой-то конкретной технологией, скорее, это разбор и сравнение, то я могу немного варьировать ее содержание. В связи с этим у меня возник вопрос, что бы вам хотелось услышать? В принципе, скелет доклада я уже продумал, но все равно есть место для различных деталей, тестов, которые я могу провести и т.д. Я постараюсь учесть все пожелания и осветить их в докладе по-максимуму.

В докладе я постараюсь рассказать о том, как работают рассматриваемые ORM внутри, что именно влияет на их производительность, проведу некоторые наиболее интересные и показательные тесты для их сравнения между собой и с чистым ADO.NET, и постараюсь рассмотреть генерируемые каждой ORM запросы.

Итак, у меня есть несколько вопросов к вам:

  1. Стоит ли включать в доклад NHibernate? Или достаточно будет L2S и EF?
  2. Какие тесты вы бы хотели увидеть?
  3. Какие сопутствующие темы вам были бы интересны? Что из неописанного выше можно осветить еще?

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

Спасибо за помощь :)

Saturday, December 13, 2008

Дао программиста

Думаю, каждый программист в своей работе уже определил для себя, что программирование состоит как минимум из двух компонентов: технологий и подходов (возможно, не самое лучшее слово для описания данного термина, но лучше термин я не нашел).

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

Подходы же определяют “как” мы используем все эти инструменты и пишем код, т.е. в случае программирования это понимание и правильное использование ООП, SOLID, паттернов проектирования (GoF, Fowler), каких-то других Patterns & Best Practices, архитектурных принципов, рефакторинга, алгоритмов, структур данных и т.д. Сюда же можно отнести и знание и использование таких практик, как TDD, DDD и пр. В том числе это и тот опыт, который мы приобретаем в процессе работы. В случае с токарем это его умение вытачивать те или иные детали, которое он тоже совершенствует.

У каждого программиста эти 2 компонента развиты в разных соотношениях. Есть ребята гармонично развитые, которые, например, не только знают о том, что есть такая штука как ООП, но и правильно его используют. Есть отклонения в ту или иную сторону.

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

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

Неужели это конец развития? Нет, конечно, это только начало. Во-первых, нет предела совершенству, и знание и понимание тех же технологий можно и нужно увеличивать. А во-вторых, когда программист переходит на уровень архитекта, у него начинаются уже свои головные боли и дальнейшее развитие, но уже не как программиста. Есть application architect, solution architect, enterprise architect, etc. и у каждого свои навыки и знания. Про дао архитекта я пока написать не могу, извините, не дорос еще :) Но оно есть, я в этом уверен.

К чему я все это веду? К тому, чтобы все понимали, что в работе программиста важны и технологии, и подходы, что даже отличное знание технологий еще не делает программиста инженером. На одном крыле далеко не улетишь. Ну и чтобы каждый мог понять хотя бы приблизительно, на каком уровне он сейчас находится и увидел, что именно нужно развивать. Благо, книги есть не только по технологиям, но и по подходам. Изучайте ООП, паттерны, рефакторинг, всякие TDD/DDD/Agile/прочее, это чужой опыт, который может помочь вам стать настоящим профессионалом. Успехов!