вторник, января 30, 2007

Тонкий IT-шный юмор

Настолько тонкий, что может служить тестом на принадлежность к касте компьютерщиков (geeks).
"A one-question geek test. If you get the joke, you're a geek: Seen on a California license plate on a VW Beetle: 'FEATURE'..."

Joshua D. Wachs, Natural Intelligence Inc.

Стащил у Михаила Елашкина.
Признаюсь честно, до меня дошло только со второго захода. :)

Дефект требований.

Дефект требований - это самый страшный дефект, который вообще может существовать в мире разработки софта. Дефект требований - это когда проектировщики все правильно спроектировали, программисты все правильно запрограммировали, тестировщики все правильно протестировали. А в результате заказчик говорит что все работает «не так». Такая ситуация уже сама по себе неприятна. А теперь добавьте к этому, что дефект требований вылазит во время эксплуатации, или, в крайнем случае, во время приемки заказчиком (customer acceptance tests). Как учили нас все классики, начиная с дедушки Брукса - это самое неподходящее время для появления дефектов, потому что цена их устранения в это время самая высокая. И вот вместо того, чтобы радостно делить премии и отправляться на очередной team building с пивом по поводу успешного завершения проекта, вы сидите в выходные дни, без оплаты и лихорадочно пытаетесь переделать половину системы не разрушив при этом другую половину.
Хорошо, если ваша команда работает по классической методе. В этом случае вы дружно идете мочить аналитика проекта. А если вы работаете по какому ни будь Agile (XP, Scrum, etc.)? Представитель заказчика - священная корова, его бить нельзя. Даже когда он говорит: «Извините ребята, я вчера поговорил с финансовым директором. Так вот, все эти юзерстори работают неправильно. Все надо переделать». Хоть бить этого парня и нельзя, но надо постараться от него избавиться. В том, что следующую итерацию вам придется переписывать старые юзерстори виноват именно он. А отвечать за это придется скорее всего вам.

понедельник, января 29, 2007

Прототипы

Когда я делаю систему на заказ, я люблю делать прототипы. Я люблю их делать потому, что прототипы любят мои заказчики. При помощи прототипа, за несколько дней возможно продвинуться на столько, что можно начинать рисовать HLD (high level design) и даже, писать код. Если все это делать без прототипа, просто ходить и беседовать с представителями заказчика, выуживая из них по капле противоречивые требования, большая часть которых являются чистой воды фантазиями, на это уйдет минимум месяц.
Я убежден, что прототип можно начинать делать после получаса беседы с парой ключевых пользователей будущей системы. Скорее всего, этот прототип вы переделаете на корню или выкинете, но свою роль он выполнит. Видели вы, как начинают сиять глаза представителя заказчика, когда он первый раз видит формочки и кнопочки будущей системы? Когда он слышит от вас «вы нажимаете эту кнопку, и система делает то и это…» - это музыка для него. Потому что до этого, «то и это» приходилось ему делать самому. Беседа сразу переходит в конструктивное русло, и вы очень быстро узнаете о будущей системе много таких вещей, о существовании которых до сих пор вы и не догадывались. Через пять минут вы уже понимаете, что у вас достаточно информации для того, чтобы идти и переделывать свой прототип.
Ваш прототип не должен делать ничего. Все что от него требуется, это достаточно правдоподобно представлять GUI системы. Если при этом, он еще позволит продемонстрировать последовательность действий (workflow) , полезность такого прототипа возрастает на порядок. Но не забудьте – в прототипе не должно быть никакого намека на выполняемую функциональность. Абсолютно! Иначе заказчик может решить, что система у вас уже готова, и вы пытаетесь морочить ему голову, изображая разработку все последующие месяцы.
И еще. Никогда не показывайте прототипы stakeholder-ам проекта (стэйкхолдеры – это боссы со стороны заказчика, в чьих руках финансирование вашего проекта). Обычно эти люди не являются пользователями разрабатываемой системы, но имеют свой взгляд на то, как она должна работать, и при этом у них достаточно власти, чтобы продавить свое мнение. В результате, вы можете получить в системе массу абсолютно бесполезных фич. И виноваты в этом будете вы. Поэтому сделайте так, чтобы стэйкхолдеру ваш прототип показали сами будущие пользователи системы. Они сделают вашему прототипу самый эффективный PR и заодно послужат надежным фильтром от буйства начальственной фантазии.

воскресенье, января 28, 2007

Проблемы с EventLog в ASPNET

Хорошая идея использовать Windows Event Log для логирования сообщений в своем ASPNET приложении. Пишем:


Sysyem.Diagnostics.EventLog.WriteEntry("MyApplication", "Something happened");


Однако в большинстве случаев эта строка вылетит с ошибкой


"Requested registry access is not allowed"


Происходит это потому, что ASPNET код обычно исполняется из под учетной записи с ограниченными правами (ASPNET на IIS 5.0 и Network Service на IIS 6.0), а при вызове EventLog.WriteEntry происходит обращение к реестру. В реестре перечислены все источники (csource) для Event Log (в нашем случае это строка "MyApplication"). У класса EventLog существует специальный метод для создания источника EventLog.CreateEventSourc. Однако в нашем случае он не поможет. Прав нет.
Соответствующий ключ реестра можно прописать ручками:


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyApplication


Программно, источники Event Log-а создаются при помощи специального класса инсталлятора System.Diagnostics.EventLogInstaller. Для этого надо создать отдельную сборку поместить в нее код инсталлера:


using System;
using System.Configuration.Install;
using System.Diagnostics;
using System.ComponentModel;

