Object Explorer в MS SQL Server, как он должен быть
Давно собирался написать эту статью, о том каким должен быть Object Explorer в SQL Server.
В движок системы добавляются все новые и новые фишки, улучшается поддержка администрирования, скорость работы и так далее. Даже появляются сниппеты кода, а так же автодополнение в базовой версии, казалось бы, чего волноваться? Однако при постоянной работе с SQL Server, и когда хоткеи ReSharper’a уже хочется привнести в каждую программу, замечаешь насколько неудобная работа с объектами базы.
Все хорошо и красиво, когда в базе находится наверно не более 20 таблиц, которые можно объять одним взглядом, однако если таблиц от 50 и больше, а так же требуется работать с несколькими окружениями – работа превращается в ад. Очень легко выполнить не тот код, работая не с тем соединением. Да и просто поиск таблиц вызывает затруднения, так как обычно помнишь примерное название, а не дословное. Впрочем подобная проблема касается любых объектов в SQL Server.
Например глядя на такую картину, что вы можете сказать?
Что это за база? Какой это сервер? Сколько тут еще таблиц?
Поведение при подписке на события
Представьте себе такую, на мой взгляд, важную проблема, которая может приводить к недопониманию работы с системой.
Для иллюстрации рассмотрим следующий пример. Пусть у нас есть некоторое приложение со списком опций и общей картинкой. Т.е. приложение выглядит примерно следующим образом:
Логика работы приложения выглядит следующим образом. При выборе элемента из списка картинка предпросмотра обновляется на произвольную из выбранного альбома. Согласитесь, что все очень просто, так?
Так как это специализированное приложение, то пусть управление будет только с клавиатуры и нам надо самостоятельно обрабатывать нажатия на клавиши. Что логично, так как при выборе нового элемента нам надо получить список картинок из альбома и показать произвольную из них в соответствующем компоненте.
Код в реальности выглядит вот так. Т.е. это то, как вы его напишите с первого раза. Собственно я написал так же.
protected override void OnActivated(object navigationParameter) {
listBox.ArrowNavigationCommandReceived += NavigationCommandRecieved;
}
private void NavigationCommandRecieved(object sender, ArrowNavigationCommandEventArgs e) {
if (e.Key == ArrowNavigationCommandKey.Down) {
// обработка нажатия и выбор картинки
}
}
Не будем пока акцентировать внимание на разные аспекты окружения. Я думаю, что представленный код в целом понятен.
Итак, что вы ожидаете от такого кода? Посмотрите внимательно на названия методов, событий – решите для себя, что вы ожидаете.
Я думаю, что большинство из вас подумало, что выберется следующий элемент из списка и покажется картинка из выбранного элемента, так?
Вполне ожидаемое поведение, но вы окажетесь не правы в своих суждениях и отработается только отображение картинки, а передвижение на новый пункт меню не произойдет. Почему? Потому что подписавшись на событие, вы, по мнению движка, полностью взяли на себя управление.
Это очень странно на первый взгляд, так как я подписываюсь на событие и ожидаю, что его получат все заинтересованные компоненты, и обработка не прервется на самом интересном месте. Для того, чтобы сработало передвижение на новый элемент из listBox, необходимо дописать IsHandled = false:
protected override void OnActivated(object navigationParameter) {
listBox.ArrowNavigationCommandReceived += NavigationCommandRecieved;
}
private void NavigationCommandRecieved(object sender, ArrowNavigationCommandEventArgs e) {
if (e.Key == ArrowNavigationCommandKey.Down) {
// обработка нажатия и выбор картинки
}
e.IsHandled = false;
}
С другой стороны, если совсем внимательно и формально отнестись к названию события, то получаем что «команда получена, а дальше вы сами разбирайтесь как с ней поступать». Но тогда странно, что это событие.
На мой взгляд надо сделать два события:
- ArrowNavigationCommandReceived – нет возможность использовать IsHandled для прерывания цепочки обработки.
- ArrowNavigationCommandReceiving – есть возможность использовать IsHandled.
Ближайшая аналогия прослеживается с событиями Closed и Closing для окон (WinForm, WPF).
Что вы думаете по этому поводу? Комментарии как всегда приветствуются.
UPD: голосование пока что запилить не могу.
Hard'n'Heavy!
PostSharp v3
За прошедшее время я написал много статей о том, как удобен в использовании PostSharp и сколько полезных вещей можно сделать с помощью него. Несмотря на то, что многие возможности пропагандировались неизменными и был открытый исходный код для различных дополнений, к сожалению все меняется.
С выходом бета-версии и RC, вторая версия библиотеки все более искореняется из документации, к ней больше не выпускают community ключей, а так же постепенно обрубаются возможности работы с дополнительными тулкитами.
Начиная с третьей версии, существует 3 набора подписок: community, professional и ultimate. Самая продвинутая стоит сейчас со всеми скидками, с учетом RC версии и раннего заказа 800$. При этом ранее бесплатные тулкиты по INPC и управлению потоками перешли в Ultimate версию, а даже не в Professional. Ранее полная версия стоила 150-200$, что было в целом более-менее адекватно с учетом предоставляемых возможностей. Но сейчас цена, на мой взгляд несколько неадекватна тому, что предлагается за нее.
В простой версии остались лишь совсем простые вещи, которые годятся чуть ли не только для учебных примеров. Хотя ладно, можно сделать много полезного с их помощью, но различные другие инструменты, которые предоставляют возможности по перестройке кода в момент конвертации IL, не дружат между собой или же подружить их очень сложно, так как они на одном и том же этапе вмешиваются в код.
С выходом Roslyn многие вещи из Ultimate пакета стали доступны бесплатно, разве что стоит приложить чуть больше усилий для их реализации. Но написав однажды несколько методов помощников, можно многие вещи делать быстро, так что опять же цена и включение возможностей многих только в Ulitmate версию сомнительны весьма.
Далее, есть проблемы при использовании PostSharp и MEF, которые пока что никак не решаются в RC версии и не думаю, что они будут разрешены позднее. MEF не может в своем контексте загрузить сборки PostSharp и аспекты не распознаются.
Честно сказать, не знаю как дальше советовать использовать PostSharp, разве только для некоторых простых задач вроде комплексного и очень подробного логирования по вызовам методов и некоторые простые ситуации. По идее должно отрабатывать слежение за изменением свойств в классе, так как в Community версии еще не отключили внедрение\реализацию интерфейсов с помощью аспектов.
Professional версия, которая включает все аспекты и подходит для существующих платформ требует от вас раскошелится на 500$, что тоже не вот какая маленькая стоимость, честно сказать. Я наверно мог бы заплатить 200$ за полную версию, но…
Еще меня поразило, что удалили или же закрыли от публики форум! Т.е. теперь нельзя свободно задать вопросы и найти ответы от других пользователей.
В общем развитие PostSharp меня несколько разочаровало. Очень печально, что столь многообещающий и интересный продукт пошел по такому пути.
Культ Карго
Огромное количество статей, выступлений, слайдов уже есть о культе Карго, однако я не думал, что это окажется актуально для предыдущего места работы.
Культ карго или карго-культ (англ. cargo cult — поклонение грузу), также религия самолётопоклонников или культ Даров небесных — термин, которым называют группу религиозных движений в Меланезии. В культах карго верят, что западные товары (карго, англ. груз) созданы духами предков и предназначены для меланезийского народа. Считается, что белые люди нечестным путём получили контроль над этими предметами. В культах карго проводятся ритуалы, похожие на действия белых людей, чтобы этих предметов стало больше. Культ карго является проявлением «магического мышления».
Можно с легкостью это переложить на сферу ИТ, когда команды просто повторяют разные внешние проявления той или иной практики не задумываясь, что должно являться результатом. Что-то резко вспомнились огромные фанерные «антикрылья» на копейках и 4 трубы – это тоже яркий пример культа карго.
Не затрагивая какие-то отдаленные примеры, хочу рассказать, как это происходит на предыдущей работе и как это можно поправить или на что обратить внимание. Честно сказать все не так плохо и постепенно процесс эволюционирует, если направлять его в нужное русло. Т.е. получается некоторый круговорот: полезная нагрузка – профит – узнали новую идею – карго – полезная нагрузка - профит
Работа блога
Всем привет, сегодня хочу немного поговорить о том, как и почему я сделал блог, что из этого получается, и как это, возможно, может вам помочь. Опосредованно конечно.
Давным давно, в одной далекой далекой галактике… На самом деле, кажется что это было очень давно, а на деле не то что бы очень. Почти 3,5 года назад я задумался о том, кем я хочу быть в дальнейшем, что именно из мира программирования мне ближе всего. На тот момент мне хотелось очень круто программировать и рассказывать об этом. Я не думал, что я уйду от активного программирования, от постоянного изучения технологий. На тот момент я подумал, что надо сделать так, чтобы люди тебя знали и сами приглашали на работу, а не самому искать работу и доказывать, что ты что-то знаешь и будешь ценным приобретением для компании. Полностью в соответствии с принципом: сначала ты работаешь на имя, потом имя работает на тебя.
Я отлично помню момент окончательного принятия решения, когда я решил, что больше тянуть нельзя и надо срочно покупать хостинг и делать блог. Окончательное решение пришло прямо перед тем как я уснул, однако как вы видите это тот случай, когда ты выполняешь данные себе обещания. На следующий же день, не сильно изучая рынок провайдеров, я остановился на мастерхосте и купил простейший хостинг и домен. Честно сказать не помню в какой момент я определился с названием, но на момент покупки хостинга имя уже было. Примерно 2-3 дня ушло на все оформление хостинга, разобраться с тем, как установить вордпресс и написать первое приветствие.
Очень, очень сложно было определиться с тем, что же писать. Мне казалось, что я знаю настолько банальные и общие вещи о которых совершенно не стоит писать. Казалось, что все это знают и будет глупо писать на такие темы. Но я себя пересилил и написал посты на основные, ключевые темы, которые я узнал за последние полгода или чуть меньше. В целом, получилось, на мой взгляд, хорошо, я втянулся и уже не мог закинуть такое дело. Тем более я понимал, что блог не даст быстрых результатов, надо постоянно и много работать, чтобы в итоге это сработало. Я размещал ссылки на статьи и статьи на всех ресурсах до которых мог только дотянуться, где могло быть хоть какое-нибудь коммьюнити программистов, и где размещают статьи. Кроме статей полезно делать видео-уроки, так как не все можно показать в статике. Мне кажется видео в итоге сыграло тоже не малую роль.
Интервью
На днях давал интервью для Люксофт, думаю, что читателям блога это будет тоже интересно =)
Как давно Вы работаете в Luxoft?
Официально в Люксофт я работаю с середины февраля 2013. До этого меня пригласили побеседовать по поводу вакансии архитектора, на каждом этапе я не терялся и активно рассказывал о блоге своем, о желании нести доброе вечное светлое, наносить непоправимое добро в массы. Особенно сильно я замучал Андрея Стукаленко, который и предложил мне попробовать себя в качестве тренера в центре обучения Люксофт. А вакансию архитектора на которую я претендовал просто сняли потом.
Расскажите о Вашем профессиональном опыте.
Профессиональный опыт достаточно большой. Самый полезный опыт и лучшее место работы до этого было в компании Intel. Там меня действительно научили программировать, основным практикам и идеям разработки, я увидел как работает распределенная международная команда программистов и аналитиков. Как строятся процессы разработки. В общем получил огромный стимул для развития, который в себе поддерживаю до сих пор. Первым местом работы, по окончании третьего курса, была небольшая компания, в которой я занимался системами отчета и разбирался с реляционными базами данных. Я рад, что все же пошел сначала в небольшую компанию, где мне не поломали мозг и «стиль программирования», а не в локальные программистко-образующие предприятия Нижнего Новгорода, которые специализируются на найме студентов. Многие мои сокурсники разочаровывались в выборе профессии по итогам работы в этих предприятиях. На первой работе я так же получил начальные знания по .Net платформе и о том, как не надо работать с людьми на примере начальника =). Совсем начальные знания .net однако же позволили мне перейти на завод, где я уже постигал азы работы с OLAP кубами, базами и продолжал изучать .Net. На заводе я долго не проработал, увидев объявление о найме сотрудников в Intel. После Intel были разные компании, в которых зрелость процессов была различна и опыт самих разработчиков, но все они дали мне широкий кругозор проблем разработки, предметных областей. Текущим местом работы является инвестиционная компания Лидер, в которой я выполняю роль архитектора и технического лидера.
Помимо основных работ так же занимался фрилансом, который тоже немало дал в плане работы с людьми и позволил заниматься разными проектами, часто очень далекими от того, чем я занимаюсь на основных работах.
Какое у Вас образование?
Я учился в нижегородском государственном университете имени Лобачевского на факультете Вычислительной математики и кибернетики. До сих пор не знаю каким чудом удалось мне успешно закончить университет =) Изначально меня соблазнило название специальности «Системный программист», однако только на 4м курсе выяснилось, что это не имеет никакого отношения к операционным системам, а это системы уравнений с обратной связью, регулируя которую можно влиять на систему – вот и получается системный программист. Однако программирование меня захватило еще до универа, так что в университете в плане программирования я занимался в основном самообразованием.
Почему Вы выбрали именно IT?
Сложно сказать. С компьютером я знаком давно, а вот программирование как предмет в школе появился только с середины 10 класса, и как-то сразу меня увлекли логика и возможности программирования. Потом наверно особенно вопрос не стоял куда идти учиться дальше, особенно с учетом специальности на ВМК «Системный программист» =) Тогда еще не было какой-то большой моды на программистов кажется и конкурс на факультет был не велик. Я до сих пор очень рад, что работаю в IT, мне нравится программировать, узнавать кучу новых вещей и рассказывать их другим.
Чем именно Вы занимаетесь в Luxoft?
Так как я работаю по совместительству, то в Luxoft я занимаюсь только тем, что связано с образовательным центром, т.е. читаю и разрабатываю курсы касающиеся архитектуры и платформы .Net. В дальнейшем думаю расширить деятельность в компании, но все переговоры только начинаются.
Почему Вы окончательно сделали выбор в пользу преподавания? Что вы могли бы дать своим коллегам и ученикам как тренер?
Преподавание очень интересный и увлекательный процесс, который так же позволяет кристаллизовать собственные знания, а так же узнать потребности людей. Ведение блога в некотором роде тоже является преподаванием, попытка донести до людей свои знания. Этим я занимаюсь уже три года с небольшим, пишу статьи, делаю видеоуроки. Преподавание так же является и хорошим промоушеном самого себя, своего имени. Я наверно слишком хорошо запомнил высказывание про то, что сначала ты работаешь на имя, потом оно на тебя.
Как тренер я могу поделиться богатым опытом полученным на многих проектах, так же я надеюсь на то, что опыт написания статей и презентаций различных технологий коллегам поможет мне интересно рассказывать тренинги.
Какие курсы вы планируете разработать/вести в дальнейшем?
Сейчас я разрабатываю курс Event Driven Architecture. На данный курс идет спрос от внешних клиентов и учебный центр нуждается в этом курсе. Так же я немного перерабатываю почти все курсы которые читаю. Переработка может быть из-за разных причин, например может быть необходимо перевести примеры с Java на .Net, привести к общему корпоративному оформлению, иногда просто разработчики курсов пропускают некоторые темы важные и после дополнительного согласования я дописываю темы.
Часто тренинги лишены основной части, ради которых все и затевается – практики. А сделать интересную практическую часть – это не тривиальная задача, так что поле для деятельности большое.
Что бы Вы посоветовали коллегам, в каком направлении следует развиваться сегодня?
Очень сложный вопрос. Хотя я часто замечаю, что люди не знают инструментов с которыми они работают, так что могу посоветовать изучать матчасть – это один из ключевых моментов эффективной работы. Так же могу посоветовать постоянно стараться расширять свой кругозор, так как таким образом можно избежать необходимости изобретать велосипеды и пользоваться готовыми продуктами, что сильно облегчает жизнь. Не надо пытаться доказать всем вокруг насколько вы крутой разработчик делая все самостоятельно.
Так же хочу посоветовать постоянно экспериментировать с подходами в программировании дома или в свободное время на работе.
А какого-то одного конкретного направления посоветовать не могу, слишком много их.
Расскажите о том, какой Вы вне работы, какие у Вас увлечения и интересы, чем занимаетесь в свободное время?
Когда тебе платят деньги за твое хобби, сложно сказать какой я вне работы! Очень много дома занимаюсь программированием и изучением нового материала, хотя стараюсь соблюдать баланс между программированием и другими хобби. Я люблю сноуборд, летом прыгаю на велосипеде, катаюсь по лесопаркам. В межсезонье нравится собирать модели самолетов от объединения Звезда, играть на бас-гитаре. Очень люблю кинотеатры, смотрю почти все фильмы которые выходят, благо кинотеатр в 5 минутах от дома.
Когда почти все время работаешь головой, то в свободное время хочется заниматься чем-то таким, что отключает мозг и дает нагрузку телу, еще желательно чтобы и адреналин выделялся. Этим летом надо будет купить радиоуправляемые джипы и с подругой устраивать заезды по лесопарку ближайшему, думаю это должно быть весело!
Hard'n'Heavy!
Начинающие и опытные разработчики
Наверно про это уже много где написано, правда я не могу вспомнить и привести конкретные источники, но то что я читал про это – точно. Чем отличается опытный разработчик от начинающего? Философичный вопрос который может вызвать множество споров и комментариев, несогласных и согласных. Как-то так получилось, что наверно я на собственном примере и проектах увидел эту разницу и вспомнил что читал о ней, но не верил в нее по всей видимости.
Как вы думаете в чем же разница?
Логика на INotifyProperyChanged
Сложность 200-300
В основном я пишу о практических подходах, конкретных реализациях идей и достаточно редко об общей структуре приложений. Как они строятся, как лучше разрабатывать приложения, какие подходы лучше поддерживаются и так далее. Я думаю, что все согласятся, что нельзя написать единое руководство по тому как надо писать приложение. Если бы такое можно было написать, то такое руководство давно было бы написано людьми гораздо более умными и выдающимися, чем я на текущий момент =) Наверно, если бы такое руководство существовало, то наша профессия была бы не столь востребована и весь рынок разработки захватили китайцы и индусы, так как они более усидчивы и исполнительны. К счастью такого руководства пока что нет, да и вряд ли появится, так что смекалка и нестандартность подходов все еще играет на нашей стороне.
Так как идеальную архитектуру не описать, то попробую хотя бы рассказать как не стоит делать в большинстве ситуаций. Хотя, на мой взгляд, описанный ниже подход вообще нигде нельзя применять.
Я уже не раз писал и говорил насколько мне не нравится явная реализация INPC при реализации MVVM для WPF, но недавнее открытие в проекте коллег не смогло меня оставить равнодушным. Честно сказать, я не представлял, что таким образом можно построить логику приложения, но что есть, то есть. Итак, не будем более затягивать вступление и обратим взор на код.
Could not find required file ‘setup.bin’
Да, вот такое странное название для не менее странной проблемы, когда на «чистой» машине не собирается проект для публикации с помощью ClickOnce.
Совсем недавно, при разборе проблемы с применением PostSharp при сборке на билд-сервере, столкнулся с проблемой, что на чистой машине, где стоит только сам билд-сервер TFS, новый фреймворк с SDK не собирается проект. Полностью сообщение об ошибке выглядело следующим образом:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (4486): Could not find required file 'setup.bin'
После того, как первое недоумение прошло и раскопки файла .targets тоже ничего не дали, решено было обратиться к гуглу и он выдал удивительные вещи. Оказывается установленного ПО недостаточно для сборки ClickOnce.
Ручным решением проблемы может быть следующее:
1. Необходимо скопировать с машины разработчиков всю папку c:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A
2. Далее в регистре прописать\создать ключ HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\GenericBootstrapper\11.0 со значением C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\Bootstrapper\
После чего все заработает.
Очень странное поведение и решение для линейки последних продуктов Microsoft, но что поделать. В общем и целом я полностью поддерживаю практику того, что билд-сервер должен быть максимально чист от инструментов разработчика, но по всей видимости самым лучшим решением будет поставить на билд-сервер последнюю версию студии с которой вы работаете и не задумываться над описанной проблемой. Возможно может всплыть что-то еще, от того, что студия не установлена на билд-сервере.
Но по прежнему не стоит ставить на билд-сервер инструменты вроде DevExpress, Telerik и так далее, потому что только на машине пользователя вы обнаружите, что не хватает какой либо библиотеки для отображения супер-таблицы или иных красивостей.
Так что будьте прагматичны и руководствуйтесь логикой и ситуацией, а не просто выполняйте бездумно правила и рекомендации.
Hard’n’Heavy!
Версионность сериализованных данных
Сложность 100-200
Во время изучения событийных систем и CQRS, поднимается вопрос о том, что надо каким-то образом читать и преобразовывать старые данные (как правило сериализованные в xml или json) к текущему состоянию системы, которая скорее всего изменилась со времени запуска. На самом деле проблема восстановления данных, чаще всего каких-либо настроек, весьма остро порой встает перед разработчиками. Т.е. у нас есть некоторое приложение, которое было уже доставлено конечному пользователю, и нам надо изменить формат сохранения настроек, сообщений. Если смотреть на проблему очень поверхностно, то обычно читаются настройки в старом формате, руками преобразуются в новый формат и сохраняются уже в новом виде.
Это сработает относительно хорошо, когда пользователей мало или вы только применили такой прием. На этом этапе разработчики вполне могут быть полны надежд о том, что больше формат файла настроек или сообщений не поменяется. Как показывает практика все совсем не так и формат поменяется еще не один раз и у целом пользователи могут пользоваться самыми разными версиями программы и обновляться пропуская некоторые важные выпуски программы, но при этом сериализованные данные должны быть прочитаны и преобразованы с любой версии данных.
На написание статьи и кода меня сподвигло наличие свободного времени (в меньшей части) и тот ужас, что я увидел в проекте коллег (в большей части). Или, если выразиться политкорректно то, код был чрезмерно раздут для задачи использовался не оптимально. Я думаю, что лучше один раз увидеть, чем сто раз прочитать.
На примере ниже сохраняются и восстанавливаются настройки расположения клиентских настроек для MDI приложения. Именно от того, что надо работать с любой версией настроек и было применено ручное составление и разбор XML файла. В доказательство можно привести проверку на внутреннюю версию файла. Хотя… что-то я смотрю и вижу, что старые версии не восстанавливаются, йехъ.
Ну да ладно, не code review является целью, а то, как можно избавиться от такой большой писанины и сделать работу с версионными данными легче и прозрачнее.


