tag:blogger.com,1999:blog-19687772095359477792009-07-13T16:45:21.014+03:00Блог Александра Кондуфороваоб информационных технологиях, программировании, путешествиях и фотографииАлександр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.comBlogger64125tag:blogger.com,1999:blog-1968777209535947779.post-11936103682774971532009-06-14T14:34:00.001+03:002009-06-15T11:52:11.446+03:00Снова об IT-образовании<p><font face="Arial">Эта заметка является комментарием на заметку Артема Сердюка </font><a href="http://www.agileukraine.org/2009/06/blog-post.html"><font face="Arial">&quot;Обучение программистов в украинских вузах&quot;</font></a><font face="Arial">. К сожалению, она не поместилась там как комментарий из-за размера, поэтому выкладываю ее здесь в полном виде. Заранее прошу прощения у автора за это.</font></p> <p><font face="Arial">&quot;Тема, конечно, животрепещущая (сам писал недавно </font><a href="http://merle-amber.blogspot.com/2008/11/it.html"><font face="Arial">заметку</font></a><font face="Arial"> на немного другую, но тоже связанную с образованием тему), но заметка уж очень эмоциональна. У вас много претензий к вузам, в которых плохо построен образовательный процесс, к преподавателям, которые не обучают студентов на должном уровне, и к самим выпускникам, которые не умеют работать на &quot;промышленном уровне&quot;. А вместе с тем разве коммерческим фирмам кто-то обещал, что выпускники будут сходу вышивать крестиком? Вроде бы нет. Более того, спросите тех же опытных банкиров, экономистов, юристов, и не только в нашей стране - там те же проблемы с &quot;дорабатыванием напильником&quot;. Разве что напильник может быть более или менее грубым. </font></p> <p><font face="Arial">Программирование и &quot;промышленная&quot; разработка софта - это, как говорится, две большие разницы. Хороший &quot;промышленный&quot; программист (как и любой другой специалист) - это не только технически подкованный программист, но еще и грамотный, ответственный, умеющий работать в команде работник. У вузов же задача другая - они не конвейерных рабочих готовят для ублажения нашего родного аутсорсового бизнеса (т.е. по принципу ПТУ), а стараются, кроме непосредственно программирования, научить человека еще и другим важным предметам. Да, не все из них понадобятся в жизни. Да, образовательно-техническая база устарела. Да, действительно хороших преподавателей мало. И наконец, да, программистов <strong>нужно учить по-другому</strong>. Все эти проблемы есть. Но только решение их нужно искать не с точки зрения &quot;а вот нам сейчас нужны PHP-девелоперы, давайте нам их, и побольше&quot;, как того требует рынок, и не с точки зрения &quot;забрать студента как можно раньше, пока вуз его окончательно не развратил&quot; а все-таки с точки зрения реформирования наших вузов для того, чтобы на выходе они давали хорошо подкованных CS-специалистов, которые будут:</font></p> <ol> <li><font face="Arial">знать техническую базу: устройство компьютера, микропроцессора, и т.д., понимать, что такое ОС, как работают компьютерные сети, что такое интернет</font> </li> <li><font face="Arial">уметь программировать (язык не важен, важно понимание и алгоритмическое мышление)</font> </li> <li><font face="Arial">знать алгоритмическую базу, структуры данных, базы знаний, основы нейросетей, искусственного интеллекта, и т.д.</font> </li> <li><font face="Arial">понимать, что такое качество кода, ООП, шаблоны проектирования, масштабирование, производительность и т.д.</font> </li> <li><font face="Arial">знать хотя бы по одному языку программирования разных уровней, и те или иные технологии по выбору студента и на том уровне, который он хочет знать</font> </li> <li><font face="Arial">разбираться в базах данных (реляционных, объектных), XML и других форматах и способах хранения данных</font> </li> <li><font face="Arial">понимать весь цикл <strong>разработки софта</strong> (а не просто уметь писать лабы), иметь представление о методологиях разработки, командной работе, QA</font> </li> <li><font face="Arial">быть немного знакомым с best practices of software development: source controls, unit testing, CI, и др., возможно - BDD, DDD, XP-практиками</font> </li> <li><font face="Arial">наверняка, что-то забыл, впишите сами... </font></li> </ol> <p><font face="Arial">Как это сделать? Уж точно не забирать студентов из вузов, заманивая зарплатами или другими коврижками. На мой взгляд, нужно создать конкуренцию между государственными и по-возможности частными вузами при активной помощи &quot;промышленной&quot; сферы. Отделить научный и образовательный процессы в вузах - а то у нас преподаватели ни наукой не занимаются, ни обучать толком не успевают. Пусть выбирают, что им хочется делать в первую очередь. Такое разделение и возрастающая конкуренция даст возможность вузам приглашать к преподаванию уважаемых технических специалистов, имеющих практический опыт, после завершения IT-карьеры, а &quot;промышленным&quot; компаниям - вести определенные курсы в вузах, если на то есть желание. При этом талантливые студенты будут иметь выбор: идти заниматься научным CS или делать карьеру в прикладной IT-сфере. Похоже, от этого выигрывают почти все. </font></p> <p><font face="Arial">Это, конечно, не все. Со стороны вузов еще нужно перенимать опыт коллег (МГУ, MIT, etc.), хотя бы лекции их посмотреть, отправлять преподавателей на стажировку. Заинтересовывать студентов действительно интересными научными разработками. Брать заказы и гранты у крупных госорганизаций и не только у них. Обновить подходы к обучению программированию, продумать и улучшить программу. Дать студентам бОльшую гибкость в выборе &quot;специальных&quot; предметов: один может хотеть изучать веб-программирование, второй - мобильные системы, а третий - робототехнику, одному нравится LAMP, второму - .NET, третьему - Ruby on Rails. Постоянно держать связь с IT-индустрией нашей страны.</font></p> <p><font face="Arial">Компаниям же можно посоветовать уже сейчас начинать проводить в вузах семинары, тренинги, мини-курсы по тем технологиям, которые важны именно данной конкретной компании - конкуренты подтянутся. Сотрудничать с преподавателями с целью повышения их квалификации в обмен на возможность давать студентам реальные темы для курсовых, и их проверки. Постоянно держать связь с руководством вузов, планомерно развивать эту сферу деятельности. </font></p> <p><font face="Arial">Вот только, боюсь, что IT-компаниям это как раз мало выгодно. Лучше обучать своих, чем &quot;чужих&quot; - это дешевле и надежнее. И вузам без конкуренции наплевать на улучшение качества образования, если только там не сидят действительно любящие свое дело люди. Так что все это замечательное будущее мы с вами получим явно не скоро. Но вода камень точит, вы же знаете.&quot;</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-1193610368277497153?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com4tag:blogger.com,1999:blog-1968777209535947779.post-45069122264086218602009-06-01T23:39:00.001+03:002009-06-02T11:06:34.399+03:00Путешествие на Закарпатье<p><font face="Arial">Я уже было решил не писать отчет о нашем походе по Карпатам и поездке в Ужгород, но, похоже, эта информация может пригодиться тем, кто собирается туда ехать после нас.</font></p> <p><font face="Arial">Ездили мы на Закарпатье впервые. До поездки для меня Карпаты были загадкой - несмотря на то, что я уже однажды бывал в Ужгороде, Львове и Коломые, про сами горы я знал лишь то, что там есть Говерла, и куда-то туда ездят кататься зимой на лыжах толпы моих друзей и сотрудников. Названия Славское, Драгобрат, Буковель при мне упоминались часто, но на привычной карте в моей голове эти места еще размещены не были. Поэтому и хотелось поехать восполнить этот пробел.</font></p> <p><font face="Arial">План похода прорабатывался несколько недель. За это время мы с Леной успели проштудировать кучу форумов и турсайтов, просмотреть кучу фоток, выучить почти на зубок карту в районе Синевира - Воловца, купить кучу инвентаря, одежды и обуви, которых нам не хватало, и пообщаться с друзьями, которые уже были в Карпатах. После всего этого мы все-таки смогли определиться с основными чекпоинтами и были морально готовы выезжать.</font></p> <p><font face="Arial"><strong>Поход</strong></font></p> <p><font face="Arial">Мы не очень долго сомневались, хотим ли мы идти на Говерлу или нет - в мае не хотим. Поэтому остановились мы на горах возле Синевира и Шипота - их посоветовали друзья. Кроме того, этот район достаточно хорошо описан в интернете, хотя нормальную карту днем с огнем не сыщешь. Немаловажен также тот факт, что максимальная высота на маршруте - не более 1600 м (хотя надо признаться, мы и туда не полезли), что давало надежду, что на майские нам не придется сильно шлепать по снегу - бахилы мы все-таки соорудили, но на покорителей снежных вершин пока еще смахиваем слабо.</font></p> <p><font face="Arial"><strong>Инвентарь</strong></font></p> <p><font face="Arial">Что нужно взять с собой в поход в мае в Карпаты? Как минимум палатку, спальник, каремат (где-то до -5), две пары обуви (непромокаемую на случай дождя или снега и легкие трекинговые кроссовки на остальное время), легкие вещи на день, теплые вещи на вечер и ночь, какую-нибудь защиту от дождя (не зонт), горелку (на случай длительного дождя), фотоаппарат (куда без него!), карту, компас, GPS (опционально), нож, котел, посуду и еду. А, да, еще хорошее настроение! :) Поскольку в этот раз мы собирались поставить рекорд тяжести наших рюкзаков, а в интернете нас постоянно пугали тем, что в селах магазины работают не так часто, как супермаркеты в Харькове (странно, правда?), к сбору еды мы в этот раз подошли серьезно: рассчитали все завтраки, обеды и ужины, и взяли с собой только то, чего нам должно было хватить на неделю похода за вычетом одного набега на местные магазинчики. Надо сказать, мы почти угадали: в поезде назад мы доедали последнюю банку паштета, но все равно брать нужно было <u>меньше!</u> Эту банку паштета (да и не только ее) можно было купить и в Ужгороде, и не устраивать ей экскурсию по горам и весям Карпат в течение 6 дней.</font></p> <p><font face="Arial"><strong>Маршрут похода</strong></font></p> <p><font face="Arial">На этой карте можно посмотреть приблизительный маршрут похода. Сторона квадрата приблизительно равна 2 км, чуть больше. Желтой пунктирной линией обозначена дорога до Синевира, красный пунктиром - маршрут пешего похода, оранжевым - переезд из села Верх-Быстрый до Шипота (село Пилипец). Красные кружочки с числами - стоянки с нумерацией ночей, красные квадратики - просто какие-то существенные места: прибытие, отправление, пересадка, гора и т.д.</font></p> <p><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ7o2Q8dtI/AAAAAAAAJYQ/6UmvelIlMsE/M34131_45.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="349" alt="M-34-131_4" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ7p1umacI/AAAAAAAAJYU/tVn37zcjs4o/M34131_4_thumb3.jpg" width="826" border="0" /></a> </p> <p><font face="Arial">Итак, маршрут получился следующий: оз. Синевир - г. Озерная - с. Верх-Быстрый - вдп. Шипот - Боржавский хребет. После чего мы вышли на центральную дорогу в районе Подобовца, сели там на автобус и поехали в Ужгород.</font></p> <p><font face="Arial">Надо сказать, что изначально мы планировали совсем другой маршрут. Начинаться он должен был там же, но после второй стоянки мы должны были подниматься вверх на Камянку, перевалить ее, спуститься в Стригальню, потом оттуда доехать до Лозянского, и снова пойти в горы, чтобы полюбоваться Боржавой: через перевал Прислоп (масло масленое, Прислоп - это и есть &quot;перевал&quot;) пройти по хребту через горы Ополонок, Граб, Магура-Жиде, дойти до горы Великий Верх, и оттуда спуститься к водопаду Шипот. Но, надо сказать, это я здорово переоценил наши силы и время. Опытные ребята, я уверен, прошли бы этот маршрут за 6 дней, и еще день бы лежали на траве, но у нас в компании лосей не было, поэтому мы топали мало (где-то 4-8 часов в день) и достаточно прогулочным темпом, фотографируя окрестности и кушая орешки.</font></p> <p><font face="Arial"><strong>День 1. Синевир</strong></font></p> <p><font face="Arial">До Карпат мы ехали поездом Харьков - Ужгород. Утром мы вышли в Воловце - ближайшей точке, из которой можно доехать до Межгорья (районный центр) автобусом, затем оттуда добраться до Синевирской поляны, откуда до Синевира уже рукой подать (7 км). Однако, вышло несколько иначе. Выходные в Карпатах - это выходные. Местные водители бастуют, даже несмотря на то, что в расписании указан их маршрут. Поэтому до Межгорья мы добирались на автобусе, проходящем из Ужгорода. По пути мы познакомились с 5-ю харьковчанами, которые тоже ехали на Синевир с целью погулять по горам. Вдевятером мы договорились с местным таксистом, который нас подвез из Межгорья до пропускного пункта на озеро, по пути развлекая рассказами о местных происшествиях и образе жизни. От пропускного пункта до озера оставалось совсем немного - всего пара километров.</font></p> <p><em><font face="Arial">Озеро Синевир (Морское око Карпат) находится на высоте 989 м, и по праву считается одним из самых красивых горных озер Украины. Есть несколько поэтических легенд об образовании озера. Согласно одной из них, озеро образовалось из слез красавицы Сини - дочери графа, слуги которого убили ее любимого Вира. Согласно другой - убежавший от гнева графа деревенский парень попросил море хоть передать привет родной земле, по которой он очень тосковал. Море сжалилось над ним, пробилось через горы, и так и осталось навсегда в этой красивой земле.</font></em></p> <p>&#160; <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ7qx61iPI/AAAAAAAAJYY/1TNwTjKe3i0/IMG_41135.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="187" alt="IMG_4113" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ7rpuBcwI/AAAAAAAAJYc/xsZ_cc8UJIM/IMG_4113_thumb3.jpg" width="276" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ7sRybCMI/AAAAAAAAJYg/XDL_PnmxjYw/IMG_41342.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4134" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ7s9c3LHI/AAAAAAAAJYk/HbRpLQXMvUs/IMG_4134_thumb.jpg" width="244" border="0" /></a> </p> <p><font face="Arial">И все же, при всем уважении к Синевиру, это очень попсовое место. Людей там уйма, причем многие никогда не видели туристов с рюкзаками, везде что-нибудь продают, даже свадьбу приезжают сюда играть! В общем, мы ожидали совсем другого, поэтому довольно быстро узнали всю необходимую информацию, полюбовались на форель в озере, и пошли на другую сторону озера подниматься на Озерную. Уже было около 5 вечера и нам нужно было что-то решать с ночевкой. Подъем на гору до ближайшей поляны стал для нас первым испытанием - мы достаточно быстро выдохлись, чего не скажешь о наших новых знакомых, которые забрались значительно быстрее. На поляне мы нашли несколько пустых домиков и начали искать безветренное место для стоянки. На самом верху, у границы леса, мы нашли несколько очень уютных мест, но решили пройти на соседнюю поляну, т.к. думали, что тропинка на вершину начинается именно там. Там мы также нашли хорошее место для ночевки, но обойдя всю ее по периметру, тропинку наверх так и не нашли. Зато нашли тропинку куда-то вбок и вниз, чему не очень сильно обрадовались. Подъем на вершину в лоб через лес не обещал много приятных моментов завтра. Поставив палатки и поужинав, мы довольно быстро пошли спать.</font></p> <p><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ7tqkBhWI/AAAAAAAAJYo/A5mvZtJPLCM/IMG_4153%5B1%5D.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="174" alt="IMG_4153" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ7uTNyKAI/AAAAAAAAJYs/dzoEN21NKjM/IMG_4153_thumb%5B1%5D.jpg" width="269" border="0" /></a><font face="Arial"></font></p> <p><font face="Arial">За первый день от начала нашего маршрута, коим я считаю пропускной пункт на Синевир, мы прошли максимум километров 5-6 (с учетом поисков ночлега). Ночевка была на высоте 1245 м, поэтому перепад высот составил около 400-500 м. Довольно неплохая разминка.</font></p> <p><font face="Arial"><strong>День 2. Озерная</strong></font></p> <p><font face="Arial">Утром мы проснулись не очень рано. Пока мы позавтракали, привели себя в порядок, сходили за водой и собрались, было уже полпервого. Знаю, что это очень поздно, но мы и не планировали марш-бросков на этот поход. Пока ребята ходили за водой, я успел сходить на соседнюю полонину, с которой мы вчера пришли, и нашел там тропинку, уходящую вверх серпантином. Довольные тем фактом, что не придется идти абы куда, мы двинулись вверх. Подъем на вершину был довольно крут, мы периодически останавливались передохнуть, но где-то через час-полтора мы были на вершине. 1495 м. С вершины (да и чуть ниже) открывался прекрасный вид на Синевир и окружающие горы. Такой Синевир производил намного лучшее впечатление. Пофотографировав эти изумительные виды и друг друга в снегу, мы собрались с духом и пошли по хребту в сторону Каменки.</font></p> <p>&#160; <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ7vIe8dbI/AAAAAAAAJYw/IwPfZcuGg-g/IMG_42852.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4285" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ7vhBrDyI/AAAAAAAAJY0/eshgQNvErWk/IMG_4285_thumb.jpg" width="244" border="0" /></a> <a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ7wYjeL2I/AAAAAAAAJY4/86-TiVn5iLo/IMG_42553.jpg"></a><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ7xNJuYUI/AAAAAAAAJY8/9ZSIKov0cro/IMG_41872.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4187" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ7xxW6H6I/AAAAAAAAJZA/aegl1x9HtYM/IMG_4187_thumb.jpg" width="184" border="0" /></a><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="IMG_4255" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ7ykXbTnI/AAAAAAAAJZE/S72UV476rOc/IMG_4255_thumb1.jpg" width="332" border="0" /></a> </p> <p><font face="Arial">Идти по хребту было очень приятно - как будто идешь по сосновому лесу, под ногами мягкая хвоя, периодически слева или справа открывается прекрасный вид. Так продолжалось довольно долго, пока мы не вышли к очередной вершине. Путь к ней вел через заросли жерепа - стелющейся сосны. Продираться через нее оказалось делом отнюдь не легким, но зато с вершины открывался прекрасный вид. Так как наш GPS мог нам сказать мало чего полезного, а солнце уже клонилось к закату, я начал волноваться, не зашли ли мы слишком далеко - в наших планах сегодня было еще спуститься вниз к воде, а склон вниз был слишком крут. Мы прошли еще полчасика по хребту и тут тропинка окончательно исчезла. Она порывалась это сделать уже несколько раз, но теперь ей это наконец удалось. Мы не нашли ничего лучше, чем спускаться вниз, благо, склон наконец-то стал пологим. Сложно описать то, по чему нам пришлось спускаться. Упавшие стволы деревьев и камни, полностью покрытые толстым слоем мха. С одной стороны нужно идти аккуратно, чтобы не поломать ноги, а с другой - такого мягкого ковра я еще не видел. Кое-где еще лежал снег, на нем, да и на редких участках мокрой земли, где снег уже сошел, а мха не было, встречались следы разных животных. Похоже, их тут много. Нам постоянно приходилось выбирать пологие участки, двигаться серпантином и переступать через огромные стволы упавших деревьев. Пару раз мы даже чуть было не скатились вниз.</font></p> <p><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ7zpSK_kI/AAAAAAAAJZI/wM-2TBhRLHE/IMG_43422.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4337" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ70Z5ODSI/AAAAAAAAJZM/mDcaIcbqeLU/IMG_4337_thumb.jpg" width="244" border="0" /></a>&#160;<a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ71Ihuf8I/AAAAAAAAJZQ/2KWcVH5MHWc/IMG_43452.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4345" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ713HtOGI/AAAAAAAAJZU/DMVPuaXqDtw/IMG_4345_thumb.jpg" width="244" border="0" /></a> </p> <p><font face="Arial">Через более чем час спуска мы вышли на вырубку, где наконец-то смогли нормально осмотреться. Впереди перед нами высились склоны Каменки, справа внизу сплошным ковром шел лес, за которым далеко-далеко было видно речку. Было уже часов 7 вечера, а спускаться вниз нужно было еще долго. Вырубка была большой и недавней - на некоторых пнях еще была смола. Но, нужно отдать местным жителям должное - хотя вырубка и походила на последствия коврового бомбометания, здесь уже были высажены маленькие деревца. По вырубке шло несколько дорог для специального трактора, который возил деревья вниз. По этим-то дорогам мы и начали спускаться под лучами заходящего солнца. Некоторые спуски были настолько крутыми, что мы чуть ли не падали и ехали вниз. Как это чудо техники умудряется на них карабкаться - для меня до сих пор загадка. Спустившись в долину, мы нашли там базовый лагерь рабочих, рядом с которым был припаркован этот самый трактор. Сходив на разведку, мы нашли одно неплохое местечко, где можно переночевать, а еще ниже нашли начало одного из рукавов реки. Успокоившись насчет воды, мы расставили палатки, поужинали и легли спать. Сегодняшний день нас всех ощутимо вымотал. Но нам еще повезло: если бы не эта вырубка, мы бы точно не успели спуститься в долину засветло, и я не знаю, где бы мы ставили палатки - на склоне это сделать было почти невозможно.</font></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ72rz3lSI/AAAAAAAAJZY/b3OFDHrqkyc/IMG_43592.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4359" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ73Li_bcI/AAAAAAAAJZc/OINwYQafofM/IMG_4359_thumb.jpg" width="244" border="0" /></a><font face="Arial"></font></p> <p><font face="Arial">Но это еще были не все приключения этого дня. Ночью меня разбудил крик птицы. Похоже, это был пугач, но кто их разберет. Кричало это чудо пронзительно и противно, как будто кто-то его режет, и все ближе и ближе перелетало к месту нашей стоянки. Я посмотрел на часы: было около 3 часов ночи. Лена спала как убитая, и это было хорошо, а вот я уснуть не мог. Все-таки не очень приятно лежать в темной палатке, которая ни от чего тебя не может защитить, когда вокруг тебя слышны разные шорохи. Да еще и эта прица орет над ухом! В голове носились мысли про то, что в Карпатах довольно много кабанов, волков и что медведи тоже есть, и невольно подсасывало под ложечкой. Хорошо еще, что нож и петарды я предусмотрительно взял с собой в палатку. Тут я услышал, что в соседней палатке расстегнулась змейка, и кто-то начал ходить по лагерю. Успокоившись, что это скорее всего Саша тоже не спит, и решил выйти подышать свежим воздухом, я кое-как снова уснул. На утро оказалось, что никто из палатки не выходил, это была змейка спальника, а шорохи и звуки шагов возле лагеря слышал не только я :)</font></p> <p><font face="Arial">Согласно данным нашего GPS, ночевали мы на высоте 939 м. За этот день по самым скромным подсчетам мы прошагали где-то 10-12 км (хотя по карте кажется, что там нет и 6).</font></p> <p><font face="Arial"><strong>День 3. Река Быстрая</strong></font></p> <p><font face="Arial">На третий день проснулись мы рано, но с выходом снова затянули. У нас даже появилась примета: во сколько не просыпайся - все равно раньше 12 не выйдешь. Собрав вещи, мы выдвинулись вниз по дороге. Рядом с дорогой постоянно текла речушка, с каждым десятком метров прибавлявшая себе воды из боковых притоков. Шли мы по впадине между двух хребтов, можно сказать по каньону реки. Судя по карте дорога должна была нас вывести к деревне и в планах у нас было добраться до нее и стать лагерем где-то на подходе. Места здесь были очень живописные, один раз мы даже видели небольшую косулю, которая спустилась с горы на водопой. Сосновый лес постепенно сдавал свои права лесу лиственному. Периодически стали появляться следы жизнедеятельности человека, пару раз по дороге проезжали машины, которые, судя по всему, ездили на вырубку - больше некуда.</font></p> <p><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ74JgKe3I/AAAAAAAAJZg/mbl-zKxTsME/IMG_44132.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4413" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ749jtjJI/AAAAAAAAJZk/twlC60Y4YRY/IMG_4413_thumb.jpg" width="184" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ75nwsuhI/AAAAAAAAJZo/8K-vpiJt-Ns/IMG_44032.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4403" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ76M3DZ6I/AAAAAAAAJZs/0VcJEGJIXGw/IMG_4403_thumb.jpg" width="244" border="0" /></a>&#160; </p> <p><font face="Arial">Погода стояла отменная. Было так жарко, что мы даже решили открыть сезон загара на дневной стоянке. Вообще, надо сказать, с погодой нам очень повезло. В Харькове прогнозы погоды нас постоянно пугали то неделей дождей, то лишь выборочными осадками по несколько дней. Когда мы подъезжали к Межгорью в первый день, то над местом нашего предполагаемого маршрута явно шел дождь. Но добравшись до Синевира, мы там застали лишь небольшой накрапывание и свинцовые тучи, которые немного портили настроение, но ухитрились за ночь сбежать куда-то очень далеко. Все остальные дни погода была отличная, за исключением четвертого дня, когда мы уже уезжали из этого района на водопад, удачно обогнув все те же свинцовые облака.</font></p> <p><font face="Arial">День прошел без приключений и ближе к вечеру мы вышли к окрестностям деревни, о приближении которой мы быстро поняли по загонам для скота. Наша речка постоянно текла рядом с нами, превратившись уже в настоящую реку метров 5 шириной. Увидев первые домики вдалеке, мы решили искать место для стоянки, и очень скоро нашли хорошую полянку, ограниченную с одной стороны рекой, а с другой - склоном горы, покрытым лесом. С дороги, по которой иногда проезжали машины и повозки, нас было не видно из-за густого кустарника возле реки, поэтому чувствовали мы себя более чем комфортно.</font></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ76yhSR7I/AAAAAAAAJZw/nysAkPJxuN4/IMG_45072.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4507" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ77h_H3yI/AAAAAAAAJZ0/r6IG7uT1-1c/IMG_4507_thumb.jpg" width="184" border="0" /></a>&#160;<a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ78cZfvEI/AAAAAAAAJZ4/nmmj0pcvgfU/IMG_45422.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4542" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ78wgEPTI/AAAAAAAAJZ8/_pAy4e9_9Wc/IMG_4542_thumb.jpg" width="244" border="0" /></a></p> <p><font face="Arial">Сегодняшний участок пути был самый простой, хотя по карте он и выглядит самым длинным. Вообще, с этими картами беда - никогда нельзя понять, сколько времени уйдет на проход того или иного участка, лишь предполагать. Поэтому на месте стоянки мы были достаточно рано - где-то в 7 часов. Времени хватило не только поставить лагерь, но и искупаться. Как самые мужики, мы с Сашей купались в ледяной речной воде.</font></p> <p><font face="Arial">За третий день было пройдено около 10 км, а лагерь мы разбили на высоте 626 м.</font></p> <p><font face="Arial"><strong>День 4. Шипот</strong></font></p> <p><font face="Arial">Ночью шел дождь. Утро нас встретило холодным ветром и туманом. По небу ходили тучи, но мы понимали, что рано или поздно солнце все равно появится, чтобы высушить наши палатки. Четких планов на этот день у нас не было. Так как мы имели один день в запасе, мы могли остаться на дневку. Но все же решили, что лишний день на Шипоте или в Ужгороде это тоже неплохо.</font></p> <p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4663" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ79weIyJI/AAAAAAAAJaA/SOpV0u72eAk/IMG_4663_thumb.jpg" width="178" border="0" /><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="185" alt="IMG_4631" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ7-QY6uaI/AAAAAAAAJaE/cFMJ-Z5jbTs/IMG_4631_thumb2.jpg" width="373" border="0" /><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ7_dmc9VI/AAAAAAAAJaI/rX74KczOJQ8/IMG_46252.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4625" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8AcdQWTI/AAAAAAAAJaM/xwh5Ht0ybIY/IMG_4625_thumb.jpg" width="244" border="0" /></a>&#160;<font face="Arial"></font></p> <p><font face="Arial">Самые большие впечатления этого дня заключались в осмотре быта обычной закарпатской деревни. Надо сказать, что деревни в Карпатах - это нечто особенное! Несмотря на то что у людей здесь нет каких-то сумасшедших полей (горы ведь), колхозов, а другой работы тут не так уж и много - животноводство да лесоповал - живут деревенские жители более чем достойно. Дома все чистенькие, убранные, лужайки ухоженные, на окнах цветы. На стенах - спутниковые тарелки, без них здесь нельзя. В большинство деревень не подводится газ, здесь нет телевизионных вышек, как на равнинах. Поэтому возле каждого дома нарублены дрова и сложены поленницы. В школах - хорошие детские площадки, чистенькие школьные автобусы. В общем, это мало похоже на наши деревни.</font></p> <p><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8BYltqmI/AAAAAAAAJaQ/BmPYz1eYZns/IMG_46752.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4675" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8CLhrtDI/AAAAAAAAJaU/bmNqDsXE8_k/IMG_4675_thumb.jpg" width="244" border="0" /></a> <a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8Cyhu2_I/AAAAAAAAJaY/PZj3FKLqjVY/IMG_46702.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4670" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8DcZuUjI/AAAAAAAAJac/xrkAcxkJ1pU/IMG_4670_thumb.jpg" width="244" border="0" /></a> </p> <p><font face="Arial">На остановке нам сказали, что доехать напрямик до Пилипца у нас вряд ли получится, поэтому пришлось ехать на автобусе до Сойм (да, тех самых, где разливается минеральная вода), а там еще битый час ждать автобус или попутку в нашу сторону. Вообще, в районе очень хорошее транспортное сообщение, но было уже довольно поздно. В результате мы поняли, что доехать на автобусе нам сегодня не светит и поймали две попутки с разрывом в полчаса. Вот только мы ошиблись и поехали до Пилипца, а не Подобовца, и нам грозило еще километров 5-7 идти пешком до водопада. Просто в Карпатах деревни мало того что плавно перетекают одна в другую, так еще и такие конфузы случаются, что физически водопад находится возле одной деревни, но если добираться от трассы, то лучше выйти на 5 километров дальше, в другой деревне, перейти через гору и попасть в нужное место. В результате, нам повезло поймать еще одну попутку, которая довезла нас до водопада.</font></p> <p><em><font face="Arial">Шипот - очень красивый водопад. Высотой 12 метров, он ниспадает каскадом, оглушая своим грохотом. В мае он еще очень полноводен, так как его еще хорошо питают тающие снега Боржавы. Рядом с водопадом проложены несколько горнолыжных трасс, построены подъемники, куча гостиниц, в общем, инфраструктура развита.</font></em></p> <p>&#160;<a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8EWG3CgI/AAAAAAAAJag/RWZ2xs1bSvk/IMG_48862.jpg"></a><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8EwQ8-AI/AAAAAAAAJak/nOQ28z2yV24/IMG_47362.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4736" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8FVdDotI/AAAAAAAAJao/y7QPAh9ehxU/IMG_4736_thumb.jpg" width="184" border="0" /></a><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4886" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8GFolGiI/AAAAAAAAJas/TAc9hoFz-Mw/IMG_4886_thumb.jpg" width="184" border="0" /></a>&#160; </p> <p><font face="Arial">Несмотря на то, что до Шипота тоже легко добраться на машине, народу здесь уже почти не было - вечер, да и будни, не суббота, как на Синевире. Мы быстро пофотографировались, поглазели немного, узнали, где можно поставить палатки и пошли наверх - на поляну, на которой периодически собираются &quot;хипари&quot;, как нам сказала девушка на проходной. &quot;Хипарей&quot; на поляне не было - еще не День защиты детей, и не Ивана Купала, когда эта поляна почти полностью покрывается палатками. Поляна представляет собой вытянутую по направлению к горам полонину между двумя речными каньонами. С нее открывается замечательный вид на Боржавский хребет, гору Великий Верх, и вниз, на деревню Пилипец. В таком живописном месте можно провести и не один день.</font></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8GiVvEfI/AAAAAAAAJaw/d2k4YwYQgTY/IMG_47384.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="195" alt="IMG_4738" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8HbkrytI/AAAAAAAAJa0/jDgIjsflmDg/IMG_4738_thumb2.jpg" width="368" border="0" /></a> </p> <p><font face="Arial">Вечер был коротким - только мы насобирали дров и поставили палатки, как наступили сумерки. Но в этот день спать не хотелось, поэтому мы долго сидели и общались перед сном.</font></p> <p><font face="Arial">Палатки мы поставили на высоте 843 м. В это &quot;неходовой&quot; день мы прошли максимум километров 5-6.</font></p> <p><font face="Arial"><strong>День 5. Боржава</strong></font></p> <p><font face="Arial">На пятый день нашего похода мы устроили наконец дневку. Шипотская поляна подходила для этого как нельзя лучше - есть вода, дрова, прекрасные виды. Днем ребята сходили вниз, разведали обстановку в домиках - мы уже и не собирались там ночевать, но в конце-концов решили, что перед отъездом в Ужгород не помешает нормально искупаться, да и хотелось успеть на 11-часовый автобус, а с нашей манерой собираться для этого на следующий день нам пришлось бы вставать в 7 утра. В результате ребята нашли отличную деревянную мини-гостиницу за 350 грн с четверых (сначала просили по 100 грн с носа), в которой мы и решили пока оставить вещи. Саша и Алена намеревались погулять возле водопада, а мы с Леной хотели сбегать налегке на хребет, раз выдалась такая возможность.</font></p> <p><font face="Arial">Через поляну шла дорога, по которой мы и начали подниматься вверх. Через час подъема дорога вышла из лесу, и мы вышли на участок, покрытый травой и низкорослым кустарником. Здесь начиналась подъем на хребет. Горы встретили нас не очень приветливо - по небу бродили низкие тучи, без солнца было довольно холодно, а ветер постоянно намеревался сдуть нас вниз. Но мы твердо решили зайти на Полонину Боржава, и увидеть противоположный склон хребта и гору Стой - самую высокую гору Боржавы. Еще через полчаса нам это удалось. Мы вышли на тропинку, идущую по хребту где-то посередине между горами Великий Верх и Гымба. Великий Верх возвышался где-то в километре справа, гора Стой виднелась впереди, а перед нами расстилался вид на долину и близлежащие горы. Мы были почти на 1400 м. Ветер был недетский и собирался дождь, поэтому мы решили не идти на Великий Верх, а начали быстро спускаться вниз. Путь наверх занял у нас полтора часа, путь вниз, с учетом десятиминутного отдыха под горой - час<font face="Arial">, прошли мы километров 8-10.</font></font></p> <p><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8IBPrFuI/AAAAAAAAJa4/nX7JeHYEcRU/IMG_48012.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4801" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8IlBs8UI/AAAAAAAAJa8/cs0PdOYK6qs/IMG_4801_thumb.jpg" width="244" border="0" /></a>&#160;<a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8JiY-2lI/AAAAAAAAJbA/g_H9QVT1Vcs/IMG_48242.jpg"></a><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8KEzySGI/AAAAAAAAJbE/guM16ZXIet4/IMG_48064.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4806" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8KtJXqQI/AAAAAAAAJbI/Uj7S99XkJTw/IMG_4806_thumb2.jpg" width="309" border="0" /></a><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4824" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8LVBKRqI/AAAAAAAAJbM/fUsUE3cRpmw/IMG_4824_thumb.jpg" width="244" border="0" /></a> </p> <p><font face="Arial">Не могу сказать, чтобы Боржава меня сильно поразила своей красотой - все-таки </font><a href="http://merle-amber.blogspot.com/2008/07/blog-post_31.html"><font face="Arial">Хамар-Дабан</font></a><font face="Arial"> значительно красивее. Но что-то притягательное есть и здесь. Самое интересное - это то, как меняется природа при подъеме наверх. Внизу уже вовсю зеленеют деревья и полно цветов, а здесь, наверху, еще ранняя весна: еле-еле видны почки на деревьях, кое-где еще лежит снег. Думаю, что летом на Боржаве просто изумительно, поэтому всем любителям природы я бы советовал сюда ехать именно летом или осенью - горы должны быть великолепны.</font></p> <p><font face="Arial">Спустившись с горы, мы еще раз зашли полюбоваться водопадом, после чего пошли в нашу гостиницу. Надо сказать, ребята сделали отличный выбор - этот трехэтажный деревянный дом имел большие по размеру номера, и приятную кухню со столовой. Здесь мы и скоротали наш вечер за ужином и общением.</font></p> <p><font face="Arial"><strong>День 6-7. Ужгород</strong></font></p> <p><font face="Arial">На следующее утро мы быстро позавтракали, собрались, узнали у хозяев дорогу на Подобовец и вышли на улицу. Погода стояла замечательная, и я то и дело фотографировал окрестности. Надо сказать, места здесь просто шикарные.</font></p> <p><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8MEf4MtI/AAAAAAAAJbQ/hfheDsflHw8/IMG_49392.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4939" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8Ms9I03I/AAAAAAAAJbU/yzKvsfnXqGw/IMG_4939_thumb.jpg" width="244" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8NWYZ5KI/AAAAAAAAJbY/foFY6v2W6H8/IMG_49425.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="172" alt="IMG_4942" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8N8XYm1I/AAAAAAAAJbc/N_a465ys8Z8/IMG_4942_thumb3.jpg" width="307" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8Ox-RAiI/AAAAAAAAJbg/f3D7Lab0J1k/IMG_49514.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="171" alt="IMG_4951" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8PZ3OK4I/AAAAAAAAJbk/dAGpe6wKycM/IMG_4951_thumb2.jpg" width="280" border="0" /></a> </p> <p><font face="Arial">Через полчаса мы уже были в Подобовце на трассе, а еще через полчаса сели в автобус на Ужгород, который идет через Воловец и Сваляву. Изначально мы планировали добираться до Ужгорода на электричке, но я ни разу не пожалел, что мы поехали автобусом - из поезда не увидишь и десятой доли того, что можно увидеть из автобуса.</font></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8QeQc5MI/AAAAAAAAJbo/JjFNVV1G3XI/IMG_49602.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4960" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8RIKF58I/AAAAAAAAJbs/QifBwFkzITE/IMG_4960_thumb.jpg" width="244" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8R2sfdAI/AAAAAAAAJbw/NVYEVr1qIhQ/IMG_49652.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4965" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8SsgC4EI/AAAAAAAAJb0/eMcmiY7R4Vo/IMG_4965_thumb.jpg" width="184" border="0" /></a> </p> <p><font face="Arial">Четыре часа спустя мы были в Ужгороде, где поселились в гостинице Интурист-Закарпатье. На самом деле, это обычная советская гостиница, немного прилизанная и чуть приукрашенная евроремонтом. Но старые уши совка торчат везде. Из достоинств гостиницы - приятный персонал, достаточно низкие цены и хороший вид из окна, если вам повезло со стороной, которая выходит на старый город. Впереди у нас был еще целый вечер, поэтому мы недолго думая умчались в центр.</font></p> <p><em><font face="Arial">Ужгород - самый маленький областной центр. В нем проживает всего около 115 тыс. жителей. Расположен он на самой границе со Словакией и недалеко от границы с Венгрией, что в достаточной степени определяет его культуру и образ жизни горожан. Ужгород - один из древнейших славянских городов. На протяжении своей истории Ужгород принадлежал Киевской Руси, Венгерскому королевству, Австрийской империи, Чехословакии, и лишь в 1945 году вошел в состав Украинской ССР. Самые известные памятники архитектуры - Ужгородский замок, римо-католический костел в стиле барокко, греко-католический и православный храмы, ратуша, епископский дворец, филармония (бывшая синагога). Здесь также стоит посетить Закарпатский музей народной архитектуры и быта, ботанический сад, художественный и краеведческий музеи, а также непременно прогуляться по набережным реки Уж и узким улочкам Старого города.</font></em></p> <p>&#160;<a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8TRtvSWI/AAAAAAAAJb8/3C7HmKeikFA/IMG_50912.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5091" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8T-osYxI/AAAAAAAAJcA/Yal1fUh74Xg/IMG_5091_thumb.jpg" width="184" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8Uj16x_I/AAAAAAAAJcE/Rh_lUuUMyZU/IMG_50252.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5025" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8Ve81RcI/AAAAAAAAJcI/PNtXkfvZPSk/IMG_5025_thumb.jpg" width="184" border="0" /> </a>&#160;<img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5083" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8VxMP5TI/AAAAAAAAJcM/T7uqFMwDPhg/IMG_5083_thumb.jpg" width="184" border="0" /> <a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8Ww4kF9I/AAAAAAAAJcQ/8FhaNBq1kaA/IMG_49672.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_4967" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8XQ3ZZUI/AAAAAAAAJcU/FiLo5NW0aEc/IMG_4967_thumb.jpg" width="244" border="0" /></a></p> <p><font face="Arial">Ужгород произвел на нас приятное впечатление. Чистенький, ухоженный, неторопливый. Настоящий кусочек Европы в Украине. Речка тоже порадовала своей чистотой и прозрачностью. С моста можно увидеть кучу форели, которая по какой-то причине не пытается убежать куда глаза глядят, а резвится на полуметровой глубине в больших количествах. Ее здесь запрещено ловить - вот и резвится. В этом маленьком примере - вся культура Закарпатья, где люди живут так, как мы, жители мегаполисов востока, не умеем, и может, никогда уже и не научимся: высаживают деревья, огораживают муравейники, ухаживают за природой, не пачкают реку. Я понимаю, что если бы в Ужгороде было не 115 тыс. жителей, а 2.5 млн, то мы бы еще посмотрели, где было бы чище, но все же мне кажется, что и в этом случае в Уже бы водилась форель, которую можно было бы увидеть с пешеходного моста в центре города...</font></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8YJhhirI/AAAAAAAAJcY/Q5SMyDOSFu8/IMG_49773.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="181" alt="IMG_4977" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8Y4xWQFI/AAAAAAAAJcc/xZWpt5gS7Ks/IMG_4977_thumb1.jpg" width="296" border="0" /></a><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8ZpMzuaI/AAAAAAAAJcg/OLluRTt4TAs/IMG_50323.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="181" alt="IMG_5032" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8af0TApI/AAAAAAAAJck/qx6rYPPmfOM/IMG_5032_thumb1.jpg" width="285" border="0" /></a></a><font face="Arial"></font></p> <p><font face="Arial">Пока мы гуляли по городу, мы нашли кафешку, где можно было посмотреть полуфинал кубка УЕФА, и успели порадоваться победе Шахтера, который через несколько недель стал обладателем Кубка УЕФА. Никогда раньше не смотрел футбол в кафе на улице - это действительно здорово!</font></p> <p><font face="Arial">Следующий день стал последним днем нашего маленького путешествия на Закарпатье. Его мы целиком и полностью посвятили прогулкам по узеньким улицам Старого города, и посещению местных достопримечательностей.</font></p> <p><font face="Arial">По дороге в центр города мы ненадолго остановились послушать детские и взрослые оркестры, которые на центральной площади города давали концерты - похоже, репетировали перед 9 мая.</font></p> <p><font face="Arial">Начали мы с Ужгородского замка. Я читал, что он уступает тому же Мукачевскому замку, да и ряду других, но в целом, было интересно побродить по залам, где когда-то звенели мечи и раздавались шаги средневековых рыцарей. К сожалению (а может, к счастью), замок сейчас принадлежит Краеведческому музею, поэтому бОльшая часть экспозиции - типичные краеведческие выставки: одежда, предметы быта, почва, животные. Правда, было несколько залов с интерьерами и один зал с оружием. Тут мы и оторвались, разглядывая разные мечи, сабли, доспехи, мушкеты и пистолеты. Сам замок очень фотогеничен, поэтому я получил огромное удовольствие, фотографируя его с разных ракурсов.</font></p> <p>&#160; <a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8bOAXsfI/AAAAAAAAJco/arWbN8JeEPo/IMG_51502.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5150" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8b7Y-ROI/AAAAAAAAJcs/tRGhxBc-Gjw/IMG_5150_thumb.jpg" width="184" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8c5cFMYI/AAAAAAAAJcw/9YHlHDKk1zE/IMG_50962.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_5096" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8dRPAxFI/AAAAAAAAJc0/WZWAszBf6Hw/IMG_5096_thumb.jpg" width="244" border="0" /></a> <a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8eorz48I/AAAAAAAAJc4/OYUFieRg9K8/IMG_51422.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_5142" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8fd7aelI/AAAAAAAAJc8/LbgD5ITdSi0/IMG_5142_thumb.jpg" width="244" border="0" /></a></p> <p><font face="Arial">Дальше по нашему плану шел Музей народной архитектуры и быта, где собрано несколько десятков деревянных хат, сарайчиков, и прочих построек со всего Закарпатья. Почти в каждую хату можно зайти и посмотреть, как жили представители разных сословий, профессий и даже национальностей. Гвоздем программы является настоящий деревянный храм, которыми так гордятся жители Закарпатской Руси.</font></p> <p><font face="Arial"><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8gHw1SNI/AAAAAAAAJdA/oN48A3t8ftk/IMG_51582.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5158" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8g_os9NI/AAAAAAAAJdE/UDXBKVYGbxQ/IMG_5158_thumb.jpg" width="184" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SiQ8hXynXsI/AAAAAAAAJdI/ymTjOwSr9G8/IMG_51842.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5184" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SiQ8iN37KrI/AAAAAAAAJdM/7XyO3iIIk6E/IMG_5184_thumb.jpg" width="184" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SiQ8jBT66wI/AAAAAAAAJdQ/GG4NKHt6ito/IMG_51612.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="IMG_5161" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SiQ8jzYu8oI/AAAAAAAAJdU/6kUKfWmqi30/IMG_5161_thumb.jpg" width="244" border="0" /></a> </font></p> <p><font face="Arial">Чуть ниже от замка и музея находится ботанический сад. Начитавшись информации о достопримечательностях, мы не поленились туда сходить, но на деле мы не увидели там ничего особенного. Поэтому, немного погуляв в одиночестве, мы выбрались оттуда и пошли ужинать - уже очень скоро нам нужно было идти на вокзал и выезжать в Харьков.</font></p> <p><font face="Arial">Так и закончилось наше первое путешествие в самую западную область нашей страны. Но уверен, что красота карпатских гор, прозрачность рек и приветливость населения еще не раз послужат нам стимулом вернуться сюда.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-4506912226408621860?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com5tag:blogger.com,1999:blog-1968777209535947779.post-88078730766953114232009-05-13T23:23:00.001+03:002009-05-13T23:24:46.951+03:00Закарпатье и Ужгород: фотографии<p><font face="Arial">Простите, что так долго не писал - было много работы + ездил на неделю на Закарпатье в поход. Собственно, результатами этой поездки и хотел бы поделиться :) Писать сейчас полный отчет времени, к сожалению, нет, но я это обязательно сделаю чуть позже. А пока что краткая информация и несколько наиболее удачных фотографий, на мой взгляд.</font></p> <p><font face="Arial">Маршрут похода проходил от озера Синевир, что в Межгорском районе, через горы Озерная, Менчилик вниз в долину реки Быстрая и по ней до деревни Верх-Быстрый. Оттуда на транспорте до Пилипца на водопад Шипот и Боржавский хребет (уже налегке). Люди, которые были в этом районе, думаю, сориентируются, а карту я нарисую позже. На все про все около 5 дней. После всего этого полдня до Ужгорода, поселение в гостиницу, прогулка по городу, просмотр полуфинала кубка УЕФА Динамо-Шахтер в кафешке на улице, целый следующий день в городе и отъезд в Харьков.</font></p> <p><font face="Arial">Надо сказать, что Закарпатье - удивительный край, очень красивый и богатый. Сами горы намного мощнее, чем тот же Крым, где почти с любой горы видно море, пару других гор и кучу деревень. Здесь же с горы открывается феноменальный вид, в котором горы не заканчиваются до самого горизонта. Не говоря уже про прекрасные буковые и хвойные леса, чистейшие родники и реки, богатую флору и фауну. В этом плане Карпаты очень напоминают <a href="http://merle-amber.blogspot.com/2008/07/blog-post_31.html">Хамар-Дабан</a>, где мы были прошлым летом. Ужгород тоже очень красив - это вообще Европа с украинским лицом. Менталитет жителей города, уровень их культуры очень похож на европейский, но в то же время многие вещи делаются с привычной небрежностью и некоторой расхлябанностью, которая так свойственна нам всем. Зато у этих людей есть то, чего так мало у восточных украинцев - желание беречь свою историю и то, что у них есть сейчас. Если разрушаются деревянные дома и церкви - их нужно собрать и сохранить для потомков, если разрушаются здания в городе - их нужно ремонтировать, если производится вырубка деревьев на горе - нужно тут же аккуратно посадить новые, если разрушаются муравейники - нужно старательно обнести их заборчиками. И таких примеров очень много. Про красоту города я вообще молчу - лучше об этом расскажут фотографии.</font></p> <p><font face="Arial"><strong>Карпаты:</strong></font></p> <p><font face="Arial"><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsruc5D_FI/AAAAAAAAJQ4/HF6J4AWOkvU/IMG_4285%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4285" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SgsrvBxKfWI/AAAAAAAAJQ8/MboW5mlo5nw/IMG_4285_thumb.jpg" width="244" border="0" /></a><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/Sgsrv34o4OI/AAAAAAAAJRA/pYhbFbqnTVM/IMG_4245%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4245" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SgsrwctuCxI/AAAAAAAAJRE/8E4d4_CIZDY/IMG_4245_thumb.jpg" width="244" border="0" /></a><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsrxacf-GI/AAAAAAAAJRI/xcwl1SA0q9s/IMG_4542%5B2%5D.jpg"><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SgsryRPkETI/AAAAAAAAJRM/oRWeV_j3nTY/IMG_4824%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4824" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SgsrzYzUj3I/AAAAAAAAJRQ/iYipakUWWUU/IMG_4824_thumb.jpg" width="244" border="0" /></a></a></font></p> <p><font face="Arial"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4542" src="http://lh6.ggpht.com/_lCZq7P5BnMo/Sgsrz0qnkOI/AAAAAAAAJRU/JbYQrid2S9k/IMG_4542_thumb.jpg" width="244" border="0" /><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4626" src="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsr0tx6LqI/AAAAAAAAJRY/era-Y5Zz91g/IMG_4626_thumb.jpg" width="244" border="0" /><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsr1dBjNaI/AAAAAAAAJRc/ymFc8an7jdo/IMG_4939%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4939" src="http://lh3.ggpht.com/_lCZq7P5BnMo/Sgsr1xFsnxI/AAAAAAAAJRg/_qywvet7i6M/IMG_4939_thumb.jpg" width="244" border="0" /></a>&#160; </font></p> <p><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsr2qKeEkI/AAAAAAAAJRk/l7wfKpmop5U/IMG_4663%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_4663" src="http://lh6.ggpht.com/_lCZq7P5BnMo/Sgsr3fTtSzI/AAAAAAAAJRo/_fdmVmeu308/IMG_4663_thumb.jpg" width="178" border="0" /></a><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsr4UTXCMI/AAAAAAAAJRs/6NuzeMzk-I8/IMG_4413%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_4413" src="http://lh6.ggpht.com/_lCZq7P5BnMo/Sgsr4wxLZ3I/AAAAAAAAJRw/G54eWOP61bM/IMG_4413_thumb.jpg" width="184" border="0" /><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/Sgsr58-O_VI/AAAAAAAAJR0/D1CxHFbC6pE/IMG_4187%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_4187" src="http://lh6.ggpht.com/_lCZq7P5BnMo/Sgsr6h6EfkI/AAAAAAAAJR4/Jt6SM9E1Wuc/IMG_4187_thumb.jpg" width="184" border="0" /></a></a><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/Sgsr7ZS-2bI/AAAAAAAAJR8/6blFJiyB11M/IMG_4736%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_4736" src="http://lh5.ggpht.com/_lCZq7P5BnMo/Sgsr8BMp0lI/AAAAAAAAJSA/HdNt_CBxN_Y/IMG_4736_thumb.jpg" width="184" border="0" /></a></p> <p><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/Sgsr83RhZEI/AAAAAAAAJSE/QjszrWTXpdU/IMG_4951%5B8%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="174" alt="IMG_4951" src="http://lh6.ggpht.com/_lCZq7P5BnMo/Sgsr-Mn6W3I/AAAAAAAAJSI/0qJf7aikviU/IMG_4951_thumb%5B6%5D.jpg" width="267" border="0" /></a><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/Sgsr_cgaMVI/AAAAAAAAJSQ/Epdn8pGvveg/IMG_4960%5B3%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="173" alt="IMG_4960" src="http://lh3.ggpht.com/_lCZq7P5BnMo/Sgsr_0lkA0I/AAAAAAAAJSU/krE48DzAWwU/IMG_4960_thumb%5B1%5D.jpg" width="227" border="0" /></a><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssA1gshrI/AAAAAAAAJSY/LCepWRqBvCU/IMG_4657%5B4%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="172" alt="IMG_4657" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SgssBpW62CI/AAAAAAAAJSc/H-8YPslAgOk/IMG_4657_thumb%5B2%5D.jpg" width="253" border="0" /></a></p> <p><font face="Arial"><strong>И Ужгород:</strong></font></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssCVddnBI/AAAAAAAAJSg/ZjC0gEW-jFU/IMG_5032%5B3%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="168" alt="IMG_5032" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SgssCxiVvBI/AAAAAAAAJSk/OAjaju9vUks/IMG_5032_thumb%5B1%5D.jpg" width="265" border="0" /></a><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SgssD-WFNTI/AAAAAAAAJSo/DeVW5JsLW9k/IMG_5142%5B2%5D.jpg"><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SgssE2T2_pI/AAAAAAAAJSs/nxiK82ETgQw/IMG_5190%5B4%5D.jpg"><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssFnG4BaI/AAAAAAAAJSw/jQXGedmsqFs/IMG_5065%5B3%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="166" alt="IMG_5065" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssGWle1oI/AAAAAAAAJS0/SkLwrCoxL_c/IMG_5065_thumb%5B1%5D.jpg" width="246" border="0" /></a><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="164" alt="IMG_5190" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssGxh0YBI/AAAAAAAAJS4/yHEIfHTUI_Q/IMG_5190_thumb%5B2%5D.jpg" width="234" border="0" /></a></a>&#160;</p> <p><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssH-sUIYI/AAAAAAAAJS8/qfgjhaJmeOM/IMG_4967%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_4967" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssISIGbVI/AAAAAAAAJTA/zXqNHRYd0Tg/IMG_4967_thumb.jpg" width="244" border="0" /></a><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_5142" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssJMTqLlI/AAAAAAAAJTE/amMRetZ6JTQ/IMG_5142_thumb.jpg" width="244" border="0" /><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssJ46wo_I/AAAAAAAAJTI/xbHatUb5JKk/IMG_5091%5B2%5D.jpg"><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssKkdZW5I/AAAAAAAAJTM/3YaO6LBnSEY/IMG_5151%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_5151" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SgssLfqS9xI/AAAAAAAAJTQ/aiTHZ4vUpMU/IMG_5151_thumb.jpg" width="244" border="0" /></a></a></p> <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_5091" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssMCvKclI/AAAAAAAAJTU/isaJVEQZHnU/IMG_5091_thumb.jpg" width="184" border="0" /><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SgssM8IRBFI/AAAAAAAAJTY/YJdnhDKIZn0/IMG_5150%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_5150" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssNUU9CFI/AAAAAAAAJTc/UVHZuC5zaHk/IMG_5150_thumb.jpg" width="184" border="0" /></a><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssONSKa6I/AAAAAAAAJTg/KU8apiaTrNk/IMG_5158%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_5158" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SgssO5SP8RI/AAAAAAAAJTk/VmY98EGcs20/IMG_5158_thumb.jpg" width="184" border="0" /></a><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SgssPlefLQI/AAAAAAAAJTo/Ia7ZQFHtLrA/IMG_5184%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_5184" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SgssQLT9kmI/AAAAAAAAJTs/1k_L0ZjMwe4/IMG_5184_thumb.jpg" width="184" border="0" /></a>&#160;&#160;&#160;&#160; </p> <p><font face="Arial">Посмотреть полный список фотографий можно здесь:</font></p> <p><font face="Arial">Карпаты - <a title="http://picasaweb.google.com/alexander.konduforov/200902#" href="http://picasaweb.google.com/alexander.konduforov/200902#">http://picasaweb.google.com/alexander.konduforov/200902#</a></font></p> <p><font face="Arial">Ужгород - <a title="http://picasaweb.google.com/alexander.konduforov/200903#" href="http://picasaweb.google.com/alexander.konduforov/200903#">http://picasaweb.google.com/alexander.konduforov/200903#</a></font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-8807873076695311423?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com4tag:blogger.com,1999:blog-1968777209535947779.post-78777574319522388192009-04-20T11:47:00.001+03:002009-04-20T11:47:50.045+03:00NHibernate – где узнать больше?<p><font face="Arial">Я вот довольно много пишу про Entity Framework и LINQ to SQL, но мало про другие ORM, особенно про NHibernate. Исправляюсь.</font></p> <p><font face="Arial">Ни для кого ни секрет, что несмотря на то, что </font><a href="http://www.hibernate.org/"><font face="Arial">NHibernate</font></a><font face="Arial"> – это очень мощный ORM, он достаточно сложен в освоении. Как модно сейчас говорить, у него слишком крутая кривая обучения (learning curve), на которую многим тяжело забраться, особенно в условиях сжатых сроков и рисков. И несмотря на то, что у наших друзей из java-community O/R Mappers в целом, и </font><a href="http://www.hibernate.org/"><font face="Arial">Hibernate</font></a><font face="Arial"> в частности пользуются популярностью уже давно, бОльшая часть .NET-программистов не пользовались этим продуктом, а многие даже и не знали о нем до выхода аналогов от Microsoft: LINQ to SQL и Entity Framework. К сожалению, .NET-сообщество программистов слишком часто не обращает внимания на то, что исходит не от Microsoft, или не доверяет этому, поэтому до недавнего времени NHibernate был интересен лишь очень небольшому проценту посвященных.</font></p> <p><font face="Arial">К слову, во многом это именно наша локальная проблема. В других странах существует так называемое </font><a href="http://msdn.microsoft.com/en-us/magazine/cc337902.aspx"><font face="Arial">ALT.NET-сообщество</font></a><font face="Arial"> (в основном, опенсорсной направленности), которые проводят </font><a href="http://www.altnetconf.com/"><font face="Arial">свои конференции</font></a><font face="Arial"> и встречи, обсуждая на них альтернативные инструменты и подходы к разработке приложений, отличающиеся от инструментов и подходов Microsoft, тем самым рекламируя их и продвигая. Многие из лидеров этого сообщества выступают с критикой продуктов от Microsoft, являясь по своей сути оппозицией в терминах, понятных нашей стране :) К слову сказать, благодаря этой “оппозиции” мы имеем достаточно серьезное движение Microsoft навстречу сообществу, более серьезное внимание к нуждам программистов, открытые исходные коды и целые проекты, идущие по open-source лицензиям.</font></p> <p><font face="Arial">Но это, скорее всего, вы и так уже знали… А заметка эта на самом деле о том, где узнать больше о NHibernate. К сожалению, на данный момент существует лишь одна книжка по NHibernate: </font><a href="http://www.amazon.com/NHibernate-Action-Pierre-Henri-Kuat%C3%A9/dp/1932394923"><font face="Arial">NHibernate in Action</font></a><font face="Arial">, которая до нашей страны дойдет, уверен, не скоро. Однако, есть довольно много альтернативных источников информации, которые, надеюсь, будут вам полезны:</font></p> <blockquote> <p><a title="http://www.nhibernate.org/" href="http://www.nhibernate.org/"><font face="Arial">http://www.nhibernate.org/</font></a><font face="Arial"> – официальный сайт, где есть полная документация</font></p> <p><a title="http://nhforge.org/" href="http://nhforge.org/"><font face="Arial">http://nhforge.org/</font></a><font face="Arial"> – ресурс, посвященный NHibernate, на котором есть </font><a href="http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx"><font face="Arial">Getting Started Guide</font></a><font face="Arial">, </font><a href="http://nhforge.org/blogs/nhibernate/"><font face="Arial">блоги</font></a><font face="Arial">, </font><a href="http://nhforge.org/wikis/"><font face="Arial">wiki</font></a><font face="Arial">, и </font><a href="http://nhforge.org/wikis/reference2-0en/nhibernate-2-0-reference-documentation.aspx"><font face="Arial">еще</font></a><font face="Arial"> </font><a href="http://nhforge.org/wikis/reference2-0en/default.aspx"><font face="Arial">много чего</font></a><font face="Arial"> </font><a href="http://nhforge.org/wikis/howtonh/default.aspx"><font face="Arial">полезного</font></a></p> <p><a title="http://blogs.hibernatingrhinos.com/nhibernate/Default.aspx" href="http://blogs.hibernatingrhinos.com/nhibernate/Default.aspx"><font face="Arial">http://blogs.hibernatingrhinos.com/nhibernate/Default.aspx</font></a><font face="Arial"> – NHibernate FAQ, фактически блог, который ведут разные авторы, много полезной информации</font></p> <p><a title="http://ayende.com/Blog/category/510.aspx" href="http://ayende.com/Blog/category/510.aspx"><font face="Arial">http://ayende.com/Blog/category/510.aspx</font></a><font face="Arial"> – категория NHibernate в блоге Oren Eine, одного из контрибьюторов (разработчиков) NHibernate, который в последнее время </font><a href="http://ayende.com/Blog/archive/2009/04/07/nhibernate-mapping-ltpropertygt.aspx"><font face="Arial">постит</font></a><font face="Arial">&#160;</font><a href="http://ayende.com/Blog/archive/2009/04/08/nhibernate-mapping-ltcomponentgt.aspx"><font face="Arial">очень</font></a><font face="Arial"> </font><a href="http://ayende.com/Blog/archive/2009/04/09/nhibernate-mapping-ltmany-to-onegt.aspx"><font face="Arial">много</font></a><font face="Arial"> </font><a href="http://ayende.com/Blog/archive/2009/04/11/nhibernate-mapping-ltdynamic-componentgt.aspx"><font face="Arial">информации</font></a><font face="Arial">&#160;</font><a href="http://ayende.com/Blog/archive/2009/04/13/nhibernate-mapping-ltsetgt.aspx"><font face="Arial">по маппингу</font></a><font face="Arial"> – на мой взгляд, самой высокой ступеньке в кривой обучения NHibernate</font></p> <p><a title="http://summerofnhibernate.com/" href="http://summerofnhibernate.com/"><font face="Arial">http://summerofnhibernate.com/</font></a><font face="Arial"> – видео обучалки (скринкасты) по NHibernate, для тех, у кого восприятие визуальной информации происходит лучше, чем восприятие текстовой, или кому просто нужно быстро разобраться на простых примерах</font></p> <p><a title="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx" href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx"><font face="Arial">http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx</font></a><font face="Arial"> – NHibernate best practices при разработке ASP.NET приложений</font></p> <p><a title="http://www.codeproject.com/KB/database/Nhibernate_Made_Simple.aspx" href="http://www.codeproject.com/KB/database/Nhibernate_Made_Simple.aspx"><font face="Arial">http://www.codeproject.com/KB/database/Nhibernate_Made_Simple.aspx</font></a><font face="Arial"> – еще одна интересная статья с CodeProject.com, вкратце обо всем</font></p> <p><a title="http://www.theserverside.net/tt/articles/showarticle.tss?id=NHibernate" href="http://www.theserverside.net/tt/articles/showarticle.tss?id=NHibernate"><font face="Arial">http://www.theserverside.net/tt/articles/showarticle.tss?id=NHibernate</font></a><font face="Arial"> – аналогично предыдущей, только с другого ресурса</font></p> </blockquote> <p><font face="Arial">Также я вам советую посмотреть следующие полезности, разработанные для NHibernate:</font></p> <blockquote> <p><a title="http://sourceforge.net/projects/nhcontrib" href="http://sourceforge.net/projects/nhcontrib"><font face="Arial">http://sourceforge.net/projects/nhcontrib</font></a><font face="Arial"> – NH Contrib, много полезных компонентов</font></p> <p><a title="http://code.google.com/p/sharp-architecture/" href="http://code.google.com/p/sharp-architecture/"><font face="Arial">http://code.google.com/p/sharp-architecture/</font></a><font face="Arial"> - Sharp Architecture – фреймворк для разработки веб-приложений с использованием ASP.NET MVC и NHibernate, рекомендуется для тех, кому нужны шаблоны использования NH с MVC, и кто хочет использовать готовый каркас приложения</font></p> <p><a title="http://nhplugin.lieser-online.de/" href="http://nhplugin.lieser-online.de/"><font face="Arial">http://nhplugin.lieser-online.de/</font></a><font face="Arial"> – поддержка NH в ReSharper, здесь добавить просто нечего</font></p> </blockquote> <p><font face="Arial">И, напоследок, еще парочка постов, похожих на мой, в которых вы найдете эти и другие полезные ссылки:</font></p> <blockquote> <p><a title="http://www.theserverside.net/news/thread.tss?thread_id=46642" href="http://www.theserverside.net/news/thread.tss?thread_id=46642"><font face="Arial">http://www.theserverside.net/news/thread.tss?thread_id=46642</font></a></p> <p><a title="http://www.thefreakparade.com/2008/07/so-you-want-to-learn-nhibernate-part-1-of-1-the-links/" href="http://www.thefreakparade.com/2008/07/so-you-want-to-learn-nhibernate-part-1-of-1-the-links/"><font face="Arial">http://www.thefreakparade.com/2008/07/so-you-want-to-learn-nhibernate-part-1-of-1-the-links/</font></a></p> </blockquote> <p><font face="Arial">Удачи в изучении NH.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-7877757431952238819?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com6tag:blogger.com,1999:blog-1968777209535947779.post-24516020330453821322009-04-12T21:59:00.001+03:002009-04-12T21:59:50.440+03:00Список интересных подкастов: выпуск #1<p><font face="Arial">Недавно прослушал несколько интересных подкастов. Хотел бы поделиться некоторыми наиболее интересными на мой взгляд:</font></p> <ul> <li><font face="Arial">.NET Rocks #411: </font><a href="http://www.dotnetrocks.com/default.aspx?showNum=411"><font face="Arial">Ward Bell on ORMs</font></a></li> </ul> <p><font face="Arial">Carl, Richard и Ward Bell обсуждают вопросы использования ORM в целом и Entity Framework в частности. Послушав этот подкаст, вы узнаете какие проблемы есть у Entity Framework v1.0 (дизайнер, POCO, etc.), еще раз про ситуацию с LINQ to SQL и Entity Framework, </font><a href="http://merle-amber.blogspot.com/2008/11/linq-to-sql-entity-framework.html"><font face="Arial">о которой я уже писал</font></a><font face="Arial">, почему NHibernate, несмотря на свои функциональные преимущества, не очень популярен в широких кругах программистов, когда стоит использовать ORM, когда не стоит, а также какие есть проблемы разработки RIA приложений, в частности проблема единственности модели данных, когда и на сервере, и на клиенте приходится делать одинаковую модель, чем тут может быть полезен DevForce .NET Silverlight-разработчикам (хотя после выхода RIA Services часть проблемы с моделью вроде бы как уходит).</font></p> <ul> <li><font face="Arial">.NET Rocks #422: </font><a href="http://www.dotnetrocks.com/default.aspx?showNum=422"><font face="Arial">Doug Crockford</font></a></li> </ul> <p><font face="Arial">Гость программы, Doug Crockford рассказывает про свой профессиональный опыт, а также про создание формата данных JSON, автором которого он является (!). Также довольно много обсуждений того, почему DOM - ахиллесова пята клиентских скриптов, различных стандартов, на которых строится JavaScript, а также его будущего. Весьма познавательно.</font></p> <ul> <li><font face="Arial">Hanselminutes #145: </font><a href="http://www.hanselminutes.com/default.aspx?showID=163"><font face="Arial">SOLID Principles with Uncle Bob - Robert C. Martin</font></a></li> </ul> <p><font face="Arial">Robert C. Martin (Uncle Bob) в гостях у Скотта рассказывает последнему, что такое Single Responsibility Principle, Open Closed Principle, Liskov Substitution Principle, Interface Segregation и Dependency Inversion Principle (SOLID). Очень детально и на примерах. Рекомендую всем, кто начинает понимать, что кроме внешнего качества продукта, есть еще его внутреннее качество - качество кода.</font></p> <ul> <li><font face="Arial">.NET Rocks #243: </font><a href="http://www.dotnetrocks.com/default.aspx?showNum=243"><font face="Arial">Scripps Institute</font></a></li> </ul> <p><font face="Arial">Просто отличный подкаст о людях, которые разрабатывают софт не только для крупных организаций, и не только за деньги. Приложение, которое вносит свою лепту в дело борьбы с раком, разработанное в Scripps Institute, в котором поучаствовало много программистов со всего мира, объединенных одной целью. WPF, Sharepoint, Scrum, и многое другое. Если вы хотите изменить мир к лучшему, то послушайте как это делают другие люди: возможно, у вас появится руководство к действию.</font></p> <ul> <li><font face="Arial">Hanselminutes #98: </font><a href="http://www.hanselminutes.com/default.aspx?showID=116"><font face="Arial">Scott Interviews His Dad</font></a></li> </ul> <p><font face="Arial">Совершенно не технический подкаст, в котором Скотт общается со своим отцом, пожарным, который сумел вырастить двух отличных сыновей, достигших успеха в своих областях. Много о детстве, воспитании, учебе, отсутствии денег и первом бизнесе, мудрых жизненных решениях и о том, как вырастить прекрасных сыновей. Потрясающий подкаст, в котором мало технической информации, зато много жизненного опыта. Рекомендую всем.</font></p> <p><font face="Arial">А какие подкасты нравятся вам?</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-2451602033045382132?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com4tag:blogger.com,1999:blog-1968777209535947779.post-68064860653349449872009-04-04T00:24:00.001+03:002009-04-04T00:35:11.265+03:00ASP.NET MVC: такие разные модели<p><font face="Arial">Как известно, ASP.NET MVC основан на паттерне </font><a href="www.rsdn.ru/article/patterns/modelviewpresenter.xml"><font face="Arial">Model-View-Controller</font></a><font face="Arial">. Первым компонентом этого паттерна является модель, которую я бы и хотел рассмотреть сегодня поподробнее.</font></p> <p><font face="Arial">Модель - это самый абстрактный компонент шаблона MVC. Моделью может быть все, что угодно, что не является контроллером и представлением :) На самом деле, модель - это то, что мы привыкли называть данными, и бизнес-логика, которая работает с этими данными, состояниями приложения и т.д. То есть, в терминах 3-звенной архитектуры, моделью можно назвать вашу бизнес-логику и все то, что лежит ниже ее, то есть слой доступа к данным и сами эти данные. А в терминах DDD моделью, наверно, можно назвать слой ваших сервисов и все, что под ним: репозитории, инфраструктуру и т.д. Причем данные эти могут находится абсолютно где угодно, а не только в базе данных: где-то на веб-сервисах, в файловой системе, распределенном кеше или даже в конфигурационном файле.</font></p> <p><font face="Arial">В ASP.NET MVC же модель - это несколько более широкое понятие, так как различных моделей в ASP.NET MVC не одна, а целых две. То, что мы рассмотрели выше, называется моделью предметной области, или доменной моделью (Domain Model). Однако есть еще одна модель - т.н. модель представления (View Model). Что же это такое?</font></p> <p><font face="Arial">View Model - это реализация одноименного подхода (или паттерна) к передаче данных в представление, который используется не только в ASP.NET MVC, но и в других местах, например, в Silverlight или WPF. View Model отличается от Domain Model тем, что он предназначен не для представления предметной области, а лишь для передачи данных из контроллера в представление в удобной форме. Ведь не всегда вашему представлению нужны все данные сущности, а иногда, наоборот, нужны данные в каком-нибудь специфическом аггрегированном формате, или просто набор этих данных, не связанный между собой ничем, кроме того факта, что он будет отображен на одной и той же странице. То есть, по сути, View Model - это некая проекция данных Domain Model, которая необходима конкретному представлению.</font></p> <p><font face="Arial">Например, у нас есть страница, которая показывает категории продуктов слева в меню, и список продуктов конкретной категории в области контента. Для отрисовки этой страницы (представления) ей необходимо получить от контроллера список категорий, выбранную категорию и список продуктов этой категории. Самый простой способ - передать эти данные через dictionary ViewData. Но это как-то не по-ковбойски :) Никакой безопасности типов + возможность ошибиться в строке ключа. Тогда остается лишь передавать данные через типизацию класса ViewPage&lt;Type&gt;, где Type - это тип передаваемого объекта, который будет доступен через свойство Model в представлении. Однако, у нас в Domain Model нет такого типа, который бы содержал две необходимые нам коллекции и одну сущность. Поэтому нужно его создать и назвать, например, ProductsListViewModel. Данный тип будет вспомогательным, его единственное назначение - это послужить контейнером для передачи данных из контроллера в представление.</font></p> <p><font face="Arial">Что это нам дает? Во-первых, теперь мы можем обращаться к переданной таким образом коллекции категорий следующим образом:</font></p> <pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100.66%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; height: 26px; background-color: #eee"><code>&lt;%= Model.Categories %&gt;<br /></code></pre><p><font face="Arial">Во-вторых, если мы когда-то решим, что нам бы не помешало создать Partial View (ascx-контрол, по-русски) для показа списка категорий, нам будет достаточно подключить его на страницу при помощи следующего вызова:</font></p><pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 101.36%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; height: 27px; background-color: #eee"><code>&lt;% Html.RenderPartial(&quot;CategoriesList&quot;, Model.Categories); %&gt;<br /></code></pre><p><font face="Arial">И даже если мы когда-нибудь захотим еще и подсвечивать выбранную категорию, то мы легко можем создать CategoriesListViewModel, который будет содержать коллекцию категории и ссылку на выбранную категорию, а потом использовать эту новую модель в ProductsListViewModel. При этом наш контрол будет наследоваться от ViewUserControl&lt;CategoriesListViewModel&gt;. Красота, все разложено по полочкам, предельно просто и понятно.</font></p><p><font face="Arial">Пара слов о том, где хранить созданные классы View Model. Как вы уже поняли, их может быть довольно много, в зависимости от количества представлений и их сложности. Я предложил бы хранить их в замечательной папочке Models, которую Visual Studio вам заботливо генерирует при создании проекта ASP.NET MVC. Классы Domain Model вы там все равно, скорее всего, хранить не будете (по крайней мере, я бы советовал для них создавать отдельную сборку). А если даже и будете, то никто не мешате создать две папки Model/DomainModel и Model/ViewModel.</font></p><p><font face="Arial">Самые внимательные уже наверно увидели сходство паттерна View Model с DTO (</font><a href="http://en.wikipedia.org/wiki/Data_Transfer_Object"><font face="Arial">Data Transfer Object</font></a><font face="Arial">). И сходство действительно есть, причем значительное. И там, и там - проекции данных для передачи куда-то. Только, в отличие от DTO, которые могут передаваться как угодно далеко, хоть на деревню дедушке, View Model объекты передаются всего лишь по соседству в представление. Так что можете пользоваться этой аналогией, если вам так будет проще понять смысл View Model и его назначение.</font></p><p><font face="Arial">Вот, вкратце, и все, что бы я хотел сказать по этому поводу. В заключение привожу небольшой набор полезных ссылок на описание разных моделей:</font></p><p><font face="Arial">Model:</font></p><p><a href="http://stephenwalther.com/blog/archive/2009/02/27/chapter-5-understanding-models.aspx"><font face="Arial">Stephen Walther: Understanding Models</font></a></p><p><font face="Arial">View Model:</font></p><p><a href="http://www.thoughtclusters.com/2007/12/datamodel-and-viewmodel.html"><font face="Arial">DataModel and ViewModel</font></a><font face="Arial"> </font><br/><a href="http://blogs.msdn.com/dancre/archive/2006/10/11/datamodel-view-viewmodel-pattern-series.aspx"><font face="Arial">DataModel-View-ViewModel pattern series</font></a></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-6806486065334944987?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com1tag:blogger.com,1999:blog-1968777209535947779.post-36792740339511363662009-03-29T22:11:00.001+03:002009-03-29T22:14:27.909+03:00Entity Framework vNext: сущности, сами отслеживающие свои изменения<p><font face="Arial">Команда ADO.NET продолжает свой эксперимент </font><a href="http://blogs.msdn.com/efdesign/default.aspx"><font face="Arial">по публичному проектированию следующей версии Entity Framework</font></a><font face="Arial">. Надо сказать, что результаты пока что весьма спорны: с одной стороны, они действительно публикуют все идеи и предлагают их обсуждать, с другой - очень часто возникает впечатление, что все решения уже приняты, и максимум, на что можно рассчитывать - это какие-то незначительные изменения в деталях.</font></p> <p><font face="Arial">Вот, например, одно из последних нововведений - это концепция </font><a href="http://blogs.msdn.com/efdesign/archive/2009/03/24/self-tracking-entities-in-the-entity-framework.aspx"><font face="Arial">сущности, которая сама отслеживает свои изменения</font></a><font face="Arial">. Я поначалу не до конца понял идею и до середины статьи думал, что ADO.NET team решил реализовать сделать свою версию </font><a href="http://www.castleproject.org/activerecord/index.html"><font face="Arial">Castle ActiveRecord</font></a><font face="Arial">, воспользовавшись </font><a href="http://merle-amber.blogspot.com/2009/02/orm.html"><font face="Arial">одноименным паттерном</font></a><font face="Arial">. Однако потом я-таки въехал в идею - никакого Active Record там нет. Смысл в том, что теперь у разработчиков появится возможность сгенерировать достаточно &quot;умные&quot; сущности (при помощи T4), которые будут сами отслеживать свое состояние и фиксировать изменения. Сохранять изменения в таких сущностях вы сможете просто вызвав метод ApplyChanges у ObjectContext, которому вы можете передать подобный объект (да, наверно, и коллекцию). Кроме того, если вы просто создадите эту сущность, она будет жить с состоянием Added до тех пор, пока кто-то не решит записать ее в базу. Фактически, теперь вы можете создать сущность при помощи одного контекста, а потом сохранить при помощи другого, то есть сущность становится намного более независимой от контекста, который ее породил. В статье подобная сущность даже называется POCO-объектом, хотя все-таки до true POCO там еще далеко.</font></p> <p><font face="Arial">Что же тут такого полезного? Ведь и раньше вроде бы можно было отсоединять сущности от одного контекста, и присоединять их потом к другому. Можно было, но только вот все изменения сущности при этом терялись как при отсоединении, так и при присоединения, т.к. сущности первой версии не обладают способностью отслеживать свои изменения, эта функция доступна лишь контексту. И это как раз и порождало кучу проблем, связанных с тем, что для обеспечения нормального взаимодействия между несколькими сущностями, было необходимо, чтобы они были созданы в одном и том же контексте. А это не очень приятно для сценариев, в которых сущности живут в приложении немножко дольше, чем время вызова одного-двух методов. Теперь же эта проблема решена.</font></p> <p><font face="Arial">Однако, лично у меня возникает один вопрос: как быть с ассоциациями (навигационными свойствами)? Теперь, когда сущность отделена от контекста, она не может им воспользоваться для того, чтобы заполнить данными незагруженное навигационное свойство. Как быть? Задал вопрос разработчикам там же в комментариях - может, ответят.</font></p> <p><font face="Arial">Другие нововведения:</font></p> <p><font face="Arial">1) </font><a href="http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx"><font face="Arial">Новый тип ассоциаций (foreign key)</font></a> <br /><font face="Arial">2) </font><a href="http://blogs.msdn.com/efdesign/archive/2009/01/22/customizing-entity-classes-with-t4.aspx"><font face="Arial">Упрощенная настройка шаблонов генерации сущностей (T4)</font></a> <br /><font face="Arial">3) </font><a href="http://blogs.msdn.com/efdesign/archive/2009/01/07/model-defined-functions.aspx"><font face="Arial">Функции, определяемые в модели</font></a> <br /><font face="Arial">4) </font><a href="http://blogs.msdn.com/efdesign/archive/2008/11/20/n-tier-improvements-for-entity-framework.aspx"><font face="Arial">Общие улучшения для N-tier архитектур</font></a> <br /><font face="Arial">5) </font><a href="http://blogs.msdn.com/efdesign/archive/2008/09/10/model-first.aspx"><font face="Arial">Концепция подхода Model First</font></a> <br /><font face="Arial">6) и многое другое (там действительно куча информации)</font></p> <p><font face="Arial">PS. Надо сказать, нашумевший </font><a href="http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/"><font face="Arial">Vote of no confidence</font></a><font face="Arial">, о котором </font><a href="http://merle-amber.blogspot.com/2008/08/entity-framework-vote-of-confidence.html"><font face="Arial">я уже писал</font></a><font face="Arial">, сделал свое дело, и вторая версия EF будет намного более солидной и зрелой. Еще бы немножко </font><a href="http://merle-amber.blogspot.com/2009/01/linq-to-sql-entity-framework.html"><font face="Arial">улучшить производительность</font></a><font face="Arial"> - и будет достаточно интересная альтернатива NHibernate.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-3679274033951136366?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com0tag:blogger.com,1999:blog-1968777209535947779.post-84149209473350833112009-03-21T19:43:00.001+02:002009-03-21T19:43:15.407+02:00Материалы доклада по ASP.NET MVC<p><font face="Arial">Как я и обещал, выкладываю материалы доклада по ASP.NET MVC, который я делал в прошедшую пятницу, 20 марта, на очередной встрече UNETA в Харькове.</font></p> <p><font face="Arial">Презентация:</font></p> <div id="__ss_1178141" style="width: 425px; text-align: left"><a title="ASP.NET MVC: new era?" style="display: block; margin: 12px 0px 3px; font: 14px helvetica,arial,sans-serif; text-decoration: underline" href="http://www.slideshare.net/AlexMerle/aspnet-mvc-new-era?type=presentation">ASP.NET MVC: new era?</a><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=asp-netmvc-090321122329-phpapp01&amp;stripped_title=aspnet-mvc-new-era" width="425" height="355" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" /> <div style="font-size: 11px; padding-top: 2px; font-family: tahoma,arial; height: 26px">View more <a style="text-decoration: underline" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration: underline" href="http://www.slideshare.net/AlexMerle">AlexMerle</a>.</div> </div> <p><font face="Arial">Исходный код тестового приложения выкладывать не буду, т.к. есть отличный пример <a title="http://nerddinner.codeplex.com/" href="http://nerddinner.codeplex.com/">http://nerddinner.codeplex.com/</a>, о котором <a href="http://merle-amber.blogspot.com/2009/03/blog-post_13.html">я уже упоминал</a>, и к которому мне особо добавить нечего. Пользуйтесь им для ознакомления и изучения. Очень маленькое 185-страничное описание этого приложения можно найти <a href="http://www.wrox.com/WileyCDA/Section/id-321793.html">здесь</a>, а живую попытку Скотта Хенселмана (<a href="http://www.hanselman.com/blog/">Scott Hanselman</a>) написать это приложение перед широкой аудиторией за 75 минут с перерывами на шутки - <a href="http://sessions.visitmix.com/MIX09/T49F">здесь</a>. Кстати, там внизу можно его скачать и насладиться просмотром на скорости 1.3-1.4, если у вас не так много времени :) На <a href="http://sessions.visitmix.com/">главной странице MIX'09</a> вы также можете найти кучу других интересных докладов, особенно по ASP.NET MVC и Silverlight. Такое впечатление, что MIX'09 прошел под эгидой этих двух технологий. В общем, рекомендую.</font></p> <p><font face="Arial">Да! Чуть не забыл. А если все получится, то, возможно, чуть позже будет еще и видео :)</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-8414920947335083311?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com2tag:blogger.com,1999:blog-1968777209535947779.post-136307583685010612009-03-18T21:05:00.001+02:002009-03-18T21:05:59.245+02:00ASP.NET MVC 1.0 released<p><font face="Arial">Я еще не нашел официального подтверждения, но на Microsoft Downloads он уже висит:</font></p> <p><a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&amp;displaylang=en"><font face="Arial">http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&amp;displaylang=en</font></a></p> <p><font face="Arial">Думаю, в ближайшее время об этом будет официально объявлено на MIX'09 :)</font></p> <p><font face="Arial">Вдобавок сообщаю, что в эту пятницу, 20 марта, я буду делать <a href="http://uneta20032009.events.live.com/">доклад по ASP.NET MVC на харьковской UNETA</a>. Какое приятное совпадение, правда? :) Так что с одной стороны поздравляю всех, что ЭТО произошло, а с другой приглашаю на нашу встречу. С учетом того, что второй доклад будет по Silverlight, а докладчиками будут Сергей Лутай и Андрей Каща, уверен, что будет интересно.</font></p> <p><font face="Arial">Приходите.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-13630758368501061?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com4tag:blogger.com,1999:blog-1968777209535947779.post-40658444275122530962009-03-13T10:27:00.001+02:002009-03-13T10:27:51.199+02:00Обеды для гиков<p><font face="Arial">Несколько всем известных гиков (nerds, geeks), <a href="http://weblogs.asp.net/scottgu/">Scott Guthrie</a>, <a href="http://www.hanselman.com/">Scott Hanselman</a>, <a href="http://blog.wekeroad.com">Rob Conery</a> и <a href="http://haacked.com/">Phil Haack</a>, пишут <a href="http://www.wrox.com/WileyCDA/Section/id-321793.html">книгу об ASP.NET MVC</a>, который они же, собственно, и разрабатывают. Книжка эта, надеюсь, будет доступна уже довольно скоро, а пока что они решили выложить <a href="http://aspnetmvcbook.s3.amazonaws.com/aspnetmvc-nerdinner_v1.pdf">отрывок книги в бесплатный доступ</a>. В отрывке этом описывается процесс создания сайта <a title="http://www.nerddinner.com/" href="http://www.nerddinner.com">http://www.nerddinner.com</a>, который предназначен для того, чтобы помочь другим гикам отрываться от своих любимых компьютеров, собираться в кучки за завтраком/обедом/ужином и обсуждать свои гиковские темы под пиво/виски/сок.</font></p> <p><font face="Arial">Так что всем, кто хочет побыстрее окунуться в изучение новой веб-технологии, и заодно на реальном примере посмотреть, как правильно разрабатывать приложения на ASP.NET MVC, рекомендуется зайти на <a title="http://nerddinner.codeplex.com/" href="http://nerddinner.codeplex.com/">http://nerddinner.codeplex.com</a> и скачать оттуда исходный код и тесты.</font></p> <p><font face="Arial">Тем же, кто проникнулся идеей организовать первый гиковский обед на просторах бывшего СССР, никто не запрещает это делать. Жаль только, что сайт этот пока что не сильно распространен в нашей части света, поэтому не ожидайте большого наплыва желающих, разве что вы не пнете их сами :)</font></p> <p><font face="Arial">Посты авторов об этом событии:</font></p> <p><a title="http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx" href="http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx"><font face="Arial">http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx</font></a> <br /><a title="http://www.hanselman.com/blog/FreeASPNETMVCEBookNerdDinnercomWalkthrough.aspx" href="http://www.hanselman.com/blog/FreeASPNETMVCEBookNerdDinnercomWalkthrough.aspx"><font face="Arial">http://www.hanselman.com/blog/FreeASPNETMVCEBookNerdDinnercomWalkthrough.aspx</font></a> <br /><a title="http://blog.wekeroad.com/blog/nerddinner-and-a-free-book/" href="http://blog.wekeroad.com/blog/nerddinner-and-a-free-book/"><font face="Arial">http://blog.wekeroad.com/blog/nerddinner-and-a-free-book/</font></a> <br /><a title="http://haacked.com/archive/2009/03/10/chapter-one-pro-aspnetmvc.aspx" href="http://haacked.com/archive/2009/03/10/chapter-one-pro-aspnetmvc.aspx"><font face="Arial">http://haacked.com/archive/2009/03/10/chapter-one-pro-aspnetmvc.aspx</font></a></p> <p><font face="Arial">Кстати, кто еще не успел проникнуться идеей о том, что MVC – это шаг в правильном направлении для веб-разработки и наше общее будущее, можете узнать о нем больше <a href="http://www.asp.net/mvc/">на официальном сайте</a>, где уже собралось довольно много материалов и видео-уроков, полностью описывающих процесс создания приложения и различные tips &amp; tricks. И еще, кроме блогов вышеперечисленных товарищей, рекомендую <a href="http://stephenwalther.com/">блог Stephen Walther’а</a>, который содержит ОЧЕНЬ много советов и трюков по ASP.NET MVC и отрывки из будущей книги Стивена по все тому же ASP.NET MVC.</font></p> <p><font face="Arial">Приятных обедов! :)</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-4065844427512253096?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com0tag:blogger.com,1999:blog-1968777209535947779.post-91115180128051887712009-03-12T11:37:00.001+02:002009-03-12T11:37:10.313+02:00О философии в программировании (и не только)<p><font face="Arial">Очень понравились несколько философских фраз, которые запросто подходят и к программированию, поэтому оставляю здесь – удобно ссылаться в будущем, и, может, кто-то еще не видел :)</font></p> <p><font face="Arial"><strong>Классика кунг-фу</strong> (<a href="http://www.rsdn.ru/Forum/Info/FAQ.philosophy.kungfu.aspx">взято с RSDN</a>):</font></p> <p><font face="Arial">Сначала ты не знаешь, что нельзя делать то-то. <br />Потом знаешь, что нельзя делать то-то. <br />Потом ты понимаешь, что иногда таки можно делать то-то. <br />Ну, а потом ты понимаешь, что помимо того-то существует еще шестьдесять шесть способов добиться желаемого, и все из них практически равноправны. <br />Когда тебя спрашивают &quot;как мне добиться желаемого&quot;, ты быстро перебираешь в уме эти шестьдесять шесть способов, прикидываешь то общее, что в них есть, вздыхаешь и говоришь: &quot;Вообще-то, главное – это гармония.&quot; <br />И на вопрос обиженных учеников: &quot;А как ее добиться?&quot;, ты говоришь: &quot;Никогда не делайте то-то&quot;.</font></p> <p><font face="Arial">Сколько раз уже убеждался в простоте и правоте этой формулировки…</font></p> <p><font face="Arial"><strong>Искусство мыть слона</strong></font></p> <p><font face="Arial">Слон большой. В нём много работы вообще и даже много разных видов работ. Нужно знать, что делать, когда делать, когда переставать это делать. <br />* Какую часть слона ты начнёшь мыть первой? <br />* Когда сочтёшь её чистой и перейдёте к следующей части? <br />* Как, собственно, убедить других, что слон уже вымыт (у них может быть и, по-видимому, действительно будет своё мнение по этому вопросу)?</font></p> <p><font face="Arial">Суть в том, что не стоит браться за мытье сразу всего слона. Ответь на мелкие вопросы и получишь более полный ответ и понимание, куда двигаться дальше.</font></p> <p><font face="Arial">За последнее особая благодарность <a href="http://anvaka.blogspot.com/">Андрею Каще</a>, который привел эту фразу в качестве аргумента в нашей дискуссии. Да, и еще Андрей недавно написал очень хорошую <a href="http://www.rsdn.ru/article/testing/UnitTesting.xml">статью по модульному тестированию</a>.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-9111518012805188771?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com1tag:blogger.com,1999:blog-1968777209535947779.post-25673161978791067182009-03-11T00:17:00.001+02:002009-03-11T00:17:01.407+02:00Кеширование и Silverlight<p><font face="Arial">На днях столкнулся на работе с интересной ситуацией, которая в который раз напомнила о том, что .NET веб-программирование - это не только ASP.NET, но еще и куча всего под ним, благодаря чему этот ASP.NET, собственно, и работает. И что знание одного лишь ASP.NET не делает вас настоящим веб-программистом. Нужно знать еще много чего, начиная от HTML/CSS/JS и вплоть до протокола HTTP (хотя бы в какой-то мере). Вот и в нашем случае для решения проблемы понадобились знания HTTP-кеширования...</font></p> <p><font face="Arial">HTTP-кеширование - это кеширование страниц и других запрашиваемых ресурсов на машине пользователя или промежуточных прокси-серверах. Делается это, естественно, для того чтобы не загружать их постоянно с сервера и таким образом уменьшить трафик и увеличить производительность приложения. Управление кешированием происходит при помощи HTTP-заголовков. Для управления кешированием используются следующие заголовки: Expires, Last-Modified/If-Modified-Since, ETag/If-None-Match, Cache-Control, Pragma, X-Cache (который не является стандартным HTTP-заголовком, но тем не менее используется веб-серверами и прокси-серверами вроде squid) и т.д.</font></p> <p><font face="Arial">Я бы не хотел сейчас останавливаться на описании всех этих заголовков: со многими из них вы уже знакомы. Всех заинтересовавшихся отправляю читать <a href="http://bogdan.org.ua/2006/10/18/http-caching-request-and-response-headers.html">несколько</a> <a href="http://nomagic.ru/all.php?aid=58">интересных</a> <a href="http://www.mnot.net/cache_docs/">статей</a>, а остальным расскажу про наш опыт, чтобы не наступили на те же грабли.</font></p> <p><font face="Arial">Итак, есть Silverlight-приложение, которое на веб-сервере представлено XAP-файлом. Наверно, вы в курсе, что во избежание постоянных загрузок этих иногда очень даже немаленьких файлов с сервера, XAP-файлы по умолчанию кешируются в браузере. Ну, как обычные ZIP-файлы, например. Так вот, заливаем мы обновленную версию XAP-файла на удаленный сервер, пробуем запустить с одного компьютера - приложение обновлено, с другого - нет, показывается старая версия (тут необходимо отметить, что компьютеры находятся в разных локальных сетях). Ну, закешировал браузер, с кем не бывает. Очищаем кеш в FF - не работает, по-прежнему старая версия. Делаем Ctrl-F5 в IE - то же самое. Никаких изменений. Чешем репу, пробуем еще раз. И еще раз. С разными вариациями. Лезем в гугл - гугл что-то говорит <a href="http://silverlight.net/forums/p/34833/105136.aspx">по поводу</a> <a href="http://silverlight.net/forums/t/11995.aspx">кеширования</a> SL-приложений, что нужно настроить в IIS опцию не кешировать приложение (свойства XAP файла в IIS -&gt; HTTP Headers таб -&gt; &quot;Enable Content Expiration&quot; -&gt; &quot;Expire Immediately&quot; с вариациями в зависимости от версии IIS). Пробуем - не получается. Похоже, придется все-таки включать голову. Берем <a href="http://www.fiddlertool.com/fiddler/">Fiddler</a>, запускаем, смотрим запросы на XAP-файл. Так и есть, берет из кеша браузера. Делаем Ctrl-F5 - запрос уходит, файл получен заново... но он старый! Быстро вспоминаем, где еще могут быть закешированы файлы - на прокси-серверах. Ага! Быстрая проверка с удалением файла на сервере, который тем не менее, отлично заново откуда-то загружается подтверждает теорию. HTTP-заголовки тоже ее подтвержают:</font></p> <p><font face="Courier New">Date: Thu, 05 Mar 2009 09:08:19 GMT <br />Age: 454965</font></p> <p><font face="Arial">Значит, файл действительно закеширован на прокси-сервере. Заголовок X-Cache (если вам повезло и он есть) позволяет даже узнать на каком:</font></p> <p><font face="Courier New">X-Cache: HIT from &lt;domain.com&gt;</font></p> <p><font face="Arial">Здесь &lt;domain.com&gt; - адрес нашего родного корпоративного проксика :) Дальше дело за малым - перенастроить squid, чтобы он не кешировал запросы с корпоративного staging-сервера - и готово. Или еще не готово?</font></p> <p><font face="Arial">Конечно, не готово. А если у клиента или его end-user'ов прокси-сервер тоже настроен таким же образом? С одной стороны, это не так страшно, если вы не собираетесь часто обновлять приложение, но с другой стороны наш случай показал, что простое обновление файла НЕ СБРАСЫВАЕТ кеш прокси-сервера! То есть браузер получает файл прямо из прокси, а тот даже думать не желает лезть за обновлением на веб-сервер. Почему? Так настроен Cache-Control, который, во-первых, public (то есть доступен для кеширования не только в браузере, но и на прокси-серверах), а во-вторых, не содержит опции по проверке обновления файла по умолчанию. Из этого следует, что в случае, если между приложением и клиентом находится кеширующий прокси, и вы обновили приложение, то пользователи не увидят его до тех пор, пока кеш прокси-сервера не сбросится. А это не всегда приемлемо.</font></p> <p><font face="Arial">Как же решить проблему раз и навсегда? Можно рубануть с плеча и поступить так, как советуют люди, установив опцию &quot;Expire Immediately&quot; для вашего XAP-файла в IIS. Но если вы сделаете это, то у вас КАЖДЫЙ запрос пользователя будет заканчивать перезагрузкой файла с сервера. Что при размере последнего больше 500 Кб-1 Мб равносильно самоубийству в особо извращенной форме для какого-нибудь вебдванольного сайта с большим количеством посещений. Есть ли способ гуманнее? Да, есть, хотя я еще и не пробовал его, поэтому действуйте на свой страх и риск. Поскольку IIS не дает нам сильно разбежаться в плане установки своих кастомных заголовков для файлов, то <a href="http://silverlight.net/forums/t/11995.aspx">здесь</a> в одном из ответов рассказывается, как сделать HTTP-хендлер, который будет устанавливать необходимые заголовки (как минимум Cache-Control: private для production и no-cache или даже no-store для девелоперских машин). К слову, это же поможет вам и в девелопменте, т.к. каждый раз давить Ctrl-F5 или очищать кеш в FF - это тоже не выход, на мой взгляд. Описывать реализацию не буду - думаю, сами справитесь да и время уже позднее :)</font></p> <p><font face="Arial">Удачи вам в Silverlight-девелопменте!</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-2567316197879106718?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com2tag:blogger.com,1999:blog-1968777209535947779.post-57597647384412594442009-03-05T15:18:00.001+02:002009-03-05T15:18:59.332+02:00Будущее тестирования от Microsoft<p><font face="Arial">Всем девелоперам, QA и менеджерам советую <a href="http://www.dotnetrocks.com/default.aspx?showNum=408">подкаст .NET Rocks по тестированию</a>. В гостях – <a href="http://blogs.msdn.com/james_whittaker/">James Whittaker</a>, Software Architect из Microsoft, который всю жизнь посвятил тестированию, а также написал кучу научных работ, посвященных этому предмету.</font></p> <p><font face="Arial">Девелоперам стоит послушать про то, что такое тестирование на самом деле, чем отличается тестирование на стороне девелопмента и на стороне тестирования, а также, наконец, понять, что QA – это не человек, который хочет сломать то, что ты написал, а человек, проверяющий качество продукта и несущий за это качество ответственность. Также немного обсуждается unit-тестирование, TDD и работа с legacy-кодом.</font></p> <p><font face="Arial">QA стоит послушать про то, как тестируют в Microsoft, как Джеймс понимает тест кейсы, в чем их проблемы, что такое покрытие тест кейсами продукта и как достичь его максимума. Но самое главное, Джеймс рассказывает кое-что про новые фичи VS 2010 для тестирования и свои идеи про то, как должно выглядеть тестирование в будущем. Test cases, которые сами оповещают QA, что их необходимо проверить после изменения кода. Или которые являются переносимыми и настолько умными, что могут сами определить, что именно нужно протестировать на новом проекте. Или автоматические тесты, которые подобно нанороботам расползаются по приложению и тестируют его сами. Ну, это уже фантастика, но компьютер когда-то тоже был фантастикой :) В общем, взрыв мозга в определенной степени.</font></p> <p><font face="Arial">Менеджерам и лидам стоит послушать про организацию тестирования в Google и Microsoft, а также размышления на тему, какое должно быть соотношение девелоперов к тестерам.</font></p> <p><font face="Arial">И еще пара шуток оттуда же:</font></p> <blockquote> <p><font face="Arial">- why did it take God only seven days to create the universe?</font></p> <p><font face="Arial">- no installed dates, no legacy to screw up. You want a planet there, put a planet there. Super nova there...</font></p> <p><font face="Arial">-----------------------</font></p> <p><font face="Arial">Возможно, вы уже слышали, что green field – это код, который пишется с чистого листа, а brown field – это код, который пишется на базе другого кода (legacy). Ну, аналогия понятна: зеленая трава, пожухлая трава. Brown field очень часто дает кучу проблем на голову, т.к. нужно слишком много поменять, чтобы продолжить работу. Так что есть еще одна аналогия :) “It was the Greenfield and Brownfield development and I like to joke that we know what's making the field brown, don't we? :)”</font></p> </blockquote> <p><font face="Arial">В общем, рекомендую. И наверно, буду почаще что-то стоящее рекомендовать из того, что слушаю.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-5759764738441259444?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com5tag:blogger.com,1999:blog-1968777209535947779.post-42651475954230151962009-02-22T19:16:00.001+02:002009-02-22T19:16:02.923+02:00Немного о дизайне: паттерны из мира ORM<p><font face="Arial">Наверняка, каждый программист слышал о паттернах (шаблонах) проектирования, читал </font><a href="http://en.wikipedia.org/wiki/Design_Patterns_(book)"><font face="Arial">классику</font></a><font face="Arial">, и с той или иной периодичностью использует паттерны в повседневной работе для того, чтобы сделать дизайн своего приложения более понятным и масштабируемым. Если вы когда-нибудь пробовали использовать Linq to SQL, Entity Framework, NHibernate или другие ORM, то вы, конечно же, заметили, что у них есть много общего. L2S и EF с некоторого расстояния вообще выглядят, как близнецы-братья, да и остальные ORM тоже недалеко ушли. Вы думаете, это совпадение? Вовсе нет. Просто все они строятся с использованием одних и тех же паттернов проектирования.</font></p> <p><em><font face="Arial">Примечание. Хотел бы отметить, что использовать мы будем терминологию небезызвестного </font></em><a href="http://en.wikipedia.org/wiki/Martin_Fowler"><em><font face="Arial">Мартина Фаулера</font></em></a><em><font face="Arial">, который является общепризнанным авторитетом в дизайне приложений, и его </font></em><a href="http://martinfowler.com/eaaCatalog/"><em><font face="Arial">каталог &quot;архитектурных&quot; паттернов</font></em></a><em><font face="Arial">.</font></em></p> <p><font face="Arial">Начнем с того, что каждый ORM имеет в своем составе некий &quot;менеджер&quot; (например, контекст в L2S и EF, или сессию в NH), который является неким логическим фасадом (<a href="http://en.wikipedia.org/wiki/Facade_pattern">Facade</a></font><font face="Arial">) к базе данных. Этот фасад, как правило, &quot;понимает&quot; определенный маппинг объектов приложения на таблицы базы данных, &quot;умеет&quot; принимать на вход простые и сложные запросы на получение объектов, знает, &quot;какие&quot; изменения объектов и &quot;как&quot; сохранить в базе данных, и многое другое. Рассмотрим, какие паттерны работают внутри и рядом с ним.</font></p> <p><strong><font face="Arial">Unit of Work</font></strong></p> <p><a href="http://martinfowler.com/eaaCatalog/unitOfWork.html"><font face="Arial">Unit of Work</font></a><font face="Arial"> - наверно, самый популярный паттерн модификации данных. Он описывает следующую стратегию работы с данными:</font></p> <ol> <li><font face="Arial">Получили объекты из ORM</font></li> <li><font face="Arial">Изменили какое угодно их количество</font></li> <li><font face="Arial">Сказали ORM сохранить данные в базу (или откатиться)</font></li> <li><font face="Arial">ORM сохранил все изменения одним махом (или откатился)</font></li> </ol> <p><font face="Arial">Даже если вы никогда в жизни в глаза не видели ORM, то знакомо, не правда, ли? Конечно, именно по такому же принципу работает старая-добрая пара DataAdapter - DataSet в plain ADO.NET. И точно так же работают как контексты L2S и EF, так и сессия NH. Unit of Work работает благодаря тому, что он хранит в себе ссылки на все объекты, которые были созданы/получены через него. Именно поэтому без дополнительных телодвижений вам не удастся заставить контекст EF сохранить объект, который был изменен в рамках другого контекста, а потом приаттачен к текущему. Контекст просто не знает, какие изменения были сделаны в объекте, т.к. это не забота объекта &quot;знать&quot; о своих изменениях, а забота окружения, коим и является для объекта контекст/сессия.</font></p> <p><font face="Arial">Паттерн Unit of Work полезно использовать и в других случаях. Например, когда вам необходимо дать пользователю возможность изменить определенные данные приложения в памяти, а потом нажатием на одну кнопку сохранить их в базу данных. Или не сохранить.</font></p> <p><strong><font face="Arial">Active Record</font></strong></p> <p><font face="Arial">В противовес предыдущему паттерну, паттерн </font><a href="http://martinfowler.com/eaaCatalog/activeRecord.html"><font face="Arial">Active Record</font></a><font face="Arial"> определяет, что объект <u>сам</u> знает, как себя извлечь из базы данных и сохранить изменения туда же. То есть объекту больше не нужны внешние &quot;менеджеры&quot;, он сам в состоянии за себя постоять.</font></p> <p><font face="Arial">В целом, использование этого паттерна остается </font><a href="http://kore-nordmann.de/blog/why_active_record_sucks.html"><font face="Arial">достаточно</font></a><font face="Arial"> </font><a href="http://blog.mikeseth.com/index.php?/archives/4-ActiveRecord-sucks,-but-Kore-Nordmann-is-wrong.html"><font face="Arial">спорным</font></a><font face="Arial">, т.к. объект в таком случае &quot;знает&quot; о способе сохранения себя в базе, и поэтому крепко связан с ней, нарушая при этом </font><a href="http://www.codeinsanity.com/2008/08/persistence-ignorance-and-ddd-with.html"><font face="Arial">Persistence Ignorance</font></a><font face="Arial">. Кроме того, если подобный объект содержит бизнес-логику, то он еще и нарушает </font><a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"><font face="Arial">Single Responsibility Principle</font></a><font face="Arial">. С другой стороны, у Active Record есть свои преимущества и </font><a href="http://karwin.blogspot.com/2008/05/activerecord-does-not-suck.html"><font face="Arial">сторонники</font></a><font face="Arial">. Из широко распространенных ORM паттерн ActiveRecord используется как минимум в </font><a href="http://www.castleproject.org/ActiveRecord/"><font face="Arial">Castle ActiveRecord</font></a><font face="Arial"> (кто бы мог подумать :)). Да и Ruby-on-Rails, насколько я слышал, его уважает.</font></p> <p><strong><font face="Arial">Identity Map</font></strong></p> <p><a href="http://martinfowler.com/eaaCatalog/identityMap.html"><font face="Arial">Identity Map</font></a><font face="Arial"> - это паттерн, который дает возможность загрузить лишь один экземпляр объекта в память. То есть, если при первом обращении к определенному объекту ORM &quot;поднимает&quot; экземпляр этого объекта из базы, но все последующие запросы, которые будут приводить к получению этого объекта (даже если этот объект будет частью списка других объектов), будут всего лишь получать ссылку на уже созданный объект, а не его копию. Работает это благодаря тому, что внутри ядра ORM есть реализация этого паттерна. Контекст/сессия, перед тем, как материализовать (создать) объект с определенным Id, сначала просматривают это хранилище на предмет существования объекта, и если он не найден, регистрируют новый материализованный объект в хранилище.</font></p> <p><font face="Arial">Что это нам дает, как программистам. Прежде всего, если мы работаем с одним и тем же контекстом/сессией, то мы можем легко сравнивать объекты по ссылке (==). Кроме того, и что более важно, если мы уже начали изменять объект, а потом вдруг он появился в результате какой-то вспомогательной выборки, то мы можем быть уверены, что это один и тот же измененный объект (конечно, если вы напрямую не сказали при выборке, что вам необходим &quot;чистый&quot; объект). Ну, и напоследок, как side effect, мы получаем небольшое кеширование в рамках контекста/сессии, что позволяет уменьшить затраты на повторную материализацию объекта (</font><a href="http://merle-amber.blogspot.com/2009/01/linq-to-sql-entity-framework.html"><font face="Arial">весьма немаленькие</font></a><font face="Arial">). Естесственно, объекты, полученные из разных конекстов/сессий, не обладают подобными свойствами, что также необходимо понимать и учитывать.</font></p> <p><strong><font face="Arial">Identity Field</font></strong></p> <p><font face="Arial">Упомянув Identity Map, нельзя обойти стороной </font><a href="http://martinfowler.com/eaaCatalog/identityField.html"><font face="Arial">Identity Field</font></a><font face="Arial">. Этот небольшой паттерн, по сути, всего лишь говорит о том, что каждый объект содержит в себе уникальный ключ, который позволяет ORM правильно идентифицировать объекты у себя внутри. В частности, в EF такую функцию выполняет класс EntityKey, который состоит из названия сущности и значений первичного ключа.</font></p> <p><font face="Arial">Как вы уже догадались, Identity Field интенсивно используется для решения задач, описанных предыдущими паттернами.</font></p> <p><strong><font face="Arial">Query Object</font></strong></p> <p><font face="Arial">Паттерн </font><a href="http://martinfowler.com/eaaCatalog/queryObject.html"><font face="Arial">Query Object</font></a><font face="Arial"> реализует в себе запрос к данным. У Фаулера написано, что этот объект должен сам знать, как превратить себя в SQL-запрос, но очень часто паттерн рассматривается более широко, описывая прежде всего способ составления сложных запросов к ORM.</font></p> <p><font face="Arial">В NH есть механизм запросов Criteria, который можно отнести к реализации этого паттерна. В L2S и EF эту функцию выполняет язык запросов LINQ, который также можно назвать его реализацией (хотя и с большой натяжкой).</font></p> <p><strong><font face="Arial">Lazy Load</font></strong></p> <p><font face="Arial">Этот паттерн известен далеко за пределами работы с базой данных, т.к. его очень часто используют и в других областях. Lazy Load описывает объект, который может в определенный момент времени не содержать всех данных, которые нужны ему или другим объектам, но &quot;знает&quot;, как и откуда эти данные получить. При этом после первого обращения и загрузки данных в объект, они кешируются в нем и уже следующие операции проходят быстрее.</font></p> <p><font face="Arial">Lazy Load в том или ином виде реализован практически во всех известных мне ORM для улучшения производительности. Ведь не всегда ваш объект Заказ должен загружать сразу и список Продуктов - они могут просто не понадобится в данной транзакции, так зачем тратить на это время и ресурсы?</font></p> <p><strong><font face="Arial">Repository</font></strong></p> <p><font face="Arial">Я не мог пройти мимо </font><a href="http://martinfowler.com/eaaCatalog/repository.html"><font face="Arial">этого паттерна</font></a><font face="Arial">, хотя на самом деле он не реализован ни в L2S, ни в EF, ни в NH, ни в AR. (Возможно, реализован в других ORM, подскажите, если знаете.) Не мог пройти, потому что паттерн Repository очень часто используется при работе с NH (</font><a href="http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx"><font face="Arial">1</font></a><font face="Arial"> и </font><a href="http://colinjack.blogspot.com/2007/11/repository-implementation-dddnhibernate.html"><font face="Arial">2</font></a><font face="Arial">), да и примеры для других ORM уже подоспели, например, для L2S (</font><a href="http://geekswithblogs.net/AndrewSiemer/archive/2008/02/05/linq-to-sql---implementing-the-repository-pattern.aspx"><font face="Arial">1</font></a><font face="Arial"> и </font><a href="http://habrahabr.ru/blogs/net/52173/"><font face="Arial">2</font></a><font face="Arial">).</font></p> <p><font face="Arial">С простой точки зрения, этот паттерн определяет фасад, который предназначен для того, чтобы быть промежуточным слоем между доменной моделью (бизнес-логикой) и источником данных. Весь код приложения за пределами репозитория работает с базой данных (или другим источником данных) через репозиторий. Однако, если смотреть на него с точки зрения пуристов DDD, то репозиторий - это уже нечто другое. Всех желающих погрузиться в нирвану DDD отправляю к следующему источнику, который достаточно неплохо </font><a href="http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx"><font face="Arial">описывает Repository с точки зрения DDD</font></a><font face="Arial">. Не заблудитесь только там :)</font></p> <p><strong><font face="Arial">Заключение</font></strong></p> <p><font face="Arial">Предлагаю пока что ограничится данными паттернами, т.к. они являются основными паттернами поведения ORM. Тех же, кто хочет узнать больше, отправляю к </font><font face="Arial">Фаулеру, <a href="http://martinfowler.com/eaaCatalog/index.html">в каталоге которого</a> описаны еще с десяток других паттернов, связанных с другими аспектами работы Data Access в целом, и ORM в частности.</font></p> <p><font face="Arial">Надеюсь, данный пост помог вам немножко лучше понять, какие механизмы лежат в основе работы привычных инструментов, а также при необходимости суметь объяснить еще кому-нибудь, чем настолько принципиально отличается NHibernate и ActiveRecord, что потребовалось городить свой огород.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-4265147595423015196?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com5tag:blogger.com,1999:blog-1968777209535947779.post-17598989489946944742009-02-15T23:05:00.001+02:002009-02-15T23:10:04.253+02:00След Шерлока Холмса в программировании или Немного об agile для программистов<p><font face="Arial">Задумывались ли вы, чем отличаются между собой waterfall и agile подходы к разработке программного обеспечения? Для меня, человека, который раньше работал либо по <a href="http://www.taxpayerblog.com/2008/09/ad-hoc-project-management-costs.html">ad hoc</a>, либо по waterfall, либо по итеративным процессам вроде UP, agile-подходы вроде XP, Scrum и др. (прошу не бить сильно ногами, что буду все причесывать под одну гребенку) раньше казались чем-то сродни ad hoc'а, только с дополнительными правилами, чтобы совершенно не скатиться в анархию. У нас даже шутка ходит о том, на проекте часто бывает не просто agile, а полный agile :) Однако после прочтения книжки Книберга я изменил свое мнение.</font></p> <p><font face="Arial">Итак, что же такое agile и как его проще всего понять программисту? Помните, что такое программирование сверху-вниз, а что такое - программирование снизу-вверх? При первом подходе мы сначала все продумываем, разрабатываем каркас, создаем классы верхних слоев, а затем уже спускаемся вниз, к деталям, наполняя их кодом и смыслом. Второй подход - прямая противоположность первому: мы сначала пишем код нижних слоев, потом интегрируем их друг с другом посредством более высоких уровней и, наконец, пишем вызывающую программу. По сути, если говорить математическим (или детективным ;)) языком, это дедукция и индукция.</font></p> <p><em><font face="Arial">Примечание. Кстати, лично мне кажется, что Шерлок Холмс пользовался все-таки индуктивным методом, а не дедуктивным, т.к. он, как и любой другой детектив, строил общую версию исходя из более мелких, частных фактов и улик, но это мое личное мнение и оно к делу не относится :).</font></em></p> <p><font face="Arial">Так к чему я это все? Да к тому, что waterfall - это как раз способ разработки методом сверху-вниз. То есть мы сначала получаем от клиента по возможности все требования (при помощи бизнес-анализа), анализируем их, оцениваем, строим архитектуру, документируем это все - и вперед, арбайтен. От общего к частному или, иными словами, посредством дедукции. Именно на этом подходе работает большинство нормальных человеческих проектов, начиная от строительства дома и заканчивая запуском спутника в космос. Но разработка ПО - это даже близко не строительство дома, хотя определенные аналогии провести можно. Все-таки поменять в последний день логику работы приложения намного легче, чем соорудить автостоянку под уже построенным зданием. То есть в разработке ПО есть такое понятие как <em>гибкость</em> (agility). Ко всему прочему, заказчики (а это может быть кто угодно) - люди зачастую не очень понимающие то, что они хотят получить в результате, а если и понимающие, то склонные менять свое мнение, иногда очень кардинально. Так что же, заставлять их выдавать на-гора все функциональные и нефункциональные требования к приложению ДО начала разработки?</font></p> <p><font face="Arial">Вот собственно из этого всего и родились различные agile-подходы к разработке ПО. А потом появился </font><a href="http://agilemanifesto.org/"><font face="Arial">небезызвестный манифест</font></a><font face="Arial"> - и пошло-поехало. Так что же такое agile и чем он отличается от обычной водопадной или итеративной практики разработки? Ну, отличий, конечно, много, но я бы в первую очередь сказать, что это - процесс разработки ПО снизу-вверх, то есть индуктивный процесс. С самого начала мы очень мало знаем о том, что мы вообще строим, иногда даже так же мало, как и заказчик. Но нам по барабану. Мы берем то, что есть, тратим не очень много времени на планирование - и стартуем. Сделали что-нибудь стоящее, показали заказчику, определили следующие задачи - и поехали дальше. И так до тех пор, пока заказчик не получит то, что хотел. При этом необходимо отметить, что гибкие методологии, в отличие от своих &quot;жестких&quot; товарищей, все же имеют свою жесткость - жесткость правил, по которым ведется разработка. Если у вас нет unit-тестов - вы обломаетесь на первых же серьезных рефакторингах системы. Если у вас нет code review или pair programming - вам будет сложно организовать коллективное владение кодом, что можем повлечь серьезные проблемы, если кто-то из ведущих разработчиков вдруг заболеет. Если вы забиваете на product backlog - у вас в скором времени возникнет каша с требованиями (впрочем, каша с требованиями возникает и тогда, когда они есть, но на их обновление точно так же забивают). Если вы не проводите ежедневные митинги - ваши разработчики будут дублировать действия друг друга и изобретать велосипеды сотнями, а код превратится в мусорку. А все потому что работа ведется в условиях <em>самоорганизовывающейся команды</em> (self-management team) и нет никого, кто бы мог сверху спустить план, в котором будет четко сказано, кто, что и когда должен делать.</font></p> <p><font face="Arial">Надо сказать, это сложно, т.к. получается, что каждый член команды должен не просто ответственно работать, но еще и быть достаточно подкованным с технической точки зрения. Так что перед тем, как с криками &quot;ура, я познал истину и теперь все мы будем жить счастливо&quot; бежать к своей команде, подумайте сначала, а сможет ли она работать в таких условиях? И, что еще более важно, подумайте, а надо ли оно вам? Если у вас есть нормальные требования и клиент знает, чего он хочет, то зачем городить огород? Возьмите какой-нибудь UP - и будет вам счастье. Если же этого нет, то добро пожаловать в мир agile :)</font></p> <p><font face="Arial">PS. А вообще, серебряной пули нет, вы же знаете. Успех или неудача вашего проекта зависит не только от того, какой процесс вы выберете, но и от того, насколько вы сможете его кастомизировать под свои нужды в процессе работы. А для этого нужно просто уметь думать.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-1759898948994694474?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com8tag:blogger.com,1999:blog-1968777209535947779.post-53908617873362752032009-02-15T21:46:00.001+02:002009-02-16T16:26:46.978+02:00Отзыв о книжках: DDD Нильссона и Scrum из окопов Книберга<p><font face="Arial">Последние несколько недель были плодотворными в плане чтения книжек. Дочитал <a href="http://www.rsdn.ru/res/book/prog/ddd.xml">&quot;Применение DDD и шаблонов проектирования: проблемно-ориентированное проектирование приложений с примерами на C# и .NET&quot; Джимми Нильссона</a> и прочитал <a href="http://scrum.org.ua/scrum-i-xp-zametki-s-peredovoj/">&quot;Scrum и XP: заметки с передовой&quot; Хенрика Книберга</a>. Спешу поделиться отзывами, так как уже давно ничего толкового не читал.</font></p> <p><font face="Arial"><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SZhw6yCHFVI/AAAAAAAAIUE/ooD9XFkxdgs/ddd%5B2%5D.jpg"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="234" alt="ddd" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SZhw8WtNGMI/AAAAAAAAIUI/5YscopH7ZGY/ddd_thumb.jpg" width="161" border="0" /></a>&#160;</font></p> <p><font face="Arial">Про первую книгу <a href="http://merle-amber.blogspot.com/2009/01/domain-driven-design.html">я уже писал</a> относительно недавно. Рекомендую всем, кто чувствует, что ему стало тесно в рамках стандартных технологий и подходов, а архитектура и дизайн его приложений хромают на обе ноги. Domain Driven Design - это радикально другой подход к разработке ПО, поэтому книжка отлично освежает голову, дает совершенно другую перспективу и точку зрения на привычные вещи. Нильссон дает общее представление о DDD, а также на примерах показывает, как можно разрабатывать реальные приложения с использованием DDD, TDD, и различных паттернов проектирования. Автор начинает с простых вещей, вводит рабочий пример и потихоньку продвигается по пути его реализации, задевая вопросы архитектуры, модели предметной области, инфраструктуры для сохраняемости, архитектурных паттернов, unit-тестов, правил, аспектно-ориентированного программирования, пользовательского интерфейса, а также немного проходится по NHibernate. В общем и целом, после прочтения книжки в голове появляется намного более серьезное понимание всех вышеперечисленных вопросов, и даже если DDD вам не подходит, вы вынесете из книги много новых знаний. Сразу хочу предупредить, что это не Эванс, здесь нет серьезной теоретической базы, лишь практика, практика, и еще раз практика. Ну, и ложка дегтя: русский перевод этой книги просто ужасен. Не понимаю, как можно было перевести кучу названий паттернов (чего стоят только прецеденты использования и неведение сохраняемости), а также стандартных терминов (DDD - ППО, проектирование предметной области, TDD - РПТ, разработка посредством тестирования). Да и ладно бы, но там не только это перевели, поэтому постоянно приходится думать, как эта фраза звучит по-английски и что это за очередной термин такой. По всей видимости, после перевода книжку не проверил эксперт в данной предметной области. Поэтому читайте оригинал :)</font></p> <p><font face="Arial"><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SZhw9e2BUwI/AAAAAAAAIUM/stwrB9mLpak/scrum%5B2%5D.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="scrum" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SZhw-lxo_1I/AAAAAAAAIUQ/wdjB3V4HFes/scrum_thumb.png" width="163" border="0" /></a> </font></p> <p><font face="Arial">Вторая книжка <a href="http://scrum.org.ua/scrum-i-xp-zametki-s-peredovoj/">была переведена</a> сообществом <a href="http://www.agileukraine.org/">Agile Ukraine</a>, за что ребятам огромное человеческое спасибо! Причем, больше спасибо за то, что они разрекламировали ее, потому что в реальности, как и предыдущая книга, эта читается на английском легко и непринужденно. Книжка переведена просто замечательно, в отличие от перевода того же Нильссона. Сама же книга повествует об опыте Хенрика Книберга в постановке и использовании Scrum'а в нескольких командах. Хенрик последовательно проходится по вопросам планирования спринта, работы с product backlog'ом, ролям команды, ведения burndown-диаграммы, проведения scrum-митингов, демо, ретроспектив, а также, что более важно, объясняет, как работать по Scrum-у в условиях fixed-cost проектов, показывает родство Scrum и XP, и делится опытом постановки процесса QA и работы с несколькими командами. В общем и целом, для человека, который знаком с другими процессами разработки ПО, и который имеет не только положительный, но и отрицательный опыт, эта книга может стать хорошим стимулом попробовать поднять Scrum у себя на проекте. Тем более, если у вас ничего другого нет :) В общем, рекомендую не только PM'ам.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-5390861787336275203?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com0tag:blogger.com,1999:blog-1968777209535947779.post-65585944238357860492009-02-06T13:08:00.001+02:002009-02-06T13:08:47.506+02:00Летаргический сон украинского .NET-сообщества<p><font face="Arial">С сожалением вынужден констатировать, что украинское .NET-сообщество либо мертво, либо находится в глубокой и беспробудной спячке. Откуда такие неутешительные выводы? Да так, личные наблюдения. Скажите, пожалуйста, проходила ли когда-нибудь в Украине нормальная полноценная .NET-конференция? Нет, я не про DevDays, которые, надо признаться, в этом году в Киеве уже были похожи хотя бы на что-то более-менее взрослое, а не на обычную рекламу последних разработок Microsoft. Я про что-то более реальное, более осязаемое, с серьезными темами и докладами, с серьезными докладчиками. А давно ли к нам с докладами наведывались реальные девелоперы из Microsoft или хотя бы из западного сообщества? Говорите, что им тут делать, они по таким мероприятиям не ездят? А если я вам скажу, что многие из них ездят не только в Европу или там Австралию, но и в Южную Африку, Египет, Пакистан, Турцию, Болгарию, Ливан? А потом делятся в <a href="http://www.dotnetrocks.com/archives.aspx">подкастах</a>, что, мол, вот какая в Софии была классная конференция, а в Пакистане у нас <a href="http://www.dotnetrocks.com/default.aspx?showNum=243">аж 3-тысячная аудитория была</a>. И в Россию приезжают, что делает честь нашим северным соседям не только потому, что они их приглашают, но и потому что они способны организовать что-то серьезное, вроде той же <a href="http://platforma2008.ru/">Платформы</a>, <a href="http://www.highload.info/program/">РИТ</a> или других конференций. Да, это еще не <a href="http://www.microsoftpdc.com/">PDC</a>, но это уже хоть что-то, вы не находите? Хорошо, а много ли у нас других конференций или встреч? Не знаю, как в Киеве или Львове, а вот в Харькове есть еще <a href="http://it-talk.dataart.com.ua/">IT Talk'и</a>, которые проводятся под чутким руководством Жени Устименкова, встречи UNETA, которые были бы невозможны без Вовы Лещинского и еще нескольких человек, за что им честь и хвала, и все. Да, еще иногда заезжают с приветом из Киева <a href="http://www.qaclub.com.ua/">QA Club</a> и <a href="http://www.agileukraine.org/">Agile Gathering</a>. Вот теперь точно все! А теперь еще одно задание: скажите, пожалуйста, сколько вы знаете украинских .NET-блоггеров, которых интересно читать. Много насчитали? Угу, вот мне тоже как-то пальцев на двух руках хватило... </font></p> <p><font face="Arial">С чего это я так разошелся? Да, кто его знает, наболело, наверно. Вчера в Харькове на чем-то наподобие DevDays были доклады по Windows Azure. Знаете, сколько было людей? Человек 50, не больше. Из них человек 30 - знакомые лица со встреч UNETA, то есть костяк, который ходит на все подобные мероприятия. И это в городе, где по самым скромным подсчетам больше 2 тысяч .NET-разработчиков. А почему? А потому что: а) реклама мероприятия была дана меньше чем за неделю до его проведения и прошла, по-моему, только по рассылке <a href="http://dev.net.ua/">dev.net.ua</a>, многие мои друзья даже не знали о том, что что-то будет, б) в Харькове у людей неоднозначное мнение об уровне подобных мероприятий: серьезные разработчики предпочитают их игнорировать, как и встречи UNETA, которые в последние несколько лет превратились в собрания студентов. Ну что за организация, в самом деле?! Почему подобные мероприятия не анонсируются как-то более серьезно, почему не рассылается реклама по разным фирмам, почему GlobalLogic может собрать пару тысяч человек на Программанию (пусть большинство из них студенты - не важно), а Microsoft Украина - нет? Ну да ладно, проблему с рекламой поправить не сложно. А вот как доказать сильным разработчикам и их работодателям, что этот день (или вечер) пройдет для них не зря? Что они услышат интересные доклады, из которых смогут узнать что-то новое для себя, что-то, что им поможет в их работе. Что они смогут встретиться с интересными людьми, пообщаться, поделиться опытом и приобрести его. Что они смогут сами поучаствовать в докладах, если видят в себе силы и имеют желание! И не говорите мне, что у нас нет ребят, способных на это. Только в одном Харькове среди моих близких и дальних знакомых я знаю десятки подобных людей, которые просто не хотят ходить на наши “местные” конференции из-за их слабого уровня.</font></p> <p><font face="Arial">Как, в конце-концов, сформировать в Украине или отдельно взятом городе настоящее сообщество, которое сможет не просто вместе двигаться вперед, но и двигать вперед всю отечественную разработку? Может, стоит обратиться за опытом к профессионалам хотя бы того же Microsoft, которые уже собаку съели на этих вопросах и построили у себя в Штатах или Европе реально сильные сообщества. Ведь все реально, было бы только желание. Существуют же online-сообщества типа того же RSDN уже в течение многих лет, и держаться как-то. Так чем мы хуже-то?</font></p> <p><font face="Arial">Ведь сообщество - это не только &quot;тусовка&quot;, это еще и место, где можно подойти и посоветоваться с экспертом в определенной области, услышать про новинки, в конце-концов, самому подготовить доклад о чем-то, если есть желание. А потом пойти и внедрить это на практике у себя в работе. Ведь это, возможно, один из самых эффективных способов повышения своего уровня и уровня окружающих тебя людей. Не говоря уже о том, что это фан. Без подобного роста над самими собой, без обмена опытом, без проб и ошибок мы так и останемся страной третьего мира в разработке ПО. И так и будем заниматься аутсорсингом саппортных проектов или банальных веб-сайтиков и ERP-систем, которыми уже никто не хочется заниматься на Западе. И не будет у нас своих разработок, своих исследований, своих продуктов и своих достижений.</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-6558594423835786049?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com30tag:blogger.com,1999:blog-1968777209535947779.post-13475130783628193182009-01-25T13:22:00.001+02:002009-01-25T13:45:17.467+02:00Методы оптимизации производительности Linq to SQL и Entity Framework<p><font face="Arial">Я хотел бы закончить начатое в предыдущих нескольких заметках (<a href="http://merle-amber.blogspot.com/2008/11/net-orm-1.html">часть 1</a>, <a href="http://merle-amber.blogspot.com/2008/11/net-orm-2-sql.html">часть 2</a>) и <a href="http://merle-amber.blogspot.com/2009/01/uneta.html">докладе</a> дело и привести набор методов по оптимизации производительности L2S и EF. В какой-то степени эту заметку можно считать текстом к <a href="http://www.slideshare.net/AlexMerle/ling-to-sql-and-entity-framework-performance-analysis-presentation?type=presentation">презентации</a>. Наверняка, это не все, что можно сделать с этой точки зрения, но это как минимум основные способы, которые могут стать отправной точкой для ваших собственных действий.</font></p> <p><strong><font face="Arial">Зачем нам все это нужно?</font></strong></p> <p><font face="Arial">Первым делом давайте обсудим, а зачем вообще нужно оптимизировать производительность этих инструментов? Неужели она настолько плоха, что ими нельзя пользоваться без этого? Вовсе нет, можно и даже нужно! Просто нужно понимать, что за огромное ускорение времени разработки, исчезновение нудного процесса создания Data Access Layer вручную и снижение затрат на дальнейшие изменения в базе данных и модели нужно чем-то платить. А платить приходится двумя вещами: временем на изучение нового инструмента (однажды) и некоторой потерей гибкости и производительности. В разных ORM потери производительности разные, но все же вы должны отдавать себе отчет в том, где и когда использовать ORM, а где и когда - нет.</font></p> <p><font face="Arial">За год работы с Entity Framework на достаточно крупном проекте я использовал в лучшем случае пару способов из приведенных ниже. И это несмотря на то, что как оказалось для нашего приложения использование ORM было, возможно, не самым лучшим выбором. У нас было несколько бизнес правил, которые заставляли нас вытаскивать чуть ли не полбазы в память, чтобы подсчитать некоторые данные для всего лишь одной сущности! При этом из-за иерархичности данных считать их в базе было еще большим злом, чем считать в памяти (поверьте, мы пробовали и меряли производительность). Поэтому, как вы сами понимаете, за dotTrace я брался довольно часто. Но, как правило, обычно все заканчивалось тем, что я находил либо ляп в коде, либо добавлял локальный кеш, чтобы не вытаскивать одни и те же данные из EF сотни, а то и тысячи раз. Надо сказать, что почти все проблемы с производительностью мы побороли через кеширование данных и правильное использование контекста EF. Но ближе к релизу приложения я начал замечать, что мы уже оптимизировали почти все, что можно и что bottleneck медленно, но уверенно переместился к границе EF, и что дальше придется оптимизировать уже его. Следствием этого и стало исследование, результаты которого я привожу сейчас.</font></p> <p><strong><font face="Arial">Основные места потери производительности</font></strong></p> <p><font face="Arial">Сначала я хотел бы остановиться на основных местах, где теряется производительность, т.к. от этого зависят и методы оптимизации:</font></p> <p><font face="Arial"><strong>1. Инициализация инфраструктуры.</strong> При &quot;холодном старте&quot; и L2S и EF теряют здесь какое-то время. Это происходит всего лишь один раз для апп-домена, но тем не менее может стать неприятной неожиданностью. L2S справляется с этим быстрее, но в EF можно пре-генерировать его внутренние views еще до запуска приложения и таким образом сократить время инициализации в разы. То есть для EF эту потерю (иногда очень значительную при первом запросе) оптимизировать можно.</font></p> <p><font face="Arial"><strong>2. Накладные расходы, связанные с маппингом.</strong> И L2S, и EF имеют эти расходы, но в EF они больше, т.к. в нем намного больше вариантов маппинга: наследование, тип на таблицу, несколько типов на таблицу, несколько таблиц на тип, сложные типы. К сожалению, тут особо не разбежишься, т.к. все происходит внутри ORM. Возможно, есть какие-то хаки, но я о них на данный момент не знаю. Поэтому будем считать, что оптимизация этой задачи нам недоступна.</font></p> <p><font face="Arial"><strong>3. Анализ запросов.</strong> Это могут быть linq-запросы (Linq to SQL, Linq to Entities) или EntitySQL для EF. Здесь ситуация выглядит получше. Разобранные EntitySQL запросы кешируются на уровне апп-домена, что позволяет не заниматься этим несколько раз. Ключом выступает как раз само текстовое представление запроса, так что будьте внимательнее и используйте параметры. С linq-запросами сложнее. Так как linq - это дерево объектов, которое представляет собой запрос, использовать его в качестве ключа довольно сложно. Но в таком случае запрос можно &quot;откомпилировать&quot; один раз (то есть, грубо говоря, закешировать его разобранный вид и команду, которая будет построена на нем) и потом выполнять его многократно. Тоже помогает.</font></p> <p><font face="Arial"><strong>4. Генерация SQL-запросов.</strong> Как и маппинг, происходит глубоко внутри, поэтому добраться туда и как-то повлиять сложно. Но нужно сказать, что почти все провайдеры реализуют внутри себя различные способы оптимизации, такие как кеширование планов запросов. В то же время во всех ORM есть одна и та же проблема: генерируемый SQL-результат не всегда оптимален (хотя как правило это так). Причем, что интересно, EF генерирует запросы в большинстве своем более оптимально, чем L2S. Один из основных советов здесь - в случае получения на выходе неоптимального запроса просто перестройте запрос в коде: поменяйте джойны, разбейте на несколько более мелких. Это помогает.</font></p> <p><font face="Arial"><strong>5. Материализация.</strong> Это процесс создания объектов по полученным реляционным данным. Занимает львиную долю времени от времени выполнения самого запроса. Однако оптимизирован за счет того, что контекст как L2S, так и EF (да и сессия NHibernate тоже) сохраняет у себя внутри материализованные объекты и при повторном обращении к этому же объекту уже не создает его повторно (если вы сами не скажете). Конечно, это сделано не для оптимизации, а для того, чтобы в рамках одного контекста у вас был только один объект Заказ с ID=7 в независимости от количества запросов. Ну, и чтобы трекать изменения в этих самых объектах. Но подобное &quot;кеширование&quot; еще и увеличивает производительность, что тоже является хорошей новостью. В защиту процесса материализации нужно добавить еще и то, что даже если вы пишете свой Data Access Layer, то вы все равно в том или ином виде занимаетесь материализацией. Вам же тоже нужно превратить записи из DataReader в какие-то объекты доменной модели. Да, ручной код более оптимален, т.к. заточен для решения лишь одной задачи, но, поверьте, ORM тоже умные люди пишут :)</font></p> <p><strong><font face="Arial">Методы оптимизации производительности</font></strong></p> <p><font face="Arial">Итак, какие же методы оптимизации производительности можно предложить. За конкретными цифрами и сравнениями вы можете обратиться к <a href="http://merle-amber.blogspot.com/2009/01/uneta.html">презентации</a>.</font></p> <p><font face="Arial"><strong>1. Пре-генерация views в Entity Framework.</strong> По шагам расписана </font><a href="http://msdn.microsoft.com/en-us/library/bb896240.aspx"><font face="Arial">в MSDN</font></a><font face="Arial"> и частично </font><a href="http://blogs.msdn.com/adonet/archive/2008/02/04/exploring-the-performance-of-the-ado-net-entity-framework-part-1.aspx"><font face="Arial">здесь</font></a><font face="Arial">, поэтому подробно останавливаться не буду.</font></p> <p><font face="Arial"><strong>2. Отключение трекинга объектов (tracking).</strong> Дает возможность немного улучшить производительность за счет того, что материализованные объекты не отслеживаются контекстом. Обратная сторона - сделанные в объектах изменения не могут быть сохранены в базу. Плюс (здесь я могу ошибиться, но вряд ли) отключается кеширование материализованных объектов в контексте, что в большинстве своем намного сильнее ухудшает производительность для большого количества запросов. Так что решайте сами, но мы у себя не использовали.</font></p> <p><font face="Arial">В L2S трекингом можно управлять через свойство контекста:</font></p> <pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; background-color: #eee"><code>context.ObjectTrackingEnabled = false;<br /></code></pre><p><font face="Arial">В EF - через ObjectQuery&lt;T&gt;, что не так удобно:</font></p><pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; background-color: #eee"><code>entities.Orders.MergeOption = MergeOption.NoTracking;<br />entities.Customers.MergeOption = MergeOption.NoTracking;<br /></code></pre><p><font face="Arial">Подробнее про трекинг в EF можно почитать <a href="http://msdn.microsoft.com/en-us/library/bb896269.aspx">в MSDN</a>.</font></p><p><font face="Arial"><strong>3. Кеширование материализованных объектов.</strong> Происходит автоматически в контексте в том случае, если включен трекинг. В интернете иногда можно прочитать советы по использованию одного контекста на запрос. Да, можно, если вы пишете тестовое приложение или вам совершенно не важна производительность. Однако, в то же время и слишком долго держать контекст в памяти - неправильно. В конце-концов он вытянет в память всю вашу базу данных, не говоря уже о том, что придется каким-то образом вручную управлять конкуренцией, т.к. данные в базе могут обновиться, а в памяти - еще нет. В любом случае, судя по цифрам, использование одного контекста на несколько запросов улучшает производительность в несколько раз.</font></p><p><font face="Arial">В нашем веб-приложении мы использовали интересную стратегию: создавали один контекст на http request и сохраняли его в Request. Все запросы в рамках одного http request работали через этот контекст, таким образом обеспечивая определенное кеширование. Плюс к этому у нас не было проблем, связанных с тем, что одна сущность была вытянута из одного контекста, а другая - из второго. Ну, и наконец, т.к. обработка http request занимает от силы несколько секунд, то проблемы с конкуренцией были сведены до минимума. В случае же, когда нам нужно было сохранять состояние объектов на протяжении нескольких http request'ов (например, для реализации многостраничных диалогов или многостраничных таблиц с поддержкой сохранения изменений), мы временно переносили контекст в сессию, а когда нужно было сохранять данные, вызывали context.ApplyPendingChanges(), и убирали контекст из сессии. Таким образом, на следующем запросе он снова создавался в рамках http request и все продолжало замечательно работать.</font></p><p><font face="Arial">Но не переборщите с этим методом. Настоятельно не рекомендуется использовать один и тот же контекст из нескольких сессий или запросов (например, поместив его в Application). Мало того, что вы получите себе на голову все вышеупомянутые проблемы, так еще и в случае параллельного выполнения нескольких запросов (а каждый http request - это отдельный поток, если вы не знали) вы получите красивый exception :)</font></p><p><font face="Arial"><strong>4. Компиляция linq-запросов.</strong> Как я уже говорил, linq-запросы, в отличие от EntitySQL, не кешируются автоматически. Для того, чтобы скомпилировать запрос, нужно выполнить очень простой вызов:</font></p><pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; background-color: #eee"><code>protected static Func&lt;NorthwindClassesDataContext, IQueryable&lt;Order&gt;&gt; compiledGetOrders =<br /> CompiledQuery.Compile(<br /> (NorthwindClassesDataContext ne) =&gt;<br /> (from o in ne.Orders<br /> select o));<br /></code></pre><p><font face="Arial">При этом не имеет особого значения, используете вы Linq to SQL или Linq to Entities. Вы просто передаете туда либо контекст L2S, либо контекст EF.</font></p><p><font face="Arial">Однако, хотел бы предостеречь тех людей, которые уже побежали переписывать свой код. Дело в том, что компиляция запроса - процесс довольно длительный, поэтому он имеет смысл лишь в том случае, если вы делаете несколько вызовов одного и того же запроса (пусть и с разными параметрами). И еще лишь в том случае, если у вас действительно сложный linq-запрос. Для случая, приведенного выше, компиляция запросов не дает существенной выгоды. Для случая с одним запросом откомпилированный запрос может работать дольше неоткомпилированного. Так что it depends.</font></p><p><font face="Arial">Подробнее про компиляцию запросов можно прочитать все <a href="http://msdn.microsoft.com/en-us/library/bb896297.aspx">в том же MSDN</a>. Также советую глянуть <a href="http://msdn.microsoft.com/en-us/library/bb738693.aspx">статью о потоке выполнения запроса в EF</a>.</font></p><p><font face="Arial"><strong>5. Использование EntitySQL.</strong> Во всех источниках написано, что самый быстрый способ работы с EF - это EntitySQL. И, как показывают тесты, это действительно так. В то же время, EntitySQL не так удобен, как linq, не поддерживает code completion (это же простая строка), не типобезопасен (у вас нет проверки уровня компиляции) и в целом выглядит как обычный SQL-код в вашем C#-коде, что не придает ему эстетичности. Да и работает не намного быстрее компилированного linq. Так что я бы советовал использовать его лишь в самых серьезных случаях. Хотя в таких случаях еще лучше написать хранимую процедуру.</font></p><p><font face="Arial">Выглядит это где-то так:</font></p><pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; background-color: #eee"><code>string query = &quot;SELECT VALUE p FROM NorthwindEntities.Products AS p&quot;<br /> + &quot; JOIN NorthwindEntities.Order_Details AS od ON od.ProductID == p.ProductID&quot;<br /> + &quot; JOIN NorthwindEntities.Orders AS o ON o.OrderID == od.OrderID&quot;<br /> + &quot; WHERE o.Customers.CustomerID == @customerId&quot;;<br />var products = <br /> entities.CreateQuery&lt;Product&gt;(query, new[] { new ObjectParameter(&quot;customerId&quot;, customerId) }).ToList();<br /></code></pre><p><font face="Arial">Подробнее почитать про EntitySQL можно </font><a href="http://blogs.msdn.com/adonet/archive/2007/05/30/entitysql.aspx"><font face="Arial">в одной из заметок на ADO.NET blogs</font></a> и в MSDN<font face="Arial">.</font></p><p><font face="Arial"><strong>6. Использование жадной загрузки (eager loading).</strong> Во-первых, нужно сказать, что и L2S, и EF по умолчанию реализуют ленивую загрузку (lazy loading). Только L2S делает это неявно, то есть сразу при обращении к навигационному свойству или коллекции, а в EF нужно явно вызвать метод Load(). Что лучше, что хуже - можно спорить долго. Жаль, что в EF не сделали включение/выключение явного/неявного режима через какое-нибудь свойство. Поэтому нам вот пришлось самим сделать неявную ленивую загрузку через кодогенерацию (я как-нибудь расскажу об этом подробнее). Но разговор сейчас не об этом. По тестам жадная загрузка, конечно же, выигрывает у ленивой, причем иногда весьма существенно. Однако если вы загрузите кучу данных, а потом не будете ее использовать - какой вам от нее прок? В этом случае, ленивая загрузка оказывается на высоте. Как же написать запрос в &quot;жадном&quot; стиле? В Entity Framework это делается через ObjectQuery.Include():</font></p><pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; background-color: #eee"><code>(from o in entities.Orders.Include(&quot;Order_Details&quot;)<br />select o).ToList();<br /></code></pre><p><font face="Arial">Также в особо тяжелых случаях я бы рекомендовал писать один запрос для получения данных, а не идти через навигационные свойства. Например:</font></p><pre style="border-right: #999999 1px dashed; padding-right: 5px; border-top: #999999 1px dashed; padding-left: 5px; font-size: 12px; padding-bottom: 5px; overflow: auto; border-left: #999999 1px dashed; width: 100%; color: #000000; line-height: 14px; padding-top: 5px; border-bottom: #999999 1px dashed; font-family: andale mono, lucida console, monaco, fixed, monospace; background-color: #eee"><code>var allProductsData = <br /> (from cust in entities.Customers<br /> where cust.CustomerID == customerId<br /> select new<br /> {Orders = <br /> from ord in cust.Orders<br /> select new<br /> {Products = <br /> from det in ord.Order_Details<br /> select det.Product}}).ToList();<br /><br />List&lt;Product&gt; products = new List&lt;Product&gt;();<br />var productsData = allProductsData.FirstOrDefault();<br />if (productsData != null)<br /> foreach (var ordersData in productsData.Orders)<br /> {<br /> foreach (Product product in ordersData.Products)<br /> {<br /> products.Add(product);<br /> }<br /> }<br /></code></pre><p><font face="Arial">Хоть это и не eager loading в чистом виде, но в то же время этот способ обходит вариант прохождения от Customer до его Products через навигационные свойства, которые бы подняли данные через lazy loading.</font></p><p><font face="Arial"><strong>7. Оптимизация обновления данных.</strong> Здесь в первую очередь хочется отметить, что по тестам EF значительно опережает L2S в этом аспекте. Причем дело не в SQL-запросах, так как их производительность, за некоторыми исключениями, почти одинакова. Проблема кроется где-то внутри L2S, поэтому учитывайте и этот аспект при выборе способа доступа к базе данных. Для оптимизации выполнения сгенерированных SQL-запросов в L2S советую глянуть еще на атрибут <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.columnattribute.updatecheck.aspx">UpdateCheck</a>, который определяет будет ли сгенерирован where по всем полям сущности или только по ее Id (это делается для реализации оптимистической конкуренции). В EF такая проверка делается только по измененным колонкам, а в L2S - по всем. Также стоит подумать об реализации колонки Version для этой самой конкуренции.</font></p><p><font face="Arial"><strong>8. Оптимизация SQL-запросов.</strong> Как я уже говорил, единственный способ - следить за ними и менять входные linq или EntitySQL запросы. Также по результатам осмотра можно наставить индексов в базе данных. Ну, и никто не отменял хранимые процедуры, куда можно поместить наиболее серьезные запросы. Так что основной совет здесь - не бояться браться за SQL профайлер в случае необходимости :)</font></p><p><font face="Arial">Еще интересен тот факт, что EF в целом генерирует более оптимальные запросы, чем L2S. Так что имейте и это в виду.</font></p><p><font face="Arial"><strong>Выводы</strong></font></p><p><font face="Arial">В целом, я описал все основные средства оптимизации производительности. Если вам интересны подробности, для EF существует <a href="http://msdn.microsoft.com/en-us/library/cc853327.aspx">целая статья в MSDN</a>, посвященная этому вопросу. Также советую интересную серию заметок <a href="http://blogs.msdn.com/adonet/archive/2008/03/27/ado-net-entity-framework-performance-comparison.aspx">в блогах ADO.NET</a>. Для Linq to SQL советую почитать следующую <a href="http://blogs.msdn.com/ricom/archive/2007/06/22/dlinq-linq-to-sql-performance-part-1.aspx">серию заметок</a>, хотя она немного устарела.</font></p><p><font face="Arial">В целом, из своего опыта могу сказать, что производительность Entity Framework уже достаточна для реализации кучи приложений. Думаю, в следующей версии она станет еще лучше. Если же вы знаете, что этого вам будет мало, то можете посмотреть на Linq to SQL. И пусть вас не пугает, что MS <a href="http://merle-amber.blogspot.com/2008/11/linq-to-sql-entity-framework.html">решила не развивать L2S в той же мере, что и EF</a> - уже есть <a href="http://merle-amber.blogspot.com/2008/10/stackoverflowcom.html">примеры высоконагруженных приложений, успешно использующих L2S</a>, не говоря о том, что это просто замечательная замена всяким типизированным и прочим датасетам (брррр). Ну, а в особо критичных к производительности случаях нам все равно никуда не деться от старого-доброго ADO.NET :)</font></p><p><font face="Arial">Если сравнивать Entity Framework с другими полноценными ORM, такими как NHibernate, LLBLGen Pro и др, то на данный момент я не могу ничего толком сказать. Надо попробовать, благо тестовое приложение, которое я написал, с легкостью расширяется другими тестовыми провайдерами. Могу лишь кое-что сказать об NHibernate, т.к. я успел его попробовать и почитал дополнительные материалы о нем. NH по производительности занимает место где-то в промежутке между L2S и EF. Плюс этот прекрасный ORM уже давно на рынке и обладает множеством других интересных способностей, например, поддержкой Persistence ignorance и кешом второго уровня, которых пока нет в Entity Framework. Так что при выборе ORM я бы однозначно смотрел и в его сторону.</font></p><p><font face="Arial">На этой замечательной ноте я бы хотел завершить цикл постов про производительность L2S и EF :) Вполне возможно, в ближайшем будущем у нас появятся дополнительные данные по производительности NHibernate и еще нескольких интересных ORM. Если у вас есть желание помочь в этом - можете <a href="http://data-access-orm-comparison.googlecode.com/files/DataAccessPerformanceTest_v2.zip">скачать тестовое приложение</a>, написать свой тестовый провайдер (это делается абсолютно несложно, поверьте мне), и расшарить результаты.</font></p><p><font face="Arial">Всем спасибо!</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-1347513078362819318?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com1tag:blogger.com,1999:blog-1968777209535947779.post-3074222410687041442009-01-24T12:58:00.002+02:002009-01-24T12:59:21.122+02:00Москва<p><font face="Arial">Совсем недавно наткнулся на фотографии из Москвы, которые мы сделали этим летом, будучи там проездом по дороге на Байкал. Когда я выкладывал </font><a href="http://merle-amber.blogspot.com/2008/07/blog-post_21.html"><font face="Arial">байкальские</font></a><font face="Arial">, </font><a href="http://merle-amber.blogspot.com/2008/07/blog-post_31.html"><font face="Arial">хамар-дабанские</font></a><font face="Arial"> и </font><a href="http://merle-amber.blogspot.com/2008/09/blog-post_04.html"><font face="Arial">иркутские</font></a><font face="Arial"> фотографии, то решил, что Москве уже </font><a href="http://picasaweb.google.ru/alexander.konduforov/2007Vacation2007Moscow"><font face="Arial">один фотоальбом</font></a><font face="Arial"> был посвящен в 2007 году, поэтому второй можно и отложить. А между тем в фотографиях образца 2008 года тоже было немало хороших, поэтому решил выложить и их </font><a href="http://picasaweb.google.ru/alexander.konduforov/200811#"><font face="Arial">на пикасе</font></a><font face="Arial">.</font></p> <p><font face="Arial">Можно по-разному относится к Москве, как к городу. Кто-то скажет, что Москва - очень красивый город, особенно летом, особенно возле Кремля :) Город с развитой инфраструктурой, большими возможностями, богатой историей. Кто-то возразит, что сейчас город заметно сдал, везде развешана реклама, идет снос старинных зданий, и что вообще ему далеко до Питера. Да и вообще, понаехали тут... Я же скажу, что для меня Москва - это прежде всего один из древнейших на Руси городов, и бывшая столица нашей некогда необъятной родины. Москва всегда была коммерческим, торговым городом, а потом ей еще и не повезло, когда она стала столицей сначала Российской империи, а потом - СССР и России. Это во-многом определило судьбу города, его застройку и дух. Тому же Питеру в этом плане, на мой взгляд, повезло чуть больше. Питер намного моложе, но его расцвет пришелся на расцвет Российской империи, а потом он не попал под жернова столичной жизни. Наверно, поэтому и сохранился как исторический и культурный памятник намного лучше. Ну да хватит сравнивать - сегодня мы поем оду Москве :)</font></p> <p><font face="Arial">Я никогда не был в Москве долго. Зато уже 4 раза был там проездом :) И скажу честно, 2 года назад город мне не очень понравился. Не смотрелся он </font><a href="http://picasaweb.google.ru/alexander.konduforov/2007Vacation2007Peterhof"><font face="Arial">по</font></a><font face="Arial"> </font><a href="http://picasaweb.google.ru/alexander.konduforov/2007Vacation2007TsarskoeSelo"><font face="Arial">сравнению</font></a><font face="Arial"> </font><a href="http://picasaweb.google.ru/alexander.konduforov/2007Vacation2007Pavlovsk"><font face="Arial">с</font></a><font face="Arial"> </font><a href="http://picasaweb.google.ru/alexander.konduforov/2007Vacation2007StPetersburg"><font face="Arial">Питером</font></a><font face="Arial">, да и с </font><a href="http://picasaweb.google.ru/alexander.konduforov/122007"><font face="Arial">Киевом</font></a><font face="Arial"> тем же, откровенно говоря, тоже. Но с каждым следующим приездом я все больше убеждался, что в Москве есть что-то особенное, какая-то своя неповторимая изюминка. Москва поражает не только размахом и шиком, но и своим внутренним духом, который еще не успел исчезнуть под давлением свалившихся буржуазно-демократических отношений. Да, самые красивые для глаза места - это стандартный набор: Кремль, Красная площадь, храм Христа Спасителя, Воробьевы горы, Новодевичий монастырь, Арбат, Царицыно, и др. Но там вы не почувствуете атмосферу города. Это все в основном для туристов. Лучше отойти в сторону от всего этого, убежать в обычные московские кварталы, погулять там. Вот там можно прочувствовать, как и чем живут обычные москвичи, понять их. А может, даже соприкоснуться с духом этого великого во всех отношениях города.</font></p> <p><font face="Arial">А пока несколько фотографий Москвы образца 2008 года:</font></p> <p>&#160;<a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrz06BB5MI/AAAAAAAAISA/VlgQTkDJM0k/Picture%20509%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 509" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SXrz17SPxCI/AAAAAAAAISE/7B7dozoN72A/Picture%20509_thumb.jpg" width="184" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrz5bV3caI/AAAAAAAAISI/Io3krl1Us24/Picture%20523%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 523" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SXrz66as_HI/AAAAAAAAISM/goGb-in4HJU/Picture%20523_thumb.jpg" width="184" border="0" /></a> <a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SXrz9bIWV9I/AAAAAAAAISQ/KczMr_f8cxU/Picture%20522%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 522" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SXrz_ndYu1I/AAAAAAAAISU/kZ31yFjEf4I/Picture%20522_thumb.jpg" width="184" border="0" /></a></p> <p>&#160; <a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SXr0CLtn5-I/AAAAAAAAISY/2TKkE3hH-Bw/Picture%20558%5B2%5D.jpg"><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SXr0D7lEnGI/AAAAAAAAISc/VEfXJ-c38-A/IMG_8971%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_8971" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SXr0GZY5YJI/AAAAAAAAISg/y5AS944EVng/IMG_8971_thumb.jpg" width="184" border="0" /></a><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 558" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SXr0HePZwuI/AAAAAAAAISk/9J2v1a9tC3M/Picture%20558_thumb.jpg" width="178" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SXr0IwkL4bI/AAAAAAAAISo/iHPYxaBpE7I/Picture%20554%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 554" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SXr0KgTohAI/AAAAAAAAISs/saonCITc5ok/Picture%20554_thumb.jpg" width="184" border="0" /></a> </p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SXr0NtAtArI/AAAAAAAAISw/ZSE10cG5oQw/Picture%20563%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="Picture 563" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SXr0Oqx16mI/AAAAAAAAIS0/FWObEvjSL-4/Picture%20563_thumb.jpg" width="244" border="0" /></a> <a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SXr0S-JAiVI/AAAAAAAAIS4/DufC_aEYWCQ/Picture%20529%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="Picture 529" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SXr0UUf4VSI/AAAAAAAAIS8/p4umOVUeeYA/Picture%20529_thumb.jpg" width="244" border="0" /></a></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-307422241068704144?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com0tag:blogger.com,1999:blog-1968777209535947779.post-52822345790900732542009-01-24T11:07:00.001+02:002009-01-24T11:07:30.054+02:00Доклад на харьковской UNETA. Материалы<p><font face="Arial">Вчера прошел мой первый доклад на харьковской встрече UNETA. Я попытался разобраться с производительностью Linq to SQL и Entity Framework, взяв в качестве бенчмарка производительность аналогичных запросов в чистом ADO.NET, а также дать какие-то советы по их улучшению. Надеюсь, тем, кто пришел, было не очень скучно :)</font></p> <p><font face="Arial">Возможно, у кого-то есть комментарии: что было хорошо, что плохо, как со стороны темы доклада, так и со стороны самого выступления. Возможно, остались какие-то незаданные вопросы. Прошу всех в комментарии - я постараюсь ответить на вопросы и учесть все пожелания (особенно, отрицательные).</font></p> <p><font face="Arial">Как я и обещал, выкладываю материалы доклада:</font></p> <p><font face="Arial"></font> <div id="__ss_948634" style="width: 425px; text-align: left"><a title="Ling to SQL and Entity Framework performance analysis" style="display: block; margin: 12px 0px 3px; font: 14px helvetica,arial,sans-serif; text-decoration: underline" href="http://www.slideshare.net/AlexMerle/ling-to-sql-and-entity-framework-performance-analysis-presentation?type=presentation">Ling to SQL and Entity Framework performance analysis</a><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=l2s-and-ef-performance-analysis-1232787471654617-3&amp;stripped_title=ling-to-sql-and-entity-framework-performance-analysis-presentation" width="425" height="355" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" /> <div style="font-size: 11px; padding-top: 2px; font-family: tahoma,arial; height: 26px">View more <a style="text-decoration: underline" href="http://www.slideshare.net/">presentations</a> or <a style="text-decoration: underline" href="http://www.slideshare.net/upload?type=presentation">upload</a> your own. (tags: <a style="text-decoration: underline" href="http://slideshare.net/tag/programming">programming</a> <a style="text-decoration: underline" href="http://slideshare.net/tag/orm">orm</a>)</div> </div> </p> <p></p> <p><font face="Arial">Скачать тестовое приложение и презентацию можно отсюда:</font></p> <p><font face="Arial">Тестовое приложение: </font><a title="http://data-access-orm-comparison.googlecode.com/files/DataAccessPerformanceTest_v2.zip" href="http://data-access-orm-comparison.googlecode.com/files/DataAccessPerformanceTest_v2.zip"><font face="Arial">http://data-access-orm-comparison.googlecode.com/files/DataAccessPerformanceTest_v2.zip</font></a></p> <p><font face="Arial">Презентация: </font><a title="http://data-access-orm-comparison.googlecode.com/files/L2S%20and%20EF%20performance%20analysis.zip" href="http://data-access-orm-comparison.googlecode.com/files/L2S%20and%20EF%20performance%20analysis.zip"><font face="Arial">http://data-access-orm-comparison.googlecode.com/files/L2S%20and%20EF%20performance%20analysis.zip</font></a></p> <p><font face="Arial">Постоянная ссылка проекта: </font><a title="http://code.google.com/p/data-access-orm-comparison/" href="http://code.google.com/p/data-access-orm-comparison/"><font face="Arial">http://code.google.com/p/data-access-orm-comparison/</font></a></p> <p><font face="Arial">Для запуска тестового приложения вам понадобится лишь поставить базу данных Northwind и изменить строки подключения. Приложение достаточно расширяемо, так что вы можете добавить туда свои собственные тестовые провайдеры, например, для работы с NHibernate или LLBLGen Pro.</font></p> <p><font face="Arial">Список полезных ссылок есть в конце доклада, так что здесь я его не привожу.</font></p> <p><font face="Arial">Удачи в ваших исследованиях!</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-5282234579090073254?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com1tag:blogger.com,1999:blog-1968777209535947779.post-57872061596396870272009-01-04T13:57:00.001+02:002009-01-04T14:02:18.125+02:00Domain Driven Design: введение<p><font face="Arial">Пару месяцев назад мне в руки попала книжка по <a href="http://en.wikipedia.org/wiki/Domain-driven_design">Domain Driven Design (DDD)</a>. Отдельную рецензию на нее я напишу позже, когда дочитаю до конца. А пока что хотелось бы поделиться мыслями, которые у меня возникли в процессе прочтения.</font></p> <p><font face="Arial">Для начала я бы сказал, что DDD переворачивает взгляд на архитектуру приложения. Слабее, чем это делает <a href="http://www.rsdn.ru/article/patterns/ModelViewPresenter.xml">MVC</a>, но все же. Как нас учили проектировать в университетах, какие были наши первые проекты в реальной жизни, как программируют в 80-90% случаев в программистких конторах? Очень просто и прямолинейно. Есть у нас требования, анализируем предметную область (domain), находим сущности, анилизируем их поведение, действия, создаем высокоуровневую архитектуру, выбираем технологии, если нужно, строим UML-диаграммы. А дальше проектируем базу данных и от нее уже пляшем: слой доступа к данных (data access layer), слой бизнес-логики (business logic layer), слой представления (presentation layer), сервисы, etc. Т.е. снизу вверх. Все создаваемые таблицы в базе данных, как правило, мапятся на объекты предметной области как один-к-одному (с небольшими исключениями). Далее создаются сущности приложения, которые, как правило, подчиняются структуре сущностей в базе данных для удобства дальнейшей работы (опять же, могут быть исключения). Даже если мы используем какой-нибудь ORM (тот же Entity Framework или NHibernate), но генерируем сущности по базе данных, то мы все равно выходим на т.н. Data Driven Design, когда структура данных диктует нашу объектную модель. Да, это работает для решения многих задач, но не всех.</font></p> <p><font face="Arial">Domain Driven Design - совершенно другой зверь. Как следует из названия, это просто еще один способ проектирования, который фокусируется прежде всего на предметной области, на объектах реального мира, их поведении и взаимодействии, то есть фокусируется на модели и бизнес-логике, а не на структуре данных. Результатом подобного смещения приоритетов становится то, что мы стараемся перевести объекты предметной области и их поведение сразу в сущности приложения, пытаясь передать в них не только свойства и атрибуты этих объектов, но и поведение. Например, сущность &quot;автомобиль&quot; в DDD будет обладать не только атрибутами марка, цвет, цена, скорость и др., но и, по-возможности, каким-то поведением, связями с другими объектами. При этом проблема сохраняемости этих объектов куда-либо (например, в базу данных) отходит на второй план. Мы об этом не думаем, таким образом достигая сразу нескольких целей:</font></p> <ol> <li><font face="Arial">Откладывание реализации слоя сохранения (persistence layer или data access layer) позволяет реализовать его тогда, когда доменная модель уже спроектирована и реализована, то есть когда она устаканилась. Сколько раз в начале разработки приложения вы добавляете или убираете колонки в таблицах или даже целые таблицы? Сколько при этом приходится переписывать кода слоя доступа к данным? Хорошо еще, если вы используете ORM.</font> </li> <li><font face="Arial">Слой сохранения реализуется как всего лишь один из инфраструктурных инструментов, а не как жизненно важный слой приложения. Акцент смещается на модель, а не на базу данных (или что у вас там) и слой доступа к ней. Это дает намного более сильный уровень независимости ваших классов от слоя сохранения (т.н. <a href="http://weblogs.asp.net/pgielens/archive/2005/07/29/420995.aspx">persistence ignorance</a>), который дает возможность быстро поменять базу данных или перейти с нее на XML или вообще какие-нибудь внешние сервисы. По сути, это снижение связанности (decoupling).</font> </li> <li><font face="Arial">Persistence ignorance дает еще одну полезную возможность. За счет того, что ваш код может жить и без слоя сохранения, его можно намного проще протестировать. Более того, в начале разработки вообще можно забить как на слой сохранения, так и на слой представления и написать сначала модель (по сути, слой бизнес логики), которую покрыть модульными тестами. Причем тесты здесь выполняют уже не столько роль парашюта на будущее, сколько роль клиентского кода более верхнего или того же слоя, при помощи которого вы можете отточить API классов модели, а также быстро поправить дизайн классов при необходимости. Слой же сохранения в таком случае можно для начала просто закрыть мок-объектами. Если пойти дальше, то в случае необходимости можно написать даже слой представления над моделью, еще даже не начав писать слой сохранения.</font> </li> <li><font face="Arial">Из предыдущего пункта вытекает то, что если вы апологет TDD, то DDD - это точно ваше. Более подходящий для TDD способ проектирования и разработки приложений сложно себе представить.</font> </li> </ol> <p><font face="Arial">Кроме всего прочего, Domain Driven Design стимулирует проектировать Rich Domain Model, то есть сущности, которые обладают не только состоянием, но и поведением. В результате разработки посредством Data Driven Design, мы очень часто получаем приложение, разработанное с использованием т.н. анемичной модели (Anemic Domain Model), в которой наши &quot;бизнес&quot; объекты на самом деле являются всего лишь сущностями для передачи данных из базы данных клиенту (UI, сервисы) и назад, т.е. обладают состоянием, но не поведением. Причем получаем мы это не потому что по-другому в Data Driven Design нельзя, а просто потому что в голове у нас это все те же записи из базы данных, просто переведенные на уровень кода. И как записи в базе данных не обладают никаким поведением, так и наши сущности, полученные оттуда, тоже сложно научить этому постфактум. Можно долго спорить о том, хороша ли анемичная модель или нет - это глупо. Просто как и у любого другого инструмента или подхода, у этого также есть свои положительные и отрицательные стороны и своя сфера применения. В приложениях, ориентированных лишь на CRUD операции, анемичная модель работает отлично. В приложениях, где много бизнес логики - уже не так хорошо. Бизнес логику приходится выносить в отдельные классы, которые будут оперировать объектами, хотя очень часто она по сути своей она принадлежит объектам.</font></p> <p><font face="Arial">Однако это еще не все. DDD - это не просто какая-то очередная методология разработки или догма проектирования. Скорее, это просто набор принципов, шаблонов, на которые можно опираться при проектировании. DDD очень активно оперирует ООП, паттернами, принципами (SOLID и пр.). Это вектор, направляющий разработку в несколько иное русло и помогающий решать задачи по-другому.</font></p> <p><font face="Arial">А что вы используете при проектировании приложений?</font></p> <p><font face="Arial">Дополнительно почитать о DDD можно в умных книжках:</font></p> <ol> <li><a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=pd_bxgy_b_img_a"><font face="Arial">Eric Evans. Domain-Driven Design: Tackling Complexity in the Heart of Software</font></a> </li> <li><a href="http://www.amazon.com/Applying-Domain-Driven-Design-Patterns-Examples/dp/0321268202/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1231066440&amp;sr=1-2"><font face="Arial">Jimmy Nilsson. Applying Domain-Driven Design and Patterns: With Examples in C# and .NET</font></a> </li> <li><a href="http://www.amazon.com/NET-Domain-Driven-Design-Solution-Programmer/dp/0470147563/ref=pd_sim_b_27"><font face="Arial">Tim McCarthy. .NET Domain-Driven Design with C#: Problem - Design - Solution (Programmer to Programmer)</font></a> </li> </ol> <p><font face="Arial">И в онлайне:</font></p> <ol> <li><a title="http://domaindrivendesign.org/" href="http://domaindrivendesign.org/"><font face="Arial">http://domaindrivendesign.org/</font></a> </li> <li><a title="http://hinchcliffe.org/archive/2005/03/20/189.aspx" href="http://hinchcliffe.org/archive/2005/03/20/189.aspx"><font face="Arial">http://hinchcliffe.org/archive/2005/03/20/189.aspx</font></a> </li> <li><a title="http://www.emxsoftware.com/Domain+Driven+Design/" href="http://www.emxsoftware.com/Domain+Driven+Design/"><font face="Arial">http://www.emxsoftware.com/Domain+Driven+Design/</font></a> </li> <li><a title="http://www.infoq.com/articles/ddd-in-practice" href="http://www.infoq.com/articles/ddd-in-practice"><font face="Arial">http://www.infoq.com/articles/ddd-in-practice</font></a> </li> <li><a title="http://www.udidahan.com/2007/03/06/better-domain-driven-design-implementation/" href="http://www.udidahan.com/2007/03/06/better-domain-driven-design-implementation/"><font face="Arial">http://www.udidahan.com/2007/03/06/better-domain-driven-design-implementation/</font></a> </li> </ol> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-5787206159639687027?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com20tag:blogger.com,1999:blog-1968777209535947779.post-79924720085166865732008-12-31T11:14:00.001+02:002009-01-24T11:48:14.930+02:00Немножко об уличных фонарях<p><font face="Arial">Несмотря на преимущественную техническую ориентированность блога, хотелось бы завершить год на мажорной ноте, то есть чем-нибудь неайтишном :) Поэтому последней заметкой уходящего 2008 года будет фотозаметка. А посвящена она будет не чему-нибудь, а уличным фонарям.</font></p> <p><font face="Arial">Дело в том, что я питаю какую-то странную слабость к этим небольшим, скромным, но от этого не менее прекрасным спутникам тихих парков и шумных улиц наших городов. Осознал я это только недавно, поймав себя на этой мысли во время съемки очередного фонаря. Просмотрев свои предыдущие фотографии, я понял, что во многих местах, где я побывал, я тоже их фотографировал, просто без осознания. Объяснить эту любовь сложно. Думаю, здесь в первую очередь играет роль то, что фонарь &#8211; это олицетворение источника света в темноте нашей жизни, который всегда на посту, всегда готов помочь людям найти дорогу. Это олицетворение постоянного служения, бескорыстного, безупречного, часто многовекового. Уличные фонари наполнены какой-то грустью. Их рабочий день начинается, когда большинство людей уже сидят в теплых домах и пьют чай, и заканчивается, когда мы просыпаемся и только-только выходим на работу. По большей части они стоят в одиночестве в ночной темноте, и лишь изредка их одиночество скрашивается одним или несколькими прохожими, которые спешат домой или на работу, ничего не замечая вокруг, даже тех, кто освещает им дорогу. Но фонари слишком скромны, чтобы просить благодарности, и слишком великодушны, чтобы обижаться на нас за это. Они просто делают свою работу, день за днем, год за годом, век за веком. </font><font face="Arial">Эта заметка &#8211; благодарность им за то, что они несут свет в наши жизни.</font></p> <p><font face="Arial"><strong>Полтава</strong></font></p> <p><font face="Arial"><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs3q0xnLqI/AAAAAAAAIDc/YVz1aT2UoUI/s1600-h/Picture%20098%5B2%5D.jpg"><img title="Picture 098" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="Picture 098" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs3rlixuiI/AAAAAAAAIDg/ThBHGpDNC44/Picture%20098_thumb.jpg?imgmax=800" width="184" border="0" /></a>&#160; <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs3smxHgtI/AAAAAAAAIDk/mFBD7bEm60A/s1600-h/Picture%20117%5B5%5D.jpg"><img title="Picture 117" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="Picture 117" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SVs3tVY79rI/AAAAAAAAIDo/xxu7EITGl84/Picture%20117_thumb%5B1%5D.jpg?imgmax=800" width="184" border="0" /></a> </font></p> <p><font face="Arial">&#160;<a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SXrjM6rE4HI/AAAAAAAAIOU/MSlWVJ_b_Ws/Picture%20115%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="Picture 115" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SXrjPvBdEtI/AAAAAAAAIOk/xIlFMsnCp_0/Picture%20115_thumb.jpg" width="244" border="0" /></a> </font></p> <p><font face="Arial"><strong>Киев</strong></font></p> <p><font face="Arial"><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs3ud1k7LI/AAAAAAAAIDs/DNp9A4F1nEA/s1600-h/Picture%20119%5B5%5D.jpg"><img title="Picture 119" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="Picture 119" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs3vxL4mXI/AAAAAAAAIDw/FXkOPUUb4Tg/Picture%20119_thumb%5B1%5D.jpg?imgmax=800" width="184" border="0" /></a>&#160;<a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs3w2k_flI/AAAAAAAAID0/5dpMcoSWTOs/s1600-h/Picture%20063%5B5%5D.jpg"><img title="Picture 063" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="Picture 063" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs3x4x3dqI/AAAAAAAAID4/jKYYD5yi2NI/Picture%20063_thumb%5B1%5D.jpg?imgmax=800" width="184" border="0" /></a> </font></p> <p><font face="Arial"><strong>Днепропетровск</strong></font></p> <p></p> <p></p> <p></p> <p></p> <p><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs3yuZZ_UI/AAAAAAAAID8/EAvehMlJfC8/s1600-h/Picture%20016%5B2%5D.jpg"><img title="Picture 016" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="Picture 016" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs3zTTOx3I/AAAAAAAAIEA/c1m1Mkzj53w/Picture%20016_thumb.jpg?imgmax=800" width="184" border="0" /></a> </p> <p><strong><font face="Arial">Коломыя</font></strong></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs30PzCc_I/AAAAAAAAIEE/7JwukE6gCZQ/s1600-h/IMG_2706%5B2%5D.jpg"><img title="IMG_2706" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_2706" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs30xYjufI/AAAAAAAAIEI/rFzA-eiz-SQ/IMG_2706_thumb.jpg?imgmax=800" width="184" border="0" /></a> </p> <p><strong><font face="Arial">Львов</font></strong></p> <p><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs33IS3XuI/AAAAAAAAIEM/WF1gH0G6a4U/s1600-h/IMG_2584%5B2%5D.jpg"><img title="IMG_2584" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_2584" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs34IS_LpI/AAAAAAAAIEQ/lAD7ohX5yw4/IMG_2584_thumb.jpg?imgmax=800" width="184" border="0" /></a> </p> <p><strong><font face="Arial">Санкт-Петербург</font></strong></p> <p></p> <p></p> <p><a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SVs344s88YI/AAAAAAAAIEU/Hl_lVQweuR8/s1600-h/IMG_4988%5B2%5D.jpg"><img title="IMG_4988" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_4988" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SVs35ldWcaI/AAAAAAAAIEY/UXW1M2LzCuU/IMG_4988_thumb.jpg?imgmax=800" width="184" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs36df0O6I/AAAAAAAAIEc/vzzzZZAFmh8/s1600-h/IMG_5416%5B2%5D.jpg"><img title="IMG_5416" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_5416" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs37OYRRgI/AAAAAAAAIEg/cVHcmDG5aPU/IMG_5416_thumb.jpg?imgmax=800" width="184" border="0" /></a> </p> <p></p> <p><strong><font face="Arial">Москва</font></strong></p> <p><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SXrjSH8e_NI/AAAAAAAAIOo/SP_w2KfO4dE/Picture%20509%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 509" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrjXK9cyHI/AAAAAAAAIO0/4FCgoI3mi9E/Picture%20509_thumb.jpg" width="184" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrjaaLrT6I/AAAAAAAAIO4/t5F5uqAwv3E/Picture%20558%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Picture 558" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SXrjehubXMI/AAAAAAAAIO8/pjCstG7SP5A/Picture%20558_thumb.jpg" width="178" border="0" /></a> </p> <p><strong><font face="Arial">Иркутск</font></strong></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs38OVag4I/AAAAAAAAIEk/EsvN6M47HIQ/s1600-h/Picture%20470%5B2%5D.jpg"><img title="Picture 470" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="Picture 470" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs39L0C-HI/AAAAAAAAIEo/OSO9D9bNEms/Picture%20470_thumb.jpg?imgmax=800" width="244" border="0" /></a> </p> <p><font face="Arial">И наконец, <strong>Харьков</strong></font></p> <p><strong><a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs3-aqo5KI/AAAAAAAAIEs/E0jmT5UW_Yw/s1600-h/IMG_8279%5B2%5D.jpg"><img title="IMG_8279" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_8279" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs3_ZQYDNI/AAAAAAAAIEw/SZftfd06Lls/IMG_8279_thumb.jpg?imgmax=800" width="184" border="0" /></a> <a href="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs4AmnvLOI/AAAAAAAAIE0/NhdM-4o2qv8/s1600-h/IMG_2966%5B2%5D.jpg"><img title="IMG_2966" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="IMG_2966" src="http://lh5.ggpht.com/_lCZq7P5BnMo/SVs4BRMwcUI/AAAAAAAAIE4/R1tw3AshN5Q/IMG_2966_thumb.jpg?imgmax=800" width="184" border="0" /></a> <a href="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrjg6mFw5I/AAAAAAAAIPI/fyR6T-AlzYk/IMG_3217%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="IMG_3217" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrjja0vCcI/AAAAAAAAIPM/yu1XsRVFS4c/IMG_3217_thumb.jpg" width="184" border="0" /></a>&#160; </strong></p> <p></p> <p></p> <p><a href="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs4CrooyZI/AAAAAAAAIE8/_0aJtUO_dlI/s1600-h/Picture%20077%5B2%5D.jpg"><img title="Picture 077" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="Picture 077" src="http://lh6.ggpht.com/_lCZq7P5BnMo/SVs4Dt4Y5cI/AAAAAAAAIFA/cjKAca49wGQ/Picture%20077_thumb.jpg?imgmax=800" width="244" border="0" /></a> <a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SXrjqGEFoCI/AAAAAAAAIPY/ae30TayGt5w/IMG_3210%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="IMG_3210" src="http://lh3.ggpht.com/_lCZq7P5BnMo/SXrjsBNcLCI/AAAAAAAAIPc/fj_Sepi3M6w/IMG_3210_thumb.jpg" width="244" border="0" /></a> </p> <p><a href="http://lh4.ggpht.com/_lCZq7P5BnMo/SXrjx442bvI/AAAAAAAAIPg/GMIxWtBmjFI/IMG_3210_kvadrat_bw%5B2%5D.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="238" alt="IMG_3210_kvadrat_bw" src="http://lh4.ggpht.com/_lCZq7P5BnMo/SXrj2bBUuyI/AAAAAAAAIPs/P8YVDmBjz0E/IMG_3210_kvadrat_bw_thumb.jpg" width="244" border="0" /></a> </p> <p><font face="Arial">Еще раз поздравляю всех с Новым годом и Рождеством! :)</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-7992472008516686573?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com6tag:blogger.com,1999:blog-1968777209535947779.post-57931164575755694572008-12-30T15:50:00.001+02:002009-01-02T21:40:42.898+02:00Разминка мозга №1. Числа и Новый год<p><font face="Arial">Думаю, ни для кого ни секрет, что программирование заключается не столько в знании какой-то технологии, сколько в умении составлять алгоритмы для решения сложных задач. У кого-то из вас, возможно, даже есть какой-то опыт олимпиад по программированию, где эти задачи, мягко говоря, бывают очень даже и очень :) Да, они зачастую абстрактны и оторваны от жизни, но это же не их основная задача. А основная их задача в том, чтобы развивать голову и не давать мозгам ржаветь. Вот и я вам предлагаю размять мозги перед встречей новогодних праздников :)</font></p> <p><font face="Arial">Задачка изначально была совсем не новогодняя, но я решил, что надо ее видоизменить в связи с праздниками, а заодно и запутать вам возможность поиска ответа в <a href="http://www.google.com.ua">великом и ужасном</a> ;)</font></p> <p><font face="Arial">Итак, представьте себе: Жил да был на свете Дед Мороз (он же &#8211; Санта Клаус). Да, это тот самый дедушка, который на Новый год приносят хорошим деткам конфеты и мандарины, а взрослым &#8211; iPod&#8217;ы и Wii. Что, вам не принесли? Ну, значит плохо себя вели ;)</font></p> <p><font face="Arial">Так вот, у Деда Мороза есть олени, много оленей (N). Чтобы не запутаться в них, он их пронумеровал положительными целыми числами, причем так, что нет двух оленей с одинаковыми номерами. Правда, номера могут начинаться не с 1 и иметь пропуски в числах. И вот стоят эти олени в длинном хлеву в стойлах, один за другим, без какой-либо последовательности (номера идут в произвольном порядке). Дед Мороз может ходить мимо этих стойл только в одном направлении, то есть заходит с одной стороны и идет до самого конца, потом обходим хлев снаружи и заходит снова со входа. И вот у нашего дедушки появился новый олень (Снегурочка подарила на день рождения, например). И захотел дедушка наконец-то навести порядок в своих оленях и присвоить новому оленю самый маленький номер из тех, что у него нет. Ну, чтобы заполнить пробелы. То есть ему нужно обойти своих подопечных (только в одну сторону, сколько угодно раз), определить минимальный положительный номер, которого нет у существующих оленей, и присвоить его новоприбывшему.</font></p> <p><font face="Arial">Однако, дедушка стар, и ваша задача &#8211; помочь ему найти это число за минимальное количество проходов по хлеву. На беду, у дедушки еще одна проблема &#8211; у него не очень хорошая память, он может запомнить лишь несколько чисел (для определенности положим не больше 5), а писать он не умеет. Зато дедушка умеет считать :) Складывать, вычитать, умножать и делить. Думаю, он умеет еще извлекать корни и решать интегральные уравнения третьего порядка, но к нашей задаче это отношения не имеет :)</font></p> <p><font face="Arial">Вот, собственно, и все. Прошу алгоритмы в комментарии, товарищи программисты и не только. Чур, код не писать, покажите, на что вы способны без компилятора ;)</font></p> <p><font face="Arial">PS. С наступающими вас! Пусть 2009 год даст новые идеи и мечты, а также энергию и устремление для их реализации! И, конечно, счастья, здоровья и любви вам и вашим близким!</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-5793116457575569457?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com11tag:blogger.com,1999:blog-1968777209535947779.post-12095295256272796742008-12-22T11:28:00.001+02:002009-01-02T21:41:55.800+02:00Доклад на харьковской UNETA<p><font face="Arial">Судя по всему, я буду одним из докладчиков на следующей харьковской UNETA, которая ориентировочно будет в начале-середине января. Тема у меня будет не совсем обычная, она будет связана с производительностью ORM. Точно будут L2S и EF, возможно, добавлю что-то еще, если хватит времени. Так как тема не связана с какой-то конкретной технологией, скорее, это разбор и сравнение, то я могу немного варьировать ее содержание. В связи с этим у меня возник вопрос, что бы вам хотелось услышать? В принципе, скелет доклада я уже продумал, но все равно есть место для различных деталей, тестов, которые я могу провести и т.д. Я постараюсь учесть все пожелания и осветить их в докладе по-максимуму.</font></p> <p><font face="Arial">В докладе я постараюсь рассказать о том, как работают рассматриваемые ORM внутри, что именно влияет на их производительность, проведу некоторые наиболее интересные и показательные тесты для их сравнения между собой и с чистым ADO.NET, и постараюсь рассмотреть генерируемые каждой ORM запросы.</font></p> <p><font face="Arial">Итак, у меня есть несколько вопросов к вам:</font></p> <ol> <li><font face="Arial">Стоит ли включать в доклад NHibernate? Или достаточно будет L2S и EF?</font> </li> <li><font face="Arial">Какие тесты вы бы хотели увидеть?</font> </li> <li><font face="Arial">Какие сопутствующие темы вам были бы интересны? Что из неописанного выше можно осветить еще?</font> </li> </ol> <p><font face="Arial">Ответы прошу оставлять в комментариях. </font><font face="Arial">Прошу поучаствовать в опросе не только харьковчан, которые планируют идти на UNETA, но и всех, кому это интересно. После доклада я сделаю отдельный пост, посвященный результатам, в котором выложу и презентацию, и тесты, и их результаты.</font></p> <p><font face="Arial">Спасибо за помощь :)</font></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-1209529525627279674?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com16tag:blogger.com,1999:blog-1968777209535947779.post-4916102786911511352008-12-13T13:47:00.002+02:002008-12-13T13:48:29.261+02:00Дао программиста<p><font face="Arial">Думаю, каждый программист в своей работе уже определил для себя, что программирование состоит как минимум из двух компонентов: технологий и подходов (возможно, не самое лучшее слово для описания данного термина, но лучше термин я не нашел).</font></p> <p><font face="Arial">Технологии определяют <strong>“чем”</strong> мы работаем, т.е. это набор инструментов: языки программирования, базы данных, среды, тулзы, библиотеки классов, фреймворки, компоненты и т.д. То есть, если взять аналогию с токарем, это те инструменты и материальные приспособления, которые он использует для изготовления деталей.</font></p> <p><font face="Arial">Подходы же определяют <strong>“как”</strong> мы используем все эти инструменты и пишем код, т.е. в случае программирования это понимание и правильное использование ООП, </font><a href="http://igor.quatrocode.com/2008/09/solid-top-5.html"><font face="Arial">SOLID</font></a><font face="Arial">, паттернов проектирования (GoF, Fowler), каких-то других Patterns &amp; Best Practices, архитектурных принципов, рефакторинга, алгоритмов, структур данных и т.д. Сюда же можно отнести и знание и использование таких практик, как TDD, DDD и пр. В том числе это и тот опыт, который мы приобретаем в процессе работы. В случае с токарем это его умение вытачивать те или иные детали, которое он тоже совершенствует.</font></p> <p><font face="Arial">У каждого программиста эти 2 компонента развиты в разных соотношениях. Есть ребята гармонично развитые, которые, например, не только знают о том, что есть такая штука как ООП, но и правильно его используют. Есть отклонения в ту или иную сторону.</font></p> <p><font face="Arial">Как правило, у начинающих программистов идет четкий перекос в сторону технологий. Они изучают язык(и) программирования, технологии разработки веб-приложений и доступа к данным в университете или по книжкам (статьям в инете/msdn/блогам, нужное подчеркнуть), и верят в то, что этого знания достаточно не только для того, чтобы написать приложение любой сложности, но и чтобы быть классным программистом в целом. Они также часто верят в то, что на любой их вопрос всегда найдется ответ в гугле, что какие-то там непонятные паттерны проектирования им не нужны и что они знают ООП в совершенстве (дружный смех в зале). Что, узнаете себя в молодости? :)</font></p> <p><font face="Arial">Прозрение приходит со временем. Вдруг оказывается, что есть еще такие вещи, как сложность приложения, связность, взаимозависимость, что ты пишешь не ООП-код, а процедуры, сгрупированные в классы, что рефакторинг – это не простой звук, а реальность, что unit-тесты – это не прихоть лида или архитекта, а отличное средство подерживать качество продукта (и кода) в здоровом состоянии. Программист начинается развиваться не только в сторону технологий, но и в сторону подходов. Приходит понимание, что технологии уже не так и важны, потому что практически любую из них ты можешь изучить довольно быстро, а вот на переписывание каличного кода можно потратить недели и месяцы. Кроме того, накопленный опыт позволяет даже относительно легко перепрыгнуть на другой язык программирования или даже платформу. Программист выходит из установленных рамок и начинает понимать, когда ту или иную технологию лучше использовать, а когда стоит избегать ее как огня. Сейчас вот мы большой кистью закрасим небо, а потом возьмем маленькую и прорисуем на его фоне ветки дерева и листики. Вы знаете, а здесь вообще акварель не подойдет, давайте это все маслом сделаем! Это уже уровень понимания начинающего архитекта.</font></p> <p><font face="Arial">Неужели это конец развития? Нет, конечно, это только начало. Во-первых, нет предела совершенству, и знание и понимание тех же технологий можно и нужно увеличивать. А во-вторых, когда программист переходит на уровень архитекта, у него начинаются уже свои головные боли и дальнейшее развитие, но уже не как программиста. Есть application architect, solution architect, enterprise architect, etc. и у каждого свои навыки и знания. Про дао архитекта я пока написать не могу, извините, не дорос еще :) Но оно есть, я в этом уверен.</font></p> <p><font face="Arial">К чему я все это веду? К тому, чтобы все понимали, что в работе программиста важны и технологии, и подходы, что даже отличное знание технологий еще не делает программиста инженером. На одном крыле далеко не улетишь. Ну и чтобы каждый мог понять хотя бы приблизительно, на каком уровне он сейчас находится и увидел, что именно нужно развивать. Благо, книги есть не только по технологиям, но и по подходам. Изучайте ООП, паттерны, рефакторинг, всякие TDD/DDD/Agile/прочее, это чужой опыт, который может помочь вам стать настоящим профессионалом. Успехов!</font></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1968777209535947779-491610278691151135?l=merle-amber.blogspot.com'/></div>Александр Кондуфоровhttp://www.blogger.com/profile/03000892844767433158noreply@blogger.com10