[RunInstaller(true)]
public class CustomEventLogInstaller: Installer
{
private EventLogInstaller customEventLogInstaller;
public CustomEventLogInstaller()
{
// создаем экземпляр EventLogInstaller
customEventLogInstaller = new EventLogInstaller();
// Устанавливаем свойство 'Source' (собственно ради чего весь сыр бор)
customEventLogInstaller.Source = "MyApplication";
// В какой лог писать (обычно Application)
customEventLogInstaller.Log = "Application";
// Добавляем myEventLogInstaller в коллекцию инсталлеров.
Installers.Add(customEventLogInstaller);
}
public static void Main()
{
}
}


Получившуюся сборку можно использовать двумя способами. Первый, скормить ее утилите installutil.exe


InstallUtil.exe <путь>\сборка_инсталлера.dll


Второй, эту сборку можно использовать в инсталяторе web приложения. Для этого ее надо включить в setup проект и назначить для всех четырех Custom Actions (Install, Commit, Rollback, Uninstall).
Да, и не забудьте настроить в свойствах Application Event Log - "Затирать по необходимости". Иначе очень скоро работа вашего приложения окажется парализована из-за постоянных ошибок о преполнении лога сообщений.

суббота, января 27, 2007

Just fun (в тему)

Цитаты:

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

Те части информационной системы до которых вы можете добраться с кувалдой называются "железом". Те части системы, которые можно только проклинать и материть, называются "софтом".
Неизвестный автор

И еще много забавных цитат собраных Михаилом Елашкиным

пятница, января 26, 2007

«Включаем – не работает», или как в последнюю минуту не завалить успешный проект.

Проект подходит к концу, приемочные тесты успешно пройдены, в проектной команде царит атмосфера всеобщей расслабухи. Знакомая картина? Даже на диаграмме распределения активностей по фазам RUP, заметно что кривые всех активностей сходят на нет. Приближается приятный момент дележа премии и пожинания лавров успеха в виде написания различных case study и success story.
Тот всплеск активности и суматошной мышиной возни, который очень часто возникает в данный период, не отмечен ни на одной из диаграмм классических процессов разработки, не учтен ни в одном их проектных планов. Тем не менее? встречается этот феномен чрезвычайно часто, связан он с развертыванием (deployment) готового продукта у заказчика и в краткой форме описывается известным афоризмом - «включаем – не работает!».
Разрабатывали мы как-то систему на заказ, с толстым клиентом. Разработали, протестировали, сделали для клиента инсталлятор, привезли заказчику развернули в АСУПе, показали. Заказчик доволен, систему приняли. За выходные АСУП установил клиента на рабочие места по всему предприятию. В подельник пользователи запускают нашего клиента и он не у кого не запускается. Сказать, что был скандал - это ничего не сказать. Заказчик в ярости. Разработчики в дауне. Оказалось, программа при открытии писала в файл в своем рабочем каталоге дату и время своего запуска. На рабочих местах у пользователей не было прав на запись в этот каталог (Program Files). До этого, и у разработчиков, и у тестировщиков, и в АСУПе заказчика программа работала нормально только потому, что все они имели права локального администратора на своих машинах. Все, как один.
Про такие случаи я могу рассказывать долго. Что же делать, для того чтобы их избежать? Самый простой совет – читайте книжки по процессам разработки. В любой книге и любой методологии разработки, вопросам деплоймента уделяется достаточно внимания.
Несколько советов:
  • Изучайте рабочую среду (environment), в которой предстоит работать приложению. Начинайте это делать еще до написания первой строчки кода. Начинайте это делать еще до разработки архитектуры приложения. Это важнейший источник не функциональных (системных) требований к приложению. Требования, источником которых является еnvironment, могут перевернуть всю вашу архитектуру с ног на голову. Не верите? Вам нужен пример? Пожалуйста: сервер приложений и сервер БД должны размещаться в разных доменах с разным уровнем безопасности, причем исходящие запросы из домена сервера приложений в домен сервера БД запрещены. Ну как? Не говорите, пожалуйста, что пример идиотский, я это сам знаю. Но он взят из реальной жизни.

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

  • Тестируйте приложение в environment максимально приближенном к боевому. Настройте тестовую среду в соответствии с требованиями к развертыванию приложения у заказчика. Потратьте на это время и ресурсы, если не хотите повторить аттракцион, о котором я писал выше.
    Создайте и опишите процедуру развертывания (deployment) приложения. Особенно это актуально для тиражируемых решений. Проведите специальное тестирование процедуры развертывания на всех типах environment. (Был неописуемый случай: тестировали большую серверную систему для развертывания под Win2K и под Win2003. А когда приехали к заказчику - оказалось - у него кластер на четыре машины и соответствующая версия OS. Ничего установить не удалось.)

  • Планируйте затраты на все эти активности в самом начале проекта. Тот, кто создавал Installation Package в VisualStudio знает что это не шутки, и времени на это уходит всегда больше, чем рассчитывали.

понедельник, января 22, 2007

Hewlett-Packard открывает R&D центр в Питере

В продолжение предыдущего поста. Hewlett-Packard открывает центр разработок в Санкт-Петербурге. Официальное открытие должно состояться сегодня - 22 января. В течении первого года планируется набрать около 40 разработчиков. Центр будет заниматься исследованиями и разработками в области Business Intelligence (BI), Data Mining и Utility Computing.
Помимо Санкт-Петербурга HP уже имеет центры разработки в Пало-Альто, Бристоле, Хайфе, Токио, Пекине и Бангалоре.
Может кто то скжет, что это не аутсорсинг вовсе, но с точки зрения HP это самый настоящий аутсорсинг разработки в Россию. А для нас важно, что светлые мозги теперь будут концентрироваться не только в Пало-Альто и Бангалоре, но и в Питере.

воскресенье, января 21, 2007

Outsourcing. Взгляд с другой стороны.

