На прошлой неделе закончил читать книгу Эндрю Ханта и Дэвида Томаса "Программист-прагматик. Путь от подмастерья к мастеру".
Читал книгу в формате FictionBook на своем смартфоме Samsung Galaxy S с помощью замечательной программы-читалки Cool Reader.
Впечатления очень положительные. Изложение в книге не сложное, так как там практически отсутствуют точные технические сведения, как это часто бывает в нашей технической литературе.
Авторы раскрывают скорее принципы, которыми должен руководствоваться любой программист в своей повседневной работе.
Крайне рекомендую прочитать эту книгу любому программисту, независимо от его уровня. Начинающий разработчик найдет для себя целый срез полезных знаний, опытный разработчик также с очень большой вероятностью найдет для себя что-то новое.
Лично мне читать эту книгу было крайне легко, так как большую часть вещей изложенных в книге я уже использую в своей повседнемной работе. Очень понравилась компактность изложения и столь большое количество системных советов, которыми могут руководствоваться разработчики независимо от их профиля и выбранной платформы.
Ниже привожу цитаты из книги, которые мне понравились.
(Об управлении временем жизни у зависимых объектов)
Есть три основных варианта развития событий:
1. Структура верхнего уровня также несет ответственность за освобождение любых входящих в нее подструктур. Затем эти структуры рекурсивно удалят данные, содержащиеся в них, и т. д.
2. Структура верхнего уровня просто освобождается. Любые структуры, на которые она указывает (и на которых нет других ссылок), становятся "осиротевшими".
3. Структура верхнего уровня отказывается освобождать себя, если в нее входят какие-либо подструктуры
Хотя принцип "модель-визуальное представление-контроллер" обычно реализуется в контексте графического интерфейса, на самом деле он является универсальной методикой программирования. Визуальное представление – это некая интерпретация модели (возможно, подмножества), и она не обязана быть графической. Контроллер в большей части является механизмом координации и не должен ассоциироваться с устройством ввода любого типа.
Подсказка 24: Занимайтесь устранением проблемы, а не обвинениями
Программное обеспечение работает несколько по-иному. В отличие от строительства, написание программ ближе к садоводству, оно ближе к живой природе, чем к бетонным конструкциям. Вы высаживаете в саду множество растений согласно первоначальному плану и условиям. Некоторые растения разрастаются, другим же уготована компостная яма. Вы можете пересаживать растения друг относительно друга, чтобы извлечь пользу из взаимодействия света и тени, ветра и дождя. Переросшие растения разрубают или обрезают, растения определенного цвета пересаживают на другие участки, где они становятся более приятными глазу с точки зрения эстетики. Вы выпалываете сорняки и подкармливаете растения, которые нуждаются в дополнительном питании. Вы постоянно следите за состоянием сада и при необходимости вносите изменения (в почву, растения, общий план)
Метафора садоводства намного ближе к реальности разработки программного обеспечения. Возможно, некая программа переросла себя или пытается осуществить слишком много – ее необходимо разбить на две. Все, что не получается в соответствии с планом, подлежит прополке или обрезке.
Попробуйте объяснить этот принцип вашему шефу, пользуясь аналогией с медициной: рассматривайте программу, нуждающуюся в реорганизации,реорганизации, как «опухоль». Чтобы удалить ее, требуется хирургическое вмешательство. Вы можете начать сразу и извлечь ее, пока она небольшая. Но если вы будете ждать, пока она вырастет и распространится, то ее удаление станет более дорогой и опасной процедурой. Подождите еще, и вы можете потерять пациента окончательно.
Многие книги и учебные пособия относят процедуру сбора исходных требований к начальной фазе проекта. Термин «сбор» напоминает о племени счастливых аналитиков, занимающихся собирательством камней-самородков мудрости, разбросанных по земле на фонеприглушенного звучания "Пасторальной симфонии". Этот термин напоминает о том, что все требования уже имеются в наличии, нужно лишь отыскать их, положить в корзину и весело шагать дальше.
Это не совсем так. Требования редко лежат на поверхности. Обычно они находятся глубоко под толщей предположений, неверных представлений и политики.
Важно обнаружить основополагающую причину того, почему пользователи поступают определенным образом, а не так, как они привыкли это делать. В конечном итоге разрабатываемой программе придется решать проблемы их бизнеса, а не просто отвечать их заявленным требованиям.
Вы отклонились от графика выполнения проекта или уже отчаялись увидеть систему работающей, поскольку конкретную проблему "невозможно решить". В этот момент необходимо сделать шаг назад и задать себе несколько вопросов:
• Существует ли более простой способ?
• Вы пытаетесь решить главную проблему или отвлекаетесь на второстепенные технические детали?
• Почему это является проблемой?
• Что делает эту проблему столь сложной для решения?
• Стоит ли делать это именно таким образом?
• Стоит ли это делать вообще?
И во многих случаях секрет удивительным образом раскроется перед вами, как только вы попробуете ответить на один из этих вопросов.
Подсказка 59: Дорогие инструменты не всегда создают лучшие решения
Конечно, в разработке программ есть место формальным методам. Однако, столкнувшись с проектом, философия которого заключается в изречении "диаграмма класса и есть приложение, все остальное – лишь механическое составление текста программы", знайте, что имеете дело с проектной командой, которая уцепилась за плавучее бревно и медленно гребет к берегу.
В группе L Стоффел руководит шестью первоклассными программистами – это руководящая работа, которую можно приравнять к управлению бродячими котами.
Журнал "Washington Post" от 9 июня 1985 г.
Подсказка 66: Дефект должен обнаруживаться единожды
Если дефект проскальзывает через сеть существующих тестов, вам необходимо добавить новый тест, чтобы поймать его в следующий раз.
В абстрактном смысле приложение успешно, если оно корректно реализует свои спецификации. К сожалению, это и оплачивается лишь абстрактно.
В действительности успех проекта измеряется тем, насколько он соответствует надеждам своих пользователей. Проект, не оправдавший их надежд, обречен на неудачу, неважно, насколько хорошо он соответствовал срокам.
Программисты-прагматики не уклоняются от ответственности. Вместо этого они испытывают радость, принимая вызовы и распространяя свой опыт. Если мы несем ответственность за проектное решение или фрагмент программы, мы делаем работу, которой можем гордиться.
среда, 17 августа 2011 г.
воскресенье, 20 марта 2011 г.
Сегодня Windows 7 довел меня до белого каления
На системном разделе моего ноутбука объем которого составляет 25 Гб (!) нехватает свободного места. Точнее там тупо ноль байт. Из-за этого масса проблем.
В качестве решения проблемы решил перенести c:\Program Files\ и c:\Program Files (x86)\ на другой раздел и сделать Junction Point.
Скопировал все содержимое, но теперь не могу удалить каталог и поменять права, даже с правами администратора.
Администратор не имеет права на удаление этого каталога, только TrustedInstaller и Local System имеет право удалить этот каталог.
Запустить cmd сессию от Local System аккаунта можно с помощью PsTools\PsExec. Но они не работают из-за какого-то дефекта в 64-редакции Windows 7.
Есть хотфик, который решает эту проблему, но чтобы его скачать нужно ввести свой email и капчу. Терпение на исходе.
На почтовый ящик пришло письмо с прямой ссылкой и паролем. Скачал, распаковал. После чего получил сообщение что hotfix не может быть установлен.
Если посмотреть на проблему изначально - 25 Гб под системный раздел для ноутбука это много или мало по состоянию на 2011 год?
Чтобы картина была более ясна отмечу что в каталог c:\Users я не сохраняю никаких своих документов.
Весь установленный софт занимает не так уж и много места:
305 Мб - C:\Program Files\
441 Мб - C:\Program Files (x86)\
1,31 Гб - C:\soft\ причем этот каталог можно не считать, так как все данные лежат на другом разделе, а это Junction Point.
Иногда я жалею что я .NET разработчик, который зависит от операционной системы Windows.
Если бы я в повседневной работе использовал только кроссплатформенные решения, то у меня хотя бы был выбор...
Update: Удалось найти достаточно простое решение моей проблемы вот тут
http://helpdeskgeek.com/windows-7/windows-7-how-to-delete-files-protected-by-trustedinstaller/
В качестве решения проблемы решил перенести c:\Program Files\ и c:\Program Files (x86)\ на другой раздел и сделать Junction Point.
Скопировал все содержимое, но теперь не могу удалить каталог и поменять права, даже с правами администратора.
Администратор не имеет права на удаление этого каталога, только TrustedInstaller и Local System имеет право удалить этот каталог.
Запустить cmd сессию от Local System аккаунта можно с помощью PsTools\PsExec. Но они не работают из-за какого-то дефекта в 64-редакции Windows 7.
Есть хотфик, который решает эту проблему, но чтобы его скачать нужно ввести свой email и капчу. Терпение на исходе.
На почтовый ящик пришло письмо с прямой ссылкой и паролем. Скачал, распаковал. После чего получил сообщение что hotfix не может быть установлен.
Если посмотреть на проблему изначально - 25 Гб под системный раздел для ноутбука это много или мало по состоянию на 2011 год?
Чтобы картина была более ясна отмечу что в каталог c:\Users я не сохраняю никаких своих документов.
Весь установленный софт занимает не так уж и много места:
305 Мб - C:\Program Files\
441 Мб - C:\Program Files (x86)\
1,31 Гб - C:\soft\ причем этот каталог можно не считать, так как все данные лежат на другом разделе, а это Junction Point.
Иногда я жалею что я .NET разработчик, который зависит от операционной системы Windows.
Если бы я в повседневной работе использовал только кроссплатформенные решения, то у меня хотя бы был выбор...
Update: Удалось найти достаточно простое решение моей проблемы вот тут
http://helpdeskgeek.com/windows-7/windows-7-how-to-delete-files-protected-by-trustedinstaller/
суббота, 5 февраля 2011 г.
The very first .NET Saturday in IT Café_
Сегодня, пятого февраля сходил на событие, проходящее под эгидой компании Ciklum, которое называется .NET Saturday.
В большинстве случаев заметки в свой блог мне писать очень и очень лень, но тут решил написать буквально пару строк о прошедшем событии.
Формат события такой. В обычном, но довольно привлекательном кафе освобождают часть зала, в зоне которого находится докладчик, все слушатели сидят прямо за своими столиками и слушают доклад. Один за другим идет ряд докладов с 15-ти минутными перерывами между ними. В перерыве между докладами можно попить чаю, кофе, поесть печеньки или конфеты.
Были прочитаны следующие доклады:
- Александр Краковецкий (Винница, head of MS User Group) «Тестирование производительности .NET приложений»;
- Дмитрий Пасько (Харьков, Team Leader) «NuGet- package management for the .NET platform»;
- Андерс Соренсен (Дания, Site manager) «Optimizing development in an offshore context»;
- Михаил Вальков (Харьков, Senior .net developer) «Antipatterns»
Мероприятие продолжалось с 15:00 по 19:00 и количество времени выделенного на каждый доклад было достаточным.
Признаюсь, что решение идти на это мероприятие меня в первую очередь натолкнула тема первого доклада, хотя после окончания мероприятия лично для меня оказались самыми интересными доклад Дмитрия Пасько по NuGet и доклад Андерса Соренсена.
Искренне благодарю всех докладчиков за их труд и время. Это очень ценно, когда человек находит желание и силы поделиться своими знаниями с локальным сообществом. В этом отношении мне несколько стыдно, поскольку я бы наверное тоже мог бы поделиться определенными вещами с коллегами по работе в рамках того или иного доклада, но до сих пор я себя так и не смог заставить это сделать.
Хотелось бы еще отметить, что формат этого мероприятия мне крайне понравился. Его продолжительность была не маленькой, но при этом я ушел оттуда не уставшим, а может быть даже отдохнувшим. Возможность попить чаю прямо посередине прослушивания доклада, выйти на улицу в перерыв для того чтобы проветрить мозги – все это было очень кстати. Сами столики очень расслабляли и наталкивали на дискуссию, хотя я бы не отказался от более длинного перерыва, чтобы успеть и проветриться и успеть похоливарить с товарищами за столиком.
Компания Ciklum планирует проводить подобные мероприятия около одного раза в месяц по субботам. Если вы вдруг узнаете о данном мероприятии, то рекомендую на него сходить хотя бы один раз для пробы.
На всякий случай отмечу, что я не работаю в Ciklum и не имею к компании никакого отношения даже не смотря на то, что по моей «вине» на это мероприятие пришло пять моих товарищей. :) Ребята, надеюсь что вам там тоже понравилось.
В большинстве случаев заметки в свой блог мне писать очень и очень лень, но тут решил написать буквально пару строк о прошедшем событии.
Формат события такой. В обычном, но довольно привлекательном кафе освобождают часть зала, в зоне которого находится докладчик, все слушатели сидят прямо за своими столиками и слушают доклад. Один за другим идет ряд докладов с 15-ти минутными перерывами между ними. В перерыве между докладами можно попить чаю, кофе, поесть печеньки или конфеты.
Были прочитаны следующие доклады:
- Александр Краковецкий (Винница, head of MS User Group) «Тестирование производительности .NET приложений»;
- Дмитрий Пасько (Харьков, Team Leader) «NuGet- package management for the .NET platform»;
- Андерс Соренсен (Дания, Site manager) «Optimizing development in an offshore context»;
- Михаил Вальков (Харьков, Senior .net developer) «Antipatterns»
Мероприятие продолжалось с 15:00 по 19:00 и количество времени выделенного на каждый доклад было достаточным.
Признаюсь, что решение идти на это мероприятие меня в первую очередь натолкнула тема первого доклада, хотя после окончания мероприятия лично для меня оказались самыми интересными доклад Дмитрия Пасько по NuGet и доклад Андерса Соренсена.
Искренне благодарю всех докладчиков за их труд и время. Это очень ценно, когда человек находит желание и силы поделиться своими знаниями с локальным сообществом. В этом отношении мне несколько стыдно, поскольку я бы наверное тоже мог бы поделиться определенными вещами с коллегами по работе в рамках того или иного доклада, но до сих пор я себя так и не смог заставить это сделать.
Хотелось бы еще отметить, что формат этого мероприятия мне крайне понравился. Его продолжительность была не маленькой, но при этом я ушел оттуда не уставшим, а может быть даже отдохнувшим. Возможность попить чаю прямо посередине прослушивания доклада, выйти на улицу в перерыв для того чтобы проветрить мозги – все это было очень кстати. Сами столики очень расслабляли и наталкивали на дискуссию, хотя я бы не отказался от более длинного перерыва, чтобы успеть и проветриться и успеть похоливарить с товарищами за столиком.
Компания Ciklum планирует проводить подобные мероприятия около одного раза в месяц по субботам. Если вы вдруг узнаете о данном мероприятии, то рекомендую на него сходить хотя бы один раз для пробы.
На всякий случай отмечу, что я не работаю в Ciklum и не имею к компании никакого отношения даже не смотря на то, что по моей «вине» на это мероприятие пришло пять моих товарищей. :) Ребята, надеюсь что вам там тоже понравилось.
четверг, 2 сентября 2010 г.
Вышел Castle.Windsor (включая Core, DynamicProxy, DictionaryAdapter) версии 2.5
Ура товарищи.
Вышел стабильный релиз Castle.Windsor, который я со спокойной совестью теперь могу рекомендовать даже начинающим ЙОК-овцам (IoC, Inversion of Control).
В анонсе бета релиза была масса отличных новостей:
- объединили Castle.Core, Caste.DynamicProxy, Castle.DictionaryAdapter в Castle.Core
- объединили Castle.MicroKernel, Castle.Windsor в Castle.Windsor
- сделали ряд незначительных breaking changes (читал описание, там все очень экзотическое и редко используемое). Можно было бы более крепко пройтись по старому API
- весь устаревший API отметили как obsolete. До этого там была настоящая каша. Прямо как в Rhino.Mocks
Castle объединяет сборки, а (Microsoft) Unity декомпозирует. ...ребята которые пидалят Unity не ведают что творят :)
К счастью основная проблема с высоким порогом вхождения была решена - благодаря тому что методы были отмечены как obsolete, новички не будут выносить себе мозг в поисках того какие именно методы стоит использовать, а какие не стоит. Более того, разработчики обещают вообще удалить все obsolete методы в релизе 3.0.
До релиза 2.5, когда у меня спрашивали что лучше использовать в качестве IoC контейнера, я постоянно колебался в ответе. Обычно рекомендовал смотреть либо на Castle.Windsor либо на Autofac и говорил что если будут малейшие сложности с Castle.Windsor, то не морочить с ним долго голову.
Теперь же однозначно уверен что логичнее использовать Caslte.Windsor, а легкий Autofac стоит использовать только лишь в Silverlight проектах.
Пользуясь случаем приглашаю всех пользователей Caslte.Windsor "приложиться" к его улучшению, оставив свои предложения на фидбек сайте. Команда разработчиков реально прислушивается к пожеланиям их пользователей:
Provide more compact, discoverable fluent API
В качестве примера тут хорошо расписаны шаги миграции проекта S#arp Architecture на последнюю версию Castle.
Указывается как разрешить проблему зависимости NHibernate и Castle.Windsor на Castle.DynamicProxy, которая переехала в Castle.Core.
Описывается рефакторинг со старого API на новый API Castle.Windsor. Много внимания уделяется IWindsorInstaller, который мне очень понравился.
ЗЫ Да, я знаю что релиз как-бы вышел с пол месяца назад, но у меня таймауты... Уж простите :)
Вышел стабильный релиз Castle.Windsor, который я со спокойной совестью теперь могу рекомендовать даже начинающим ЙОК-овцам (IoC, Inversion of Control).
В анонсе бета релиза была масса отличных новостей:
- объединили Castle.Core, Caste.DynamicProxy, Castle.DictionaryAdapter в Castle.Core
- объединили Castle.MicroKernel, Castle.Windsor в Castle.Windsor
- сделали ряд незначительных breaking changes (читал описание, там все очень экзотическое и редко используемое). Можно было бы более крепко пройтись по старому API
- весь устаревший API отметили как obsolete. До этого там была настоящая каша. Прямо как в Rhino.Mocks
Castle объединяет сборки, а (Microsoft) Unity декомпозирует. ...ребята которые пидалят Unity не ведают что творят :)
К счастью основная проблема с высоким порогом вхождения была решена - благодаря тому что методы были отмечены как obsolete, новички не будут выносить себе мозг в поисках того какие именно методы стоит использовать, а какие не стоит. Более того, разработчики обещают вообще удалить все obsolete методы в релизе 3.0.
До релиза 2.5, когда у меня спрашивали что лучше использовать в качестве IoC контейнера, я постоянно колебался в ответе. Обычно рекомендовал смотреть либо на Castle.Windsor либо на Autofac и говорил что если будут малейшие сложности с Castle.Windsor, то не морочить с ним долго голову.
Теперь же однозначно уверен что логичнее использовать Caslte.Windsor, а легкий Autofac стоит использовать только лишь в Silverlight проектах.
Пользуясь случаем приглашаю всех пользователей Caslte.Windsor "приложиться" к его улучшению, оставив свои предложения на фидбек сайте. Команда разработчиков реально прислушивается к пожеланиям их пользователей:
Provide more compact, discoverable fluent API
В качестве примера тут хорошо расписаны шаги миграции проекта S#arp Architecture на последнюю версию Castle.
Указывается как разрешить проблему зависимости NHibernate и Castle.Windsor на Castle.DynamicProxy, которая переехала в Castle.Core.
Описывается рефакторинг со старого API на новый API Castle.Windsor. Много внимания уделяется IWindsorInstaller, который мне очень понравился.
ЗЫ Да, я знаю что релиз как-бы вышел с пол месяца назад, но у меня таймауты... Уж простите :)
среда, 11 августа 2010 г.
Полиглотное программирование в .NET это хорошо. История внедрения IronPython
Неплохая статья. Выгодно отличается трезвым взглядом человека-практика.
Признаюсь что читать все комментарии сил не нашел, но хотелось бы оставить одну галочку в Success Stories исключительно для статистики. :)
Уже несколько лет работаю на одном большом проекте в котором с самого начала присутствовал скриптинг.
Причем начиналось это все с написания скриптов общего назначения на NVelocity и это был сущий ад, поскольку Velocity ну никак не является скриптовым языком общего назначения.
Но это было время .NET 1.1, IronPython'а тогда еще не было, а нам нужна была возможность написания скриптов, которые бы вызывались во время отработки различных фабричных методов.
В какой-то момент мы нашли проект IronPython и начиная с версии 1.0 RC я был человеком, который "двигал" этот язык и передавал опыт работы другим командам внутри нашего проекта.
Все это происходило медленно, но верно. По ходу дела я переезжал с одного релиза на другой, решая разного рода проблемы взаимодействия C# и IronPython при хостинге DLR внутри C# приложения.
Вначале были переписаны скрипты с NVelocity на IronPython практически один-в-один. Разве что я старался скрипты представлять в более организованном, процедурном виде ну и использовать простейшие возможности языка.
Следующим этапом был постепенный перевод всех скриптов на более высокоуровневую объектную модель. Тут пришлось пройтись по некоторым не очевидным граблям, которые выплывали во время наследования абстрактных классов C# в типах, которые я реализовывал на языке Python.
В конечном счете теперь у нас на проекте появляется все больше и больше скриптов на IronPython, которые постепенно становятся все более "умными".
При этом, скажу что мы, как суровые челябинские разработчики, пишем без IntelliSense и без отладчика. Спасает то, что я разобрался как можно вытащить script stack trace. :)
В конечном счете я для себя сделал такой вывод:
Многоязыковость платформы .NET это однозначно хорошо, так как позволяет в определенных ситуациях находить отличные решения. И мне кажется что эта самая многоязыковость или даже "распыленность" Microsoft по C#/F#/VB.NET/IronPython/IronRuby вряд ли нанесет существенный вред платформе в целом и языку C# в частности.
Другое дело что от такого обилия языков программирования бедный разработчик теряется, но это уже проблемы этого разработчика. Кто-то пусть делает ставку на проверенную лошадку, кто-то пусть экспериментирует. Главное что всем хватает места и это очень радует.
Признаюсь что читать все комментарии сил не нашел, но хотелось бы оставить одну галочку в Success Stories исключительно для статистики. :)
Уже несколько лет работаю на одном большом проекте в котором с самого начала присутствовал скриптинг.
Причем начиналось это все с написания скриптов общего назначения на NVelocity и это был сущий ад, поскольку Velocity ну никак не является скриптовым языком общего назначения.
Но это было время .NET 1.1, IronPython'а тогда еще не было, а нам нужна была возможность написания скриптов, которые бы вызывались во время отработки различных фабричных методов.
В какой-то момент мы нашли проект IronPython и начиная с версии 1.0 RC я был человеком, который "двигал" этот язык и передавал опыт работы другим командам внутри нашего проекта.
Все это происходило медленно, но верно. По ходу дела я переезжал с одного релиза на другой, решая разного рода проблемы взаимодействия C# и IronPython при хостинге DLR внутри C# приложения.
Вначале были переписаны скрипты с NVelocity на IronPython практически один-в-один. Разве что я старался скрипты представлять в более организованном, процедурном виде ну и использовать простейшие возможности языка.
Следующим этапом был постепенный перевод всех скриптов на более высокоуровневую объектную модель. Тут пришлось пройтись по некоторым не очевидным граблям, которые выплывали во время наследования абстрактных классов C# в типах, которые я реализовывал на языке Python.
В конечном счете теперь у нас на проекте появляется все больше и больше скриптов на IronPython, которые постепенно становятся все более "умными".
При этом, скажу что мы, как суровые челябинские разработчики, пишем без IntelliSense и без отладчика. Спасает то, что я разобрался как можно вытащить script stack trace. :)
В конечном счете я для себя сделал такой вывод:
Многоязыковость платформы .NET это однозначно хорошо, так как позволяет в определенных ситуациях находить отличные решения. И мне кажется что эта самая многоязыковость или даже "распыленность" Microsoft по C#/F#/VB.NET/IronPython/IronRuby вряд ли нанесет существенный вред платформе в целом и языку C# в частности.
Другое дело что от такого обилия языков программирования бедный разработчик теряется, но это уже проблемы этого разработчика. Кто-то пусть делает ставку на проверенную лошадку, кто-то пусть экспериментирует. Главное что всем хватает места и это очень радует.
суббота, 3 апреля 2010 г.
Inversion of Control and Dependency Injection. Ссылки
Inversion of Control and Dependency Injection: Working with Windsor Container
http://msdn.microsoft.com/en-us/library/aa973811.aspx
Ознакомительная статья, раскрывающая основные концепции Inversion of Control и Dependency Injection, которую написал Oren Eini aka Ayende Rahien. Носит предельно практических характер. Достаточно много хорошего материала, все изложение идет в ключе разработки некоего приложения (или сервиса) по обработке заказов. Крайне рекомендую эту статью к прочтению.
Inversion of Control and Dependency Injection with Castle Windsor Container. Four Parts.
Цикл статей об использовании Inversion of Control и Dependency Injection с помощью популярного фреймверка Castle.Windsor.
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart1.aspx
Первая статья является вводной. Вначале статьи приводится пример кода в котором нарушается принцип разделения ответственности (Separation of concerns) и который написан без оглядки на Unit-тестирование. Затем приводится реализация кода с использованием принципа обращения зависимостей (Inversion of Control), а точнее с помощью Constuctor [Dependency] Injection. Вторая версия удобна с точки зрения тестирования, но не удобна в реальном использовании, так как клиент будет знать сразу о нескольких реальных типах. И заключительной части показывается использование IoC/DI контейнера, точнее его базовой части в виде Castle.MicroKernel API, а затем и в расширенной - Castle.Windsor.
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart2.aspx
Во второй части рассматриваются инъекция опциональных зависимостей (Property Injection), приводится пример инъекции конкретной реализации (имеет смысл, когда на один и тот же интерфейс может быть несколько реализаций). В конце статьи приводятся примеры декларативного Xml конфигурирования основных коллекций - Array, IList, IDictionary.
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart3.aspx
В третьей части показывается пример вынесения части конфигурации в отдельные разделы Xml конфигурации Castle.Windsor и включение этих параметров при декларировании сервисов. По простым примерам видно, насколько просто и одновременно мощно можно конфигурировать сервисы Castle.Windsor с помощью конфигурационного файла. Если нужно задать значение параметра, который имеет сложный пользовательский тип, то это можно сделать с помощью TypeConverter'а. Приводится, не совсем полезный пример реализации декоратора и его регистрации. Возможно это сделано для того чтобы потом можно было привести пример с define и if/else прямо внутри конфигурационного файла.
Всех описанных возможностей конфигруации хватит за глаза любому, даже самому энтерпрайзному приложению :)
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart4.aspx
В четвертой части описывается крайне важный материал - управление жизненным циклом сервисов внутри Castle.Windsor контейнера.
Любому, кто собирается работать с Caslte.Windsor стоит обязательно разобраться в том, что такое Lifestyle, Lifecycle, Commision/Decomission и Release Policy. Чтобы не было неожиданно неприятных ситуаций как со мной и Web-приложением на production сервере :)
Информация по Facility довольно полезна, но не так критична.
Building the Policy Injection in 40 Minutes with Windsor
http://ayende.com/Blog/archive/2007/03/07/Building-the-Policy-Injection-in-40-Minutes-with-Windsor.aspx
Реализация Policy Injection в виде Facility для Castle.Windsor. Типичный пример аспект-ориентированного программирования. Не знаю кто придумал термин Policy Injection, и что конкретно он обозначает, но когда мне говорят реализация аспекта (AOP), то я сразу понимаю о чем идет речь.
Caching with Castle Windsor
http://consultingblogs.emc.com/owainwragg/archive/2008/10/31/caching-with-castle-windsor.aspx
Реализация Facility, которая обеспечивает кеширование данных используя аспект-ориентированный подход. Очевидно, что с помощью IoC и AOP-подхода можно достаточно удобно решать такие вещи как Security, Logging, Caching.
The joys of Castle.Services.Transaction
http://www.jroller.com/hammett/entry/the_joys_of_castle_services
Описывается использование AutomaticTransactionFacility. Просто апофеоз декларативной attribute-driven разработки. Выглядит настолько необычно что я даже не знаю, стоит ли пытаться повторить это дома :) В любом случае идея невероятно креативная.
Hidden jewels in the Castle stack: Transaction Services
http://blogs.taiga.nl/martijn/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services
Прошу меня простить, но эта ссылка уже реальный оффтопик основной темы. В посте развивается идея сервиса транзакций из проекта Castle, только теперь транзакционность пытаются прикрутить уже к файловой системе...
List of .NET Dependency Injection Containers (IOC)
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
Достаточно обширная подборка IoC контейнеров на платформе .NET от Scott Hanselman'а.
BitterCoder's Wiki. Container Tutorials
http://wiki.bittercoder.com/Default.aspx?Page=ContainerTutorials&AspxAutoDetectCookieSupport=1
Коллекция ссылок на туториалы по Castle.Windsor, в настоящее время представлено четырнадцать частей. Специфика этих туториалов заключается в том, что там в каждой части раскрывается только одна функциональная возможность библиотеки. Возможно для кого-то такой дробный формат изложения покажется удобным.
Внизу страницы приведена целая коллекция ссылок по рассматриваемой тематике на различные сторонние ресурсы.
Inject Some Life into Your Applications—Getting to Know the Unity Application Block
http://msdn.microsoft.com/en-us/library/cc816062.aspx
Вводная статья по Unity, IoC контейнеру, который разрабатывался силами Microsoft и затем был выпущен с открытым исходным кодом. Рассматриваются основные аспекты IoC контейнера. Все примеры кода приведены сразу на двух языках - C# и VB.NET.
IoC libraries compared
http://elegantcode.com/2009/01/07/ioc-libraries-compared/
Сравнение API у различных IoC контейнеров: Ninject, StructureMap, Unity, Spring.net, Castle.Windsor, Autofac. Следует принять во внимание что статья написана в январе 2009 года, а API каждого из перечисленный фреймверков постоянно совершенствуется.
Две простейшие реализации IoC контейнеров. По их реализации можно сделать вывод о том, какая основная задача ставится перед таким контейнером.
It's My Turn To Build An IoC Container In 15 Minutes and 33 Lines
http://www.kenegozi.com/Blog/2008/01/17/its-my-turn-to-build-an-ioc-container-in-15-minutes-and-33-lines.aspx
Building an IoC container in 15 lines of code
http://ayende.com/Blog/archive/2007/10/20/Building-an-IoC-container-in-15-lines-of-code.aspx
http://msdn.microsoft.com/en-us/library/aa973811.aspx
Ознакомительная статья, раскрывающая основные концепции Inversion of Control и Dependency Injection, которую написал Oren Eini aka Ayende Rahien. Носит предельно практических характер. Достаточно много хорошего материала, все изложение идет в ключе разработки некоего приложения (или сервиса) по обработке заказов. Крайне рекомендую эту статью к прочтению.
Inversion of Control and Dependency Injection with Castle Windsor Container. Four Parts.
Цикл статей об использовании Inversion of Control и Dependency Injection с помощью популярного фреймверка Castle.Windsor.
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart1.aspx
Первая статья является вводной. Вначале статьи приводится пример кода в котором нарушается принцип разделения ответственности (Separation of concerns) и который написан без оглядки на Unit-тестирование. Затем приводится реализация кода с использованием принципа обращения зависимостей (Inversion of Control), а точнее с помощью Constuctor [Dependency] Injection. Вторая версия удобна с точки зрения тестирования, но не удобна в реальном использовании, так как клиент будет знать сразу о нескольких реальных типах. И заключительной части показывается использование IoC/DI контейнера, точнее его базовой части в виде Castle.MicroKernel API, а затем и в расширенной - Castle.Windsor.
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart2.aspx
Во второй части рассматриваются инъекция опциональных зависимостей (Property Injection), приводится пример инъекции конкретной реализации (имеет смысл, когда на один и тот же интерфейс может быть несколько реализаций). В конце статьи приводятся примеры декларативного Xml конфигурирования основных коллекций - Array, IList
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart3.aspx
В третьей части показывается пример вынесения части конфигурации в отдельные разделы Xml конфигурации Castle.Windsor и включение этих параметров при декларировании сервисов. По простым примерам видно, насколько просто и одновременно мощно можно конфигурировать сервисы Castle.Windsor с помощью конфигурационного файла. Если нужно задать значение параметра, который имеет сложный пользовательский тип, то это можно сделать с помощью TypeConverter'а. Приводится, не совсем полезный пример реализации декоратора и его регистрации. Возможно это сделано для того чтобы потом можно было привести пример с define и if/else прямо внутри конфигурационного файла.
Всех описанных возможностей конфигруации хватит за глаза любому, даже самому энтерпрайзному приложению :)
http://dotnetslackers.com/articles/designpatterns/InversionOfControlAndDependencyInjectionWithCastleWindsorContainerPart4.aspx
В четвертой части описывается крайне важный материал - управление жизненным циклом сервисов внутри Castle.Windsor контейнера.
Любому, кто собирается работать с Caslte.Windsor стоит обязательно разобраться в том, что такое Lifestyle, Lifecycle, Commision/Decomission и Release Policy. Чтобы не было неожиданно неприятных ситуаций как со мной и Web-приложением на production сервере :)
Информация по Facility довольно полезна, но не так критична.
Building the Policy Injection in 40 Minutes with Windsor
http://ayende.com/Blog/archive/2007/03/07/Building-the-Policy-Injection-in-40-Minutes-with-Windsor.aspx
Реализация Policy Injection в виде Facility для Castle.Windsor. Типичный пример аспект-ориентированного программирования. Не знаю кто придумал термин Policy Injection, и что конкретно он обозначает, но когда мне говорят реализация аспекта (AOP), то я сразу понимаю о чем идет речь.
Caching with Castle Windsor
http://consultingblogs.emc.com/owainwragg/archive/2008/10/31/caching-with-castle-windsor.aspx
Реализация Facility, которая обеспечивает кеширование данных используя аспект-ориентированный подход. Очевидно, что с помощью IoC и AOP-подхода можно достаточно удобно решать такие вещи как Security, Logging, Caching.
The joys of Castle.Services.Transaction
http://www.jroller.com/hammett/entry/the_joys_of_castle_services
Описывается использование AutomaticTransactionFacility. Просто апофеоз декларативной attribute-driven разработки. Выглядит настолько необычно что я даже не знаю, стоит ли пытаться повторить это дома :) В любом случае идея невероятно креативная.
Hidden jewels in the Castle stack: Transaction Services
http://blogs.taiga.nl/martijn/2008/12/03/hidden-jewels-in-the-castle-stack-transaction-services
Прошу меня простить, но эта ссылка уже реальный оффтопик основной темы. В посте развивается идея сервиса транзакций из проекта Castle, только теперь транзакционность пытаются прикрутить уже к файловой системе...
List of .NET Dependency Injection Containers (IOC)
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
Достаточно обширная подборка IoC контейнеров на платформе .NET от Scott Hanselman'а.
BitterCoder's Wiki. Container Tutorials
http://wiki.bittercoder.com/Default.aspx?Page=ContainerTutorials&AspxAutoDetectCookieSupport=1
Коллекция ссылок на туториалы по Castle.Windsor, в настоящее время представлено четырнадцать частей. Специфика этих туториалов заключается в том, что там в каждой части раскрывается только одна функциональная возможность библиотеки. Возможно для кого-то такой дробный формат изложения покажется удобным.
Внизу страницы приведена целая коллекция ссылок по рассматриваемой тематике на различные сторонние ресурсы.
Inject Some Life into Your Applications—Getting to Know the Unity Application Block
http://msdn.microsoft.com/en-us/library/cc816062.aspx
Вводная статья по Unity, IoC контейнеру, который разрабатывался силами Microsoft и затем был выпущен с открытым исходным кодом. Рассматриваются основные аспекты IoC контейнера. Все примеры кода приведены сразу на двух языках - C# и VB.NET.
IoC libraries compared
http://elegantcode.com/2009/01/07/ioc-libraries-compared/
Сравнение API у различных IoC контейнеров: Ninject, StructureMap, Unity, Spring.net, Castle.Windsor, Autofac. Следует принять во внимание что статья написана в январе 2009 года, а API каждого из перечисленный фреймверков постоянно совершенствуется.
Две простейшие реализации IoC контейнеров. По их реализации можно сделать вывод о том, какая основная задача ставится перед таким контейнером.
It's My Turn To Build An IoC Container In 15 Minutes and 33 Lines
http://www.kenegozi.com/Blog/2008/01/17/its-my-turn-to-build-an-ioc-container-in-15-minutes-and-33-lines.aspx
Building an IoC container in 15 lines of code
http://ayende.com/Blog/archive/2007/10/20/Building-an-IoC-container-in-15-lines-of-code.aspx
четверг, 11 марта 2010 г.
WatiN и ASP.NET integration tests
Не так давно пробовал библиотеку WatiN в работе, впечатления очень положительные.
На мой взгляд эту библиотеку очень выгодно отличает ее API. Он очень domain specific и его удобно использовать и читать.
Так же очень логично использовать так называемый "Page-based API", когда каждая страница в сценарии инкапсулирована в отдельный класс, унаследованный от класса WatiN.Core.Page. В этом классе описывается мэппинг контролов страницы на определенные свойста класса с помощью атрибутов, а так же реализуется логика взаимодействия со страницей в методах класса.
Реализованные классы страниц могут быть повторно использованы во множестве тестов с разными входными данными и с разными наборами страниц.
Таким образом, при чтении теста тестировщик или разработчик концентрируется не на полях ввода и кнопках, а на бизнес-логике и логике взаимодействия с веб приложением.
Классический API можно увидеть на главной странице сайта WatiN, я же приведу пример "Page-based API":
Надеюсь что весь приведенный код не нуждается в комментариях. Если вы его сразу же поняли, значит этот API можно считать действительно удачным.
Пример реального кода на WatiN:
В коде выше описан верхний уровень сценария взаимодействия с сайтом FedEx. Глядя на код можно получить четкое представление о том, что нужно сделать пользователю для того чтобы скачать некий репорт с сайта. При этом все ньюансы разметки страницы и ввода данных сгруппированы и изолированы :)
WatiN даже умеет взаимодействовать со скрытым окном браузера, что позволяет запускать integration тесты на локальной машине прямо во время работы.
Стоит отметить, что в работе со скрытым окном браузера есть несколько ньюансов:
1. Если понадобится сделать скриншот страницы, то окно браузера необходимо сделать видимым, но не активным, иначе вместо скриншота у нас будет снимок черного экрана. Окно можно делать не активным, чтобы оно не мешало работе. После снятия скриншота окно можно будет сразу же спрятать:
2. Обработка диалоговых окон часто завершается неудачей без видимых на то причин. К сожалению у меня не было достаточно времени чтобы четко вычислить закономерность поведения, поэтому я проблему решил приведением окна браузера в видимый + активный режим. Понятно что побочным эффектом будет периодические появления диалоговых окон в самый неудачный для вас момент, но как правило таких ситуаций не так уж и много. Буду очень признателен, если кто-нибудь подскажет решение данной проблемы.
3. На моем копьютере WatiN отказывается работать в режиме Windows Service без доступа к рабочему столу, несмотря на то что на официальном сайте утверждается обратное.
...случайно заметил что в IE8 все вставки кода выглядят просто ужасно. Что интересно, FF и iPhone показывают правильно.
На мой взгляд эту библиотеку очень выгодно отличает ее API. Он очень domain specific и его удобно использовать и читать.
Так же очень логично использовать так называемый "Page-based API", когда каждая страница в сценарии инкапсулирована в отдельный класс, унаследованный от класса WatiN.Core.Page. В этом классе описывается мэппинг контролов страницы на определенные свойста класса с помощью атрибутов, а так же реализуется логика взаимодействия со страницей в методах класса.
Реализованные классы страниц могут быть повторно использованы во множестве тестов с разными входными данными и с разными наборами страниц.
Таким образом, при чтении теста тестировщик или разработчик концентрируется не на полях ввода и кнопках, а на бизнес-логике и логике взаимодействия с веб приложением.
Классический API можно увидеть на главной странице сайта WatiN, я же приведу пример "Page-based API":
using (var ie = new IE("http://www.google.com"))
{
var page = ie.Page<GoogleSearchPage>();
page.SearchFor("WatiN");
}
...
[Page(UrlRegex="www.google.*")]
public class GoogleSearchPage : Page
{
[FindBy(Name="btnG")]
public Button SearchButton;
[FindBy(Name="q")]
public TextField SearchCriteria;
public void SearchFor(string searchCriteria)
{
this.SearchCriteria.TypeText(searchCriteria);
this.SearchButton.Click();
}
}
Надеюсь что весь приведенный код не нуждается в комментариях. Если вы его сразу же поняли, значит этот API можно считать действительно удачным.
Пример реального кода на WatiN:
browser = new IE(fedExHomePageUrl);
browser.Page<FedExLoginPage>().LogIn(login, password);
browser.GoTo(fedExSearchPageUrl);
browser.Page<FedExSearchPage>().Search(dateFrom, dateTo);
browser.Page<FedExSearchResultPage>().SaveAs(reportPath);
browser.Page<FedExDownloadPage>().Download(browser, reportPath);
...
В коде выше описан верхний уровень сценария взаимодействия с сайтом FedEx. Глядя на код можно получить четкое представление о том, что нужно сделать пользователю для того чтобы скачать некий репорт с сайта. При этом все ньюансы разметки страницы и ввода данных сгруппированы и изолированы :)
WatiN даже умеет взаимодействовать со скрытым окном браузера, что позволяет запускать integration тесты на локальной машине прямо во время работы.
Стоит отметить, что в работе со скрытым окном браузера есть несколько ньюансов:
1. Если понадобится сделать скриншот страницы, то окно браузера необходимо сделать видимым, но не активным, иначе вместо скриншота у нас будет снимок черного экрана. Окно можно делать не активным, чтобы оно не мешало работе. После снятия скриншота окно можно будет сразу же спрятать:
browser.ShowWindow(NativeMethods.WindowShowStyle.ShowNormalNoActivate);
browser.CaptureWebPageToFile(debugImagePath);
browser.ShowWindow(NativeMethods.WindowShowStyle.Hide);
2. Обработка диалоговых окон часто завершается неудачей без видимых на то причин. К сожалению у меня не было достаточно времени чтобы четко вычислить закономерность поведения, поэтому я проблему решил приведением окна браузера в видимый + активный режим. Понятно что побочным эффектом будет периодические появления диалоговых окон в самый неудачный для вас момент, но как правило таких ситуаций не так уж и много. Буду очень признателен, если кто-нибудь подскажет решение данной проблемы.
3. На моем копьютере WatiN отказывается работать в режиме Windows Service без доступа к рабочему столу, несмотря на то что на официальном сайте утверждается обратное.
...случайно заметил что в IE8 все вставки кода выглядят просто ужасно. Что интересно, FF и iPhone показывают правильно.
Подписаться на:
Сообщения (Atom)