Офшор скорее жив чем мертв, нравится это кому то или нет. На Cnet опубликованы некоторые результаты интересного опроса на данную тему. В данном опросе участвовали в основном софтверные компании, члены Software & Information Industry Association (SIIA).Аутсорсинг от таких компаний это лакомый кусок для любого поставщика IT услуг. 60% опрошенных компаний используют офшор. 57% из них предполагают увеличение объема офшорных операций. 65% компаний размещают свои операции в Индии, 29% в восточной Европе и России, 21% в Китае. То, что среди ведущих американских софтверных компаний, каждая третья имеет операции в России, конечно радует, хотя надо понимать, что в денежном выражении наша доля рынка будет выглядеть не столь радужно.
По оценкам, Восточную Европу и Россию ожидает настоящий бум офшора. До 2008 года здесь ожидается троекратный рост в результате которого будет создано до 130 000 новых рабочих мест. Сколько из них достанется России? Перспективы хорошие, но за них придется побороться. Очень показателен в этом плане комментарий к статье:
«I will take my 20 years experience & walk away from the industry & see if spotty face youths called Sergei & Venkatesh take my place (invidually - not together).
Good luck to them. And good luck to everyone using their software. But don't complain to me if the service deteriorates, if the call center can't understand your accent, if you can't get the problem fixed for a week, if your software solutions aren't flexible, scalable & extensible».

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

Бои без правил при приеме на работу.

Систематически на программистских форумах разгораются жаркие дискуссии на темы связанные с собеседованиями при приеме на работу, или техническими интервью. По накалу страстей с ними могут соперничать, пожалуй, только холивары C++ vs. Delphi или Windows vs. Linux.
Имея достаточно большой опыт прохождения подобных интервью, намного больший - проведения оных, а также, систематически наблюдая за дискуссиями на форумах, могу сказать - положение в этой области у нас удручающее.
Техническое интервью штука сложная, и для вопрошающего и для вопрошаемого. Кандидаты бывают разные. Бывают кандидаты квалифицированные, а бывают не очень, бывают очень умные, но смущающиеся, а бывают не очень умные, но нагловатые и т.д. Встречаются даже overqualified. Не видели таких? А вот мне попадались. Overqualified – означает, что человек не подходит на должность, потому что слишком много знает. И вот среди них всех надо выбрать самого подходящего. И сделать это должен интервьюер. И вот тут самая большая проблема.
Вот на форуме RSDN человек жалуется - завалил собеседование. Кратко суть такова: разволновался, срезался на третьем, довольно простом вопросе. После чего с ним попрощались. В дальнейшем обсуждении превалируют два мнения: «Не расстраивайся» и «Учи матчасть. Это должен знать каждый». А мое мнение – человеку просто повезло. В конторе явно полный бардак с процессом подбора персонала. А в коллективе, вероятно, царит атмосфера гуру-вщины и хакер-изма.
А проблема, проблема она в интервьюерах, и не только в той неизвестной конторе. Она повсюду. Обычно проводить интервью поручают наиболее опытному программисту: старшему, ведущему или тимлиду. Предполагается, что имея глубокие знания предмета, он успешно сможет оценить кандидата. Но дело в том, что глубокие знания предмета, это ровно половина того, что нужно интервьюеру для решения поставленной задачи. Вторая половина – это умение проводить интервью. Навык, к сожалению, гораздо более редкий, чем умение хорошо программировать. Обучать ему, по идее должны службы HR, но увы. И вот такие «полуграмотные» интервьюеры встречаются с кандидатами и начинаются, нет не интервью, начинаются бои без правил. Ведь никто не объяснил им элементарных вещей. Например, что не следует прерывать интервью после первого неверного ответа, даже если вопрос относится к разряду элементарных. Или, очень любимые многими интервьюерами ситуационные вопросы, основанные на личном опыте разрешения сложных и проблемных ситуаций. Типа, «вот был у нас случай...., как бы вы решили эту проблему». Ну и ответит кандидат правильно, и о чем это говорит? Это говорит о том, что вы в свое время потратили на решение этой проблемы несколько часов, а то и дней, а он решил ее за считанные секунды :). Может стоит его взять, а вас уволить? Одни пытаются сделать выводы только из рассказа кандидата о его опыте работы. Другие заваливают его кучами стандартных вопросов надерганных из интернета. Третьи устраивают перекрестный допрос кандидата вдвоем, перескакивая с темы на тему.
А что в результате. В результате субъективизм, непрофессионализм, испорченные нервы и потерянные деньги. Деньги теряет компания. Теряет на бесконечных собеседованиях с «отрывом от производства», на качестве принятых сотрудников, которое не соответствует требованиям и критериям, и наконец в виде упущенной выгоды, которая уплывает с необъективно отсеяными кандидатами.
Сегодня все знают, что «у них» (в зарубежных компаниях) собеседования проходят по другому. Там подход гораздо серьезней. Компании готовы тратить несколько сотен долларов на каждого кандидата, поскольку есть осознание того, что цена ошибки в этом вопросе будет на порядки больше. Технических интервью может быть пять или шесть. А если интервью одно, то наверняка проводит его специально подготовленный человек. Причем решение о приеме кандидата делает вовсе не интервьюер, а руководитель принимающий человека. Интервьюер - это лишь технический эксперт, который выдает рейтинговую оценку кандидата. И кстати отзывы тех, кто проходил интервью у них, более положительные. Если уж кого и завернули, то часто говорят так: «ну я не прошел, но собеседование понравилось».
Все потому, что у них tech interview, а у нас пока бои без правил, или в лучшем случае интеллектуальное казино «Что? Где? Когда?».

пятница, января 19, 2007

среда, января 17, 2007

Судный день или "Проблема с цифрой 7"

Те кто заходит на RSDN уже видели это. Человек пишет в форум RSDN, цитирую:
"Добрый день всем.
Проблема с цифрой — 7.
При выполнении следующего кода,
результат работы будет — 75.


public static void Main(string[] args)
{
Console.WriteLine(int.Parse("775"));
}


То есть во всех преобразованиях из string в int теряется
первая цифра 7.

При выполнении, например, операций
Convert.Int32("75"), возвращает 5.

При следующем коде :

public static void Main(string[] args)
{
Console.WriteLine(int.Parse("7"));
}


В ouptup window летит сообщение:
A first chance exception
of type 'System.FormatException' occurred in mscorlib.dll
Если обложить
операцию try ... catch то ловится FormatException.

Framework
переставлял.

Пробовал и на Framework 1.1 и на FrameWork 2.0.

Помогите пожалуйста"

Мистика какая то :)
Оказывается человеку кто то выставил на машине в региональных настройках для знака минус символ '7'.
Я просто плакал весь.

Дон Фергюсон - "Father of WebSphere" переходит в Microsoft

Как сообщает Dotnet.sys-con.com, Дон Фергюсон (Don Ferguson), Chief Architect IBM, известный, как отец WebSphere, переходит в Microsoft на позицию Microsoft Technical Fellow in Platforms and Strategy (что-то типа главного технического консультанта).
Дон Фергюсон изсестен не только как архитектор WebSphere, но и как один из основных идеологов концепции SOA, автор и соавтор многих основопологающих спецификаций в области web сервисов.
Как сообщает Microsoft: "осмысление тенденций, прогнозирование и применение их в существующих и будущих продуктах, евангелизм видения Microsoft будут ключевыми аспектами деятельности Дона".
Основные идеи, которые в последнее время продвигал Фергюсон, это роль web сервисов, как платформонезависимого слоя, связывающего различные информационные системы, а также business driven development.
В лице Фергюсона Microsoft заполучила выдающегося архитектора и идеолога.

воскресенье, января 14, 2007

Почему я не куплю себе iPhone

В последнее время я присматриваю себе подходящий комуникатор, но iPhone я не куплю. Нет, не потому что до нашей "азии" он дойдет только к 2008 году. Я не куплю iPhone потому, что Стив Джобс, эксплуатируя мои эстетические чувства, хочет, извините, "поднять меня на бабки".
Вот смотрите. Покупаете вы смартфон, модный и очень популярный. Незадача - просто в салоне купить вы его не можете - только с тарифным планом, ну скажем, "iБум" и пакетом дополнительных услуг на $49 в месяц от сотового оператора "МЦС". Вы уже подключены к другому оператору? Вам придется менять все контакты и визитки? Придется пожертвовать всем этим ради концепта от Apple. Он продается только в пакете с услугами определенного оператора.
Софт в айФоне конечно крутой, мультимедийный пакет - что надо, но ни флешку подоткнуть, ни свой софт поставить вам не удастся. Не знаю как вам, а я лично со своим смртфоном собирался поэкспериментировать, написать что нибуть свое для него. Давно, знаете, хотел поближе познакомиться с этой областью. Похоже - не выйдет. Apple мало $800 за аппарат и отчислений от оператора, они хотят иметь долю со всего софта и со всего контента, что будет крутится в iPhone.
Двух мегапискельная камера в айФоне - это вообще какой-то казус, который опять же кроме как жадностью Apple, ничем объяснить невозможно.
В общем, айФон не для меня. Я пожалуй подожду полгодика, пока китайский производитель освоится :). Выпустит что-то, подходящего форм фактора, с поддержкой wifi и bluetooth , с хорошим тачскрином, и с Symbian внутри (ну или на худой конец WinMobile 2007). Они наверняка сделают слот для флешек, а может и GPS модуль встроят. И стоить все это будет ровно столько, сколько я готов за него заплатить. А статусом придется пожертвовать...

P.S. А может и не китайцы. Может наш Sitronic's подсуетится. Не надо только быть такими жадными как Apple. А что, палю идею :)

пятница, января 12, 2007

Declarative and Imperative Security в .Net web сервисах

Жуткая вообще тема, конечно. Вот человек спрашивает «как мне защитить web сервис», и что такое Thread.CurrentPrincipal, и что такое declarative и imperative security. И никто ему толком не ответил. А я не зарегистрирован на SQL.ru и регистрироваться мне там лень. Да и вообще, не там он вопрос свой задал. Спросил бы на gotdotnet.ru или на rsdn.ru – ему бы быстренько ответили. А тема, вообще то хорошая. Жизненная тема.
Продвинутым читателям все это будет скучно и не интересно. Так и не читайте дальше. Но тем, кто приступает к решению подобных задач, я надеюсь, этот материал будет полезен.
Начнем, наверное, с того, что когда мы обращаемся к web сервису, как клиент, нам совершенно нет нужды обращаться к контексту безопасности текущего потока, который как раз и представлен статическим Thread.CurrentPrincipal. На клиенте у нас есть прокси класс web сервиса, а у него замечательное свойство Credentials. Вот его мы и используем для того, чтобы передать web сервису информацию о вызывающем его пользователе. Сделать это надо до первого вызова web метода сервиса, т.е. сразу после создания его экземпляра. Тут есть два варианта. Либо мы передаем информацию о текущем пользователе, и делается это вот так:


// создаем экземпляр прокси класса сервиса на клиенте
Echo echo = new Echo();
// передаем сервису удостоверения текущего пользователя
echo.Credentials = System.Net.CredentialCache.DefaultCredentials;


Либо передаем сервису удостоверения другого пользователя (учетной записи) которые храним где-либо в надежном месте:


// создаем экземпляр прокси класса сервиса на клиенте
Echo echo = new Echo();
// передаем сервису удостоверения пользователя "domain\user"
echo.Credentials = new System.Net.NetworkCredential("user","password","domain");


Вот собственно и все, что нам надо сделать на клиенте. Теперь перенесемся на сервер.
Чтобы исключить неавторизованный доступ к web сервису нам достаточно указать это в конфигурационном файле web.config


<authorization>
<deny users="?" />
</authorization>


Теперь все пользователи, которые не прошли аутентификацию будут завернуты IIS-ом с ошибкой 401 – Unauthorized еще на подступах к нашему web сервису. Сама аутентификация может осуществляться разными способами, в том числе теми, что вы напишите сами. ASP.Net хорошо расширяема в этом аспекте (читаем MSDN здесь).
Итак, те запросы которые добрались таки до нашего web сервиса уже аутентифицированы (ужасное слово). Это важно понимать. Что это означает на практике? Все мы знаем, что каждый запрос у IIS обрабатывается в отдельном потоке. Следовательно, каждый вызов web метода нашего web сервиса тоже обрабатывается в отдельном потоке, и контекст безопасности этого потока (представленный статическим Thread.CurrentPrincipal) содержит данные о пользователе вызвавшем этот метод с клиента. (Справедливости ради, надо отметить, что Thread.CurrentPrincipal может не содержать никаких данных о пользователе, если мы разрешили анонимный доступ к web сервису.)
И тут наступает время поговорить о декларативном и императивном (declarative and Imperative) стиле обеспечения безопасности в .Net. Главное, что стоит знать об этом, состоит в том, что оба стиля, декларативный и императивный, используют одни и те же механизмы, основанные на контексте безопасности потока (Thread.CurrentPrincipal). Декларативный стиль состоит в том, что мы при помощи специальных атрибутов помечаем код, и таким образом предписываем CLR выполнять те или иные проверки безопасности при любом доступе к этому коду. Звучит сложно, но выглядит все это просто:


[WebMethod]
[PrincipalPermission(SecurityAction.Demand, Role="Home\\Supervisor")]
public string Ask(string question)
{
string user = "User ";
return user + " asked: " + question;
}


Атрибут PrincipalPermission указывает, что перед исполнением данного метода CLR необходимо проверить (SecurityAction.Demand) входит ли тот, кто вызвал этот метод в роль «Supervisor» на компьютере (или в домене) «Home». Если данное условие не выполняется (пользователь не входит в данную роль), то при попытке вызова мы получим вот такое исключение


System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Security.SecurityException: Request for principal permission failed. at System.Security.Permissions.PrincipalPermission.Demand() at System.Security.PermissionSet.Demand() at TargetService.Echo.Ask(String question)


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


[WebMethod]
public string Ask(string question)
{
PrincipalPermission perm = new PrincipalPermission(
Thread.CurrentPrincipal.Identity.Name,
RoleName);
perm.Demand();

string user = "User ";
return user + " asked: " + question;
}


У нас добавилось две строчки кода. Сначала мы создаем экземпляр PrincipalPermission, передавая ему имя пользователя из текущего контекста безопасности и имя роли. А затем вызываем метод Demand(), который проверяет, принадлежит ли пользователь заданной роли. В случае метод Demand() выбрасывает исключение вот такого вида:


System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Security.SecurityException: Request for principal permission failed. at System.Security.Permissions.PrincipalPermission.Demand() at TargetService.Echo.Ask(String question)


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


[WebMethod]
public string Ask(string question)
{
if(!Thread.CurrentPrincipal.IsInRole(RoleName))
throw new SecurityException("Request for principal permission failed");

string user = "User ";
return user + " asked: " + question;
}


Этот код выглядит еще проще, чем предыдущий, но результат получаем аналогичный. Если текущий пользователь не принадлежит заданной роли, получаем исключение:


System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Security.SecurityException: Request for principal permission failed at TargetService.Echo.Ask(String question)


И, наконец, вот на этом месте, как мне кажется, наступает самое подходящее время, разобраться с тем, откуда все таки берутся все эти роли, и как Principal или PrincipalPermission узнает о том, что текущий пользователь входит в данную роль.
Код, который отвечает за это (определение принадлежности пользователя к роли) содержится в методе CurrentPrincipal.IsInRole(string). Если мы не предпринимали никаких дополнительных действий, то наверняка наш Thread.CurrentPrincipal на поверку окажется экземпляром класса WindowsPrincipal. Это следствие того, что мы использовали режим Windows Integrated Aithentication IIS. Сам WindowsPrincipal представляет учетную запись пользователя Windows (локальную или доменную) а метод WindowsPrincipal.IsInRole(string) определяет принадлежность пользователя группе (доменной или локальной).
Ну а если мы хотим для авторизации использовать не Windows пользователей, а своих, данные о которых храним в БД приложения? Или, как вариант, пользователи у нас будут Windows, а вот роли мы определяем свои, и правила принадлежности пользователя к роли у нас тоже свои и при этом очень хитрые? Обе проблемы решаемы, но для этого нам придется писать код.
Когда нас не устраивает WindowsPrincipal, есть класс GenericPrincipal и мы можем создать его экземпляр и присвоить HttpContext.Current.User в обработчике события Application_AuthenticateRequest, что в Global.asax. Ну а если нас не устраивает и GenericPrincipal, мы можем написать свою реализацию интерфейса IPrincipal и даже расширить ее. Потребоваться это может, например, в случае, когда нас не устраивает метод IsInRole(string). Может случиться такое, что для определения принадлежности к роли понадобится передавать дополнительные параметры. Тогда мы делаем свою реализацию IPrincipal и расширяем ее дополнительными методами (не интерфейс, конечно, а класс). Вообще то, все это замечательно, с картинкам, с примерами кода, расписано в MSDN. Мне подробней все равно не написать, да и смысла нет.
Вот собственно то, что вам надо знать для того, чтобы начать понимать, как обеспечивается безопасность ASP.NET web сервисов. Теперь вы можете заняться этой темой плотнее, используя MSDN, и попытаться построить действительно безопасный сервис (или сайт – механизмы безопасности для web сервисов и web страниц ASP.NET общие). Есть еще одна тема, которая плотно связана с безопасностью - это имперсонация и делегирование в ASP.NET. О них я тоже недавно писал, и кому интересно, могут посмотреть по ссылке

вторник, января 09, 2007

«Connected Experience» - Microsoft задает тон на CES 2007

Это символично, Бил Гейтс выступает, с по сути, программной речью (keynote) на всемирной выставке потребительской электроники. Благодаря web 2.0 :) мы можем уже сейчас посмотреть web трансляцию этого события
Сегодня в мире появляется все больше замечательных электронных устройств (amazing devices) и Microsoft создает софт (извините за тавтологию), который способен объединить все эти устройств, такова главная нить доклада. «Connected Experience» - под этим лозунгом выступает Microsoft на CES 2007. Забавно, что похожие идеи использовала Sun почти 15 лет назад, когда продвигала только что созданную платформу Java. Но тогда, видимо, эта идея опередила свое время. А сегодня уже Microsoft готовится пожинать урожай на этой ниве. И похоже ей повезет больше чем предшественнице :)
Microsoft стремительно выходит рамки офисных ПК в новые для себя сферы мобильных устройств, встроенной электроники, HDTV и т.д. И основным локомотивом на этом пути должна стать Windows Vista. Аплодисменты присутствующих вызвала демонстрация полета над виртуальной 3d картой Лас-Вегаса на ноутбуке с Windows Vista, управляемой джойстиком от X-Box 360. Одновременно на автосалоне в Деторойте и на выставке в Лас Вегасе Ford и Microsoft демонстрируют свою совместкую разработку в области бортовой электроники Sync
В общем, рекомендую посмотреть. Гейтс, как всегда, выступает ярко и захватывающе.
И еще. Наверное, мне все-таки придется проапгрейдить свой домашний компьютер, чтобы поставить Vista. Переиначивая знаменитое выражение била Гейтса «Vista is a reason to upgrade your comp.» (в оригинале: “Cool is a reason to spend money.”)

понедельник, января 08, 2007

"Ну вы, блин, даете..."(с)

После нового года в блогах Gotdotnet.ru появилась новая фича. В борьбе со спам ботами старая добрая капча (картинка с символами) кому-то показалась недостаточно крутой для такого продвинутого сообщества как GotDotNet. Теперь, для того, чтобы оставить коментарий в блоге надо ответить на вопрос типа такого:

Интересно, чем руководствовался тот, кто все это придумал. Спам фильтр типа капчи, представляет собой задачу, с которой легко справляется любой человек, но которая представляет очень большую сложность для программы.
Я могу в течении часа написать бота, котрый методом простого перебора, автоматически составит базу правильных ответов на все эти вопросы.
Так кого же отсекает этот фильтр? Это не спам фильтр, а какой то кастовый фильтр. Он отсекает от блогов gotdotnet миллионы умных людей, не знакомых с сакральным знанием .net fw.
Вот захочет Ольга Дергунова или Уильям Генри Гейтс Третий прокоментировать пост в блоге GotDotNet.ru, и не сможет. Первая - из-за того что не очень знакома с .Net Framework а второй - потому что не сможет прочитать вопрос по русски :)
Помнится такие методы в своем общении использовали в массонских ложах. На мой взгляд весьма опрометчивое и не дальновидное решение. Получается русский ортодоксальный дотнет блог. Кстати большинству участников блога фича понравилась. Грусно.

Чем бы заняться стартапу

Елена Макурочкина рассуждает на тему "Чем бы заняться стартапу". Интересная тема. Я уже оставил свой коментарий, но захотелось более развернуто порассуждать на эту тему. Действительно, что за софт такой надо сделать, чтоб с ним на рынок выйти и денег кучу заработать. А может секрет не в том что сделать, а в том как это подать?
Но все таки то, что мы продвигаем имеет решающее значение.
"Не новое и не уникальное" - это явно не для стартапов. Цена выхода на рынок с таким продуктом слишком уж велика. Живой пример - Microsoft Dynamics (ERP от Microsoft, бывшая Navision). Только имея такие ресурсы как у M$ можно пропихивать не новый и не уникальный продукт на столь плотно освоенный рынок как ERP системы.
А по остальным вариантам - не все все так плохо. Посмотрите на Google. Это же конгломерат стартапов. Вот, например Google SketchUp - программа 3D моделирования. Вы про нее слышали? Наверняка нет. Пробится на рынок 3D - ой как сложно, но не сомневайтесь, скоро про SketchUp узнают все. В этом продукте есть одна вещь, которой нет ни у одного конкурента. Благодаря некоторым, скажем так - инновациям, в GUI освоить работу с этой штукой можно за 20 минут. Вы пробовали с нуля, без книжки, освоить работу в 3d Max? То то-же. У всех 3d продуктов - сложность - как родимое пятно. Так сложилось - продукты для профессионалов, а SketchUp - продукт для массового использования. Успех гарантирован.
И еще про Google. Вы пользуетесь Google? Вы можете вспомнить как вы узнали про Google? Сейчас Google торгует рекламой и зарабатывает на этом миллиарды, но сам он никогда рекламой для своей раскрутки не пользовался. Принципиально. Я сам узнал про Google в 2000 году, читая один из интернет дневников (слова блог тогда не было :). Сейчас это называют социальными сетями и web 2.0, а тогда это все расходилось через fido, форумы и т.п. Сегодня социальные сети это мощнейший инструмент, которым с успехом пользуются многие стартапы.

суббота, января 06, 2007

Почему agile не дружит с design

Мне нравятся методологии Agile и прочие XP. Мне нравится нацеленность на результат во всех их практиках, отсутствие формализма, гибкость и динамичность. Если кому-то XP кажется хаосом, значит он ничего не понял в этой методике.
Единственное что мне не нравится – недостаточное внимание к проектированию. В манифесте agile читаем:
«Самые лучшие архитектуры, требования и дизайны
систем создаются самоорганизующимися командами.»

Вероятно, это действительно так, когда команда состоит из таких зубров, как те, что писали этот манифест. Обычно все обстоит совсем иначе. Обычно все, как в статье Мартина Фаулера «Is design dead?»

«Наверное, наиболее привычным является эволюционное проектирование. Определение "эволюционный" указывает на то, что во время реализации системы ее дизайн растет вместе с ней. Проектирование, в этом случае, является частью процесса программирования, поэтому в ходе развития системы дизайн меняется.

В большинстве случаев, эволюционное проектирование - это нечто ужасное. В конце концов, все равно вместо дизайна системы вы получаете просто набор из специфических решений, каждое из которых затрудняет дальнейшие изменения в программном коде. Часто это вообще нельзя считать дизайном (и, уж конечно, такой дизайн никак нельзя назвать хорошим). Как говорит Кент, дизайн существует для того, чтобы дать возможность оперативно вносить в систему любые изменения. Если дизайн плох, то такая возможность исчезает. В результате вы будете иметь дело с энтропией программного продукта, и со временем и без того плохой дизайн системы станет еще хуже. Теперь вам будет не только сложнее вносить в систему изменения, но и отыскивать и исправлять ошибки, которые начинают множиться с катастрофической быстротой. Все это - кошмар разработок в стиле "code and fix", когда с течением времени исправление ошибок обходится все дороже и дороже.»

Хорошо написал Мартин, мне даже и добавить нечего. Далее в своей статье Мартин рассуждает о том, как при помощи таких практик XP как тестирование, рефакторинг, простой дизайн (YAGNI) и т.д., можно побороть этот кошмар.
Сейчас один из проектов, в которых я участвую, ведется по методике SCRUM уже второй год. С дизайном там ситуация примерно как описано выше. Все то, что призвано заместить отсутствие предварительного проектирования, к сожалению, не срабатывает.
Я, как и Фаулер, склонен относить себя к «трусливым XP-шникам», потому что предпочитаю иметь high level design системы перед тем, как приступать к разработке. И слава Богу, что все agile методологии позволяют мне такую «вольность». За что я их и уважаю.

Процессы vs. сервисы.

В недалеком прошлом я активно занимался тематикой workflow. Так вот, я всегда считал процессный подход исключительно эффективной методикой и средством для разработки корпоративных приложений. Попробую кратко описать, в чем он состоит. Термин «бизнес процесс» из числа тех, которые имеют очень широкую трактовку. В зависимости от того, кто его употребляет, каждый вкладывает в него свой смысл. Для менеджера и бизнес аналитика бизнес процесс - это согласованная, управляемая и систематическая (повторяемая) совокупность активностей участников (действующих лиц), направленная на достижение определенных бизнес целей предприятия. Для проектировщика или архитектора, бизнес процесс это совокупность бизнес объектов (данных), бизнес операций (функций), исполнителей и бизнес правил, описывающих последовательность исполнения и взаимосвязи исполнителей операций и данных. Естественно, что первые оперируют реальными бизнес процессами, а вторые - их отражением в информационных системах.
Процессный подход подразумевает, что разработка системы строится вокруг реальных бизнес процессов предприятия. Начиная с фазы анализа, проектирования и заканчивая сдачей в эксплуатацию и дальнейшей поддержкой и модификацией системы. Что делает такой подход эффективным? Первое, бизнес процессы направлены на реализацию бизнес целей предприятия. И это очень важно, ведь таким образом, создаваемая система имеет прямой выход на конкретные бизнес цели. Заказчику понятно, что система делает для его бизнеса. Второе, это комплексный подход. Бизнес процессы обычно пронизывают несколько функциональных областей, таких как закупки, производство, сбыт, управление взаимоотношений с клиентами, управление персоналом и т.п. На границах этих областей обычно возникают проблемы, которые снижают эффективность информационных систем. Процессный подход – хорошее средство от подобных проблем. Кроме того, сила процессного подхода в грануляции функционала на элементарные бизнес операции, и отделение бизнес операций от логики самого процесса (такой как, например, последовательность исполнения операций). Как результат высокая адаптивность системы. Операции могут компоноваться в новые и новые процессы, а сами процессы могут легко изменяться в соответствии с изменчивыми потребностями бизнеса.
Вот здесь лежит очень важная точка соприкосновения двух концепций: процессного и сервис ориентированного подхода. Вы не находите?
Слабо связанные, автономные и независимые сервисы идеально подходят на роль поставщиков бизнес операций для процессного подхода. А среда исполнения бизнес процессов замечательно смотрится как надстройка над SOA, или вернее как ее составная часть. Я считаю, что, например, в роли сервисной шины предприятия (ESB), workflow ориентированная среда исполнения бизнес процессов будет намного эффективней традиционных шинных архитектур основанных на очередях сообщений.
В общем, как ни крути, а получается вот она, серебряная пуля – «SOA + процессный подход», на основе которой будут создано новое поколение корпоративных информационных систем.
К сожалению, практические опыты серьезно омрачили этот светлый образ будущего благоденствия. Основные проблемы возникли в степени адаптивности получаемых решений, т.е. именно там, где предполагалось пожать самый большой урожай бенефитов от нового подхода.
Вот, к примеру, разрабатываем систему управления оплатой счетов на текущие расходы компании (accounts payable). Начинаем анализ с определения бизнес процессов, которые собираемся автоматизировать. Бизнес процесс не сложен: все текущие расходы, как-то: канцелярские принадлежности, транспортные, рекламные, представительские, и другие расходы связаны с оплатой выставленных счетов. Заявки на эти расходы должны быть согласованы, а счета своевременно оплачены. Бизнес цели тоже понятны: оптимизировать расходы, обеспечить своевременную оплату счетов, увязать расходы с бюджетами и финансовым планированием. В соответствии с процессным подходом, выявляем действующих лиц и исполнителей, источники и потребителей информации, информационные потоки и основные бизнес операции. Компонуем полученные бизнес операции по функциональным признакам в сервисы, реализуем их. Отдельно реализуем бизнес правила потока исполнения работ (т.е. самого бизнес процесса). Компонуем все это вместе и получаем в результате замечательную, структурированную и эффективную работающую систему.
На нашу беду, в этот момент в организации сменяется финансовый директор, а вместе с ним меняются принципы финансового планирования и соответствующие изменения надо внести в нашу систему управления оплатой счетов. Вот тут-то и наступает момент истины. По идее, благодаря процессному подходу и сервис ориентированной архитектуре, мы легким движением руки изменяем настройки соответствующих бизнес процессов и, вуаля, наша система работает по новому. Реально оказывается, что изменение логики бизнес процесса тянет за собой «небольшие» изменения в бизнес операциях, которые «наши программисты сделают максимум за неделю». Но какого дьявола? Мы приложили столько усилий для того, чтобы отделить реализацию наших сервисов от реализации бизнес правил потока исполнения, и первое же изменение в процессе тянет за собой изменения в сервисах. Где же адаптивность? Ситуация крайне неприятная, и к сожалению, довольно типичная. Если вы в нее не попадали, то это означает одно из двух: либо вы никогда не создавали подобных систем, либо вам удается виртуозно управлять ожиданиями заказчика (customer’s expectations).
Пытаясь проанализировать причины неудач, я поначалу искал их в архитектурных просчетах, потом - в несовершенстве используемых платформ и технологий, полагая, что они не могут обеспечить должный уровень адаптивности. Сейчас я склоняюсь к тому, что причина лежит в несовершенстве методологии анализа, а уж затем в изъянах проектирования и в последнюю очередь в несовершенстве технологий.
Начиная анализ с модели бизнес процессов, выделяя бизнес операции и сервисы из этой модели, мы на самом раннем этапе закладываем обратную корреляцию между полученной в результате моделью сервисов и моделью бизнес процессов. А ведь именно на разделении этих двух моделей, на достижении их независимости их друг от друга, базируется высочайшая адаптивность сервис ориентированных систем. Получается, мы сами закладываем эту зависимость на самых ранних этапах анализа и проектирования, попросту не замечая этого. Иными словами мы проектируем сервисы заточенными под конкретные процессы. Ничего удивительного в этом нет. Полученные в результате анализа модели сервисов и бизнес процессов отвечают всем формальным критериям полноты, непротиворечивости, однозначности, etc. Лишь потом мы обнаруживаем, что любое сколь ни будь значительное изменение бизнес процессов, требует внесения изменений в сервисы, чего по идее быть не должно.
Как, же избежать этой порочной зависимости? Я не имею пока четкого ответа на этот вопрос. Возможно, начинать анализ все же надо традиционным способом, с предметных областей, а модель процессов формировать на самом последнем этапе анализа после модели сервисов? Говорят, именно такой подход использует новая методология Motion от Microsoft. Но это тема для совсем другого разговора.

пятница, января 05, 2007

Неуловимое обаяние архитектуры

Для тех, кто интересуется архитектурой ПО будут небезинтересны рассуждения на эту тему Антона Терехова. Все, что принято называть благородным словом "архитектура" Антон опускает до уровня зубодробительной аббревиатуры HLD (high level design). А сама же архитектура - материя эфирная, "должна быть понятна всем", но что это такое никому толком не известно. С чем я, в прочем, соглашусь без лишних споров :).

среда, января 03, 2007

Complexity Fighting

Борьба со сложностью - святая обязанность архитектора (да и программиста тоже), о которой, к сожалению часто забывают. Или стесняются. Конечно, каждому хочется наваять крутую архитектуру (как в очередной прочитанной книжке), или применить классный паттерн (visitor или decorator или plugin или всех сразу). Часто за этим ничего не стоит, кроме желания самоутвердиться среди коллег. Многие разработчики стесняются применять простые решения, из-за того что коллеги могут подумать, что у вас недостаточная квалификация. Например, разработчик реализует "элегантную" схему кэширования данных, не зная о том, что получаемые им данные уже и так кэшируются на предыдущем логическом уровне. Иногда надо обладать определенной смелостью для того, чтобы применить простые решения на практике. Горе вам, если вы работаете в команде, где считается крутым писать код так, чтобы никто не мог понять как он работает.
Жестокий закон разработки состоит в том, что программные системы являются сложными системами, и в ходе разработки сложность системы неумолимо нарастает. Сложность определяет тот предел, дальше которого невозможно продвинутся в разработке. Вместе со сложностью растет энтропия. Энтропия убивает систему и разрушает процесс разработки. Если с этими явлениями не бороться и программный продукт и процесс его разработки деградируют. Все последние десятилетия программная инженерия развивалась в направлении позволяющим разрабатывать все более сложные системы с приемлемым уровнем качества, производительности и т.д.
Боритесь со сложностью и вам воздастся :) Боритесь со сложностью на этапе проектирования. Ранжируйте требования, смело отметайте несущественные, и требования не подкрепленные реальными потребностями.
Всегда думайте о том - можно ли обойтись без этого блока (слоя, компонента, шлюза и.д.)? Что будет если выкинуть то или это? Достаточно прост ли этот интерфейс, нельзя ли из него выкинуть пару методов? Не будет ли гораздо проще, если в этот интерфейс добавить пару методов? Нельзя ли убрать вот эту зависимость между компонентами?
Простая программа наверняка будет работать лучше чем сложная. Однако простую программу написать гораздо сложнее, чем сложную.
Сложность опасный противник, она подбирается со всех сторон, и бороться с ней надо постоянно.