Thursday, December 29, 2011

Аутсорсинг и продуктовая разработка

Очень часто приходится слышать как программисты сравнивают и противопоставляют продуктовую и аутсорсинговую (outsourcing) разработку. И часто при этом говорят, что аутсорсинг - это ерунда и неинтересные проекты, а вот если разрабатывать продукты или начать стартап, то сразу будет счастье. Если быть до конца точными, то все это разделение не совсем корректно, т.к. сравниваются метры с килограммами.

Кстати, само слово “стартап” также часто используется неверно среди IT-шников. Стартап - это любой начинающийся бизнес, не только IT, просто наибольшее распространение он получил именно в нашей сфере в эпоху доткомов.

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

Итак, компании, так или иначе занимающиеся разработкой ПО, можно условно разделить на 2 группы:

  1. производящие ПО для собственных нужд или с целью самостоятельного распространения (продукты и услуги)
  2. предоставляющие услуги по разработке ПО для сторонних заказчиков

Вторую группу составляют именно те компании, которые обычно называют аутсорсинговыми, но так ли это, что они не разрабатывают продукты? В первую группу входят компании, которые обычно называют продуктовыми, но единственные ли они в этой группе?

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

  1. продукты (в основном настольные, мобильные и embedded, реже - веб), а также веб-решения, предоставляющие пользователям различные услуги, но предназначенные для использования большим количеством сторонних пользователей, а не самой компанией
  2. custom solutions - индивидуальные решения, предназначенные для внутреннего использования одним потребителем, например, внутри компании или организации

Если и другие классификации ПО, но нам они сейчас не очень интересны.

Понятно, что custom solutions могут разрабатываться как внутри самой компании (in-house), так и на заказ у какого-нибудь вендора. Но ведь и продукты со “стартапами” не всегда разрабатываются внутри компании, которая потом эти продукты продает.

Если скрестить это все, то получим следующую картинку:

Custom_vs_products

То есть любая аутсорсинговая компания может производить для своих заказчиков как индивидуальные решения, так и продукты. С точки зрения разработки продуктов их отличие от продуктовых компаний лишь в том, что аутсорсинговые компании, как правило, не принимают решения по продукту (Product Management на стороне заказчика) и не продают эти самые продукты, т.е. почти не рискуют, но и не собирают все сливки.

Поймите меня правильно, я ни в коем случае не хочу сказать, что разработка ПО на заказ (по сути, продажа труда, знаний и времени разработчиков) - лучше, чем разработка и продажа собственных продуктов или услуг на базе собственных решений. Разрабатывать продукты сложнее, потому что лишь 20-30% этого процесса - непосредственно разработка, остальное - анализ рынка и конкурентов, работа с пользователями, и самое главное - продажи. И после всех усилий и вложенных средств еще неизвестно - взлетит или не взлетит. Продавать услуги по разработке ПО в этом отношении намного проще и гораздо менее рискованно. В то же время и возможности заработка в аутсорсинговой модели ограничены рейтами, а разница между доходами и расходами невелика, в то время как в случае успеха продукта или стартапа доход может быть в разы, десятки и сотни раз выше, чем расходы. Но, как известно, кто не рискует, тот не пьет шампанского.

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

Monday, December 26, 2011

Распределенные транзакции (Distributed Transactions) и их настройка

Каждый программист, работающий с данными, сталкивался с обычными транзакциями той или иной базы данных. Основная задача транзакций – обеспечить consistency данных после завершения операции: изменения либо успешно сохраняются от начала и до конца, либо полностью откатываются, если что-то пошло не так. Даже если вы ни разу не писали в SQL коде ключевые слова BEGIN TRAN, COMMIT TRAN или ROLLBACK TRAN или нечто подобное, это еще не значит, что вы их не использовали. Все ORM, реализующие паттерн unit of work (Entity Framework, NHibernate и др.) объединяют операции по изменению данных в транзакцию перед сохранением.

Транзакции хорошо работают в рамках одной базы данных, но если у вас распределенная система, которая требует сохранения данных в разных базах на разных серверах, а иногда и платформах, то нужна более тяжелая артиллерия – распределенные транзакции (distributed transactions, DT).

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

Truly Understanding .NET Transactions and WCF Implementation

Работа вложенных транзакций отлично расписана здесь:

Understanding nested transaction scopes

Также не забывайте про MSDN:

http://msdn.microsoft.com/en-us/library/w97s6fw4(v=VS.90).aspx

Итак, .NET поддерживает распределенные транзакции при помощи класса TransactionScope. Кроме этого, основная технология разработки распределенных приложений, WCF, также поддерживает распределенные транзакции из коробки, предоставляя программисту целый комплекс конфигурационных параметров и атрибутов, которые позволяют с легкостью превратить ваш сервис из обычного в распределенно-транзакционный.

Для того, чтобы запустить ваш сервис в режиме поддержки распределенных транзакций, необходимо выполнить несколько шагов, щедро описанных в книгах, а также статьях и блогах в Интернете:

1) Сконфигурировать WCF для поддержки DT

Распределенные транзакции не поддерживаются в режиме basicHttpBinding, поэтому нам нужно использовать хотя бы на wsHttpBinding, в binding которого нужно прописать атрибут transactionFlow=”true”:

<wshttpbinding>
    <binding name="wsConfig" transactionflow="true">
         <security mode="None" />
    </binding>
</wshttpbinding>

2) Установить специальные атрибуты в интерфейсе сервиса и его методов

Необходимо добавить атрибуты TransactionFlow для метода в контракте и свойства атрибута OperationBehavior TransactionScopeRequired и опционально TransactionAutoComplete в реализации метода:

[ServiceContract] 
public interface IServiceContract 
{ 
    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.Allowed)] 
    string ServiceMethod(string param1, string param2); 
}

public class Service : IServiceContract 
{ 
    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 
    public string ServiceMethod(string param1, string param2) 
    { 
      // some server-side operations with database 
    } 
}

Атрибут TransactionFlow принимает несколько опций: Allowed обозначает, что метод сервиса может вызываться как из кода, обернутого в TransactionScope, так и из обычного. Mandatory требует наличия TransactionScope, а NotAllowed (по умолчанию) заставит сервис игнорировать транзакции на клиенте вообще.

3) Создать на стороне клиента транзакцию, внутри которой вызвать метод WCF сервиса

Выглядит это приблизительно так:

public static string DoSomethingWithRemoteCall(string param1, string param2) 
{ 
    string result = null; 

    TransactionOptions options = 
        new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromSeconds(300) }; 
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, options)) 
    { 
        // some client-side database actions 

        using (var ecommerceFactory = new ChannelFactory("Staging")) 
        { 
            ecommerceFactory.Open(); 

            var proxy = ecommerceFactory.CreateChannel(); 
            bool success = false; 

            try 
            { 
                result = proxy.ServiceMethod(param1, param2); 
                success = true; 
            } 
            catch (Exception ex) 
            { 
                // log exception 
                return;

            } 
            finally 
            { 
                if (success) 
                    ecommerceFactory.Close(); 
                else 
                    ecommerceFactory.Abort(); 
            } 
        } 

        // other possible client-side database actions
        scope.Complete(); 
    } 

    return result; 
}

Безусловно, в вашем коде вызов сервиса должен находиться в отдельном классе, это лишь пример.

TransactionOptions позволяет задать некоторые параметры транзакции. В нашем случае это уровень изоляции (значение по умолчанию Serializable не рекомендуется из-за опасности возникновения дедлоков) и таймаут операции (5 минут).

При создании TransactionScope мы указываем параметр TransactionScopeOption.RequiresNew, что не позволит никакому другому коду обернуть наш метод в свою транзакцию. Подробнее вложенные транзакции описаны здесь.

Внутри TransactionScope в случае, если мы действительно хотим закоммитить транзакцию, мы делаем вызов scope.Complete(). Если нам нужно транзакцию откатить (как в случае с catch в примере), мы просто не вызываем Complete(). Вызывать Complete() нужно после всех клиентских операций с базой данных, которые происходят внутри транзакции, иначе у вас случится ошибка, что connection или provider уже закрыт.

Обратите внимание, что в коде сервиса из предыдущего пункта нет никакого намека на TransactionScope, кроме атрибутов TransactionFlow и OperationBehavior. Он там и не нужен, для стандартного сценария атрибутов достаточно. Однако никто вам не мешает создавать свои вложенные транзакции, как с опцией Required (используем родительскую транзакцию), так и с опциями RequiresNew (новая независимая транзакция) и Suppress (код не будет выполнятся в родительской транзакции).

4) Запустить сервис и клиент

И вуаля – все работает. Или не работает? Говорите, полезли странные ошибки выполнения?

Для того, чтобы распределенные транзакции заработали, необходимо сделать еще правильно сконфигурировать клиенты и сервера:

1) Убедиться, что на всех клиентах и серверах (здесь и далее - включая сервера баз данных и веб-сервера) установлена и запущена служба Distribution Transactions Coordinator. Именно эта служба отвечает за координацию ваших распределенных транзакций.

2) Убедиться, что на всех клиентах и серверах включена поддержка распределенных транзакций. Для этого запускаем Control Panel –> Administrative Tools –> Component Services, идем в Computers –> My Computer –> Distributed Transaction Coordinator –> Properties (контекстное меню) и устанавливаем на вкладке Security следующие параметры:

  • Network DTC Access
  • Allow Remote Clients
  • Allow Inbound
  • Allow Outbound

Component_Services

3) Разрешить работу Distributed Transactions Coordinator во всех установленных брандмауэрах, включая Windows Firewall:

Firewall

4) Убедиться, что все ваши клиенты и сервера находятся в одной локальной сети. В большинстве случаев так оно и есть, но есть исключения, и если вы тот самый счастливчик, то вам придется немного попотеть, реализовывая поддержку протокола WS-Atomic Transaction (WS-AT), который упоминается в общей статье. Если вы тот самый счастливчик, которому надо начинать настраивать WS-AT, то вот еще пара полезных статей:

Configuring WS-Atomic Transaction support (MSDN)

Building transactional Web services with WebSphere Application Server and Microsoft .NET using WS-AtomicTransaction

5) Для работы DTC по локальной сети: все машины должны пинговаться по netbios-имени.

6) Важно: Если вы пошли по нашему пути и запустили тестовую конфигурацию на виртуальных машинах, запущенных с одного образа: переустановить DTC. DTC не работает с одинаковыми CID, а переустановка их сбрасывает. Это проблема, с которой мы столкнулись и которую смогли найти лишь запустив утилиту DTCPing.

Больше деталей здесь: Warning: the CID values for both test machines are the same

7) Если ничего не помогло: поставить и запустить DTCPing и посмотреть, что она говорит. Очень хороший способ, когда ничего другое не помогает:

Troubleshooting MSDTC issues with the DTCPing tool

Saturday, December 3, 2011

Paypal: работа с 3rd party merchant accounts

Интеграция с Paypal – вещь не сложная. Paypal поддерживает два типа API: Name-Value pairs (URL-based) и стандартный SOAP, а также несколько сервисов для работы, из которых самые распространенные Website Payments Standard и Website Payments Pro (Express Checkout и Direct Payments). Paypal также предоставлят Sandbox для тестирования и достаточно подробную документацию по каждому продукту и типу интеграции. Это если вкратце.

На деле же, как и с любым другим API, здесь есть свои подводные камни, с которыми приходится бодаться. Об одном из них, на который я потратил довольно много времени, мне и хотелось бы рассказать.

Для того, чтобы ecommerce сайт работал с Paypal, необходимо иметь Paypal merchant аккаунт, на который идет вся оплата за товары и услуги, продаваемые на сайте. Для авторизации на Paypal для аккаунта генерируются т.н. API Credentials: Username, Password и Signature/Certificate (лучше использовать Signature). Как это делается, в деталях рассказывается в документации. То есть механизм простой: веб-приложение передает запросы на Paypal, используя три параметра API Credentials, а Paypal таким образом “знает”, с каким merchant аккаунтом идет работа, грубо говоря, кому перечислять деньги за товары.

Все это замечательно работает, когда у вас в приложении “хостится” один продавец, и так работает наверно 95% всех ecommerce-сайтов, от простейших шаблонных электронных магазинов до более серьезных решений. Но в случае реализации сложной торговой площадки, на которой может работать множество торговцев, вроде Amazon.com, eBay.com или etsy.com, этого становится недостаточно. Есть два способа решения этой задачи.

Первый способ очевидный: пусть каждый merchant сгенерирует себе API Credentials и укажет их в своем профиле торговой площадки. Тогда при работе с выбранным Paypal API нужно будет всего лишь подставлять нужные credentials – и вуаля. Однако если посмотреть на профили того же Amazon или eBay для торговцев, то можно увидеть, что они просят ввести только Merchant account email. И никаких паролей или API credentials! Это и есть второй способ интеграции, не так хорошо задокументированный.

Упоминание об этом способе почему-то достаточно хорошо скрывается в документации к функциям API и фактически встречается лишь в описании работы с Name-Value pairs API и на форумах (кстати, форумы Paypal очень полезны, но гуглом не индексируются, поэтому лучше искать прямо там). Вот оно:

image

То есть можно сгенерировать API Credentials для всего приложения и динамически подменять лишь SUBJECT поле для каждого запроса, таким образом говоря Paypal, с каким merchant сейчас идет работа. И все бы хорошо, да только NOTE там указан не просто так. Paypal API достаточно мощный и дает возможность обращаться к некоторой внутренней информации merchant аккаунта, поэтому необходимо, чтобы merchant дал разрешение на определенные операции. Эти разрешения merchant может задать в Profile –> API Access –> Grant API Permissions. Далее нужно ввести API account username торговой площадки, которой даются разрешения и в появившемся списке выбрать те разрешения, которые нужны. Например, для работы с Express Checkout нужно выбрать как минимум:

  • Use Express Checkout to process payments

Также полезными могут оказаться:

  • Authorize and capture your PayPal transactions – если оплата проходит в 2 этапа: авторизация и захват/списание денег
  • Refund a transaction on your behalf – для возврата денег в случае возврата товара
  • и некоторые другие (полный список есть здесь)

Дальше – больше. Процесс разрешения прав можно упростить для торговцев еще сильнее, если использовать т.н. Paypal Permissions Service. Этот сервис предоставляет возможность интеграции торговой площадки со специальными страницами разрешения прав на Paypal. То есть пользователю-торговцу достаточно лишь кликнуть ссылку или кнопку на сайте торговой площадки, и он будет автоматически переброшен на страницу Paypal с уже выбранным набором прав для разрешения, необходимых вашему приложению. Пользователю останется лишь подтвердить разрешение.

Тестирование этого процесса также заслуживает внимания, так как там притаилась еще одна небольшая засада. Вам необходимо создать 2 (!) различных sandbox-аккаунта, один из которых будет использоваться для создания API Credentials веб-приложения, а второй – для создания тестовых merchant-аккаунтов, которые будут якобы продавать товары. И неважно, что merchant (или seller) аккаунты можно создать и на основном sandbox аккаунте, вам не удастся сконфигурировать нужные права и Paypal будет возвращать непонятные ошибки.

Надеюсь, для кого-то эта информация окажется полезной и сэкономит время.

Saturday, November 19, 2011

Онлайн-курсы от Стэнфорда

Многие программерские ресурсы уже раструбили эту новость, но, может, кто-то еще не слышал. Полтора месяца назад Стэнфордский университет запустил бесплатные онлайн-курсы по Artificial Intelligence и Machine Learning. Эксперимент оказался довольно удачным (хотя отзывы по курсу AI и хуже, чем по ML) и с января по март запускается вторая волна курсов, 8 9 по Computer Science и 2 по Enterpreneurship:

1. Machine Learning — jan2012.ml-class.org
2. Introduction to Computer Science — www.cs101-class.org
3. Natural Language Processing — www.nlp-class.org
4. SaaS and Software Engineering — www.saas-class.org
5. Human-Computer Interaction — www.hci-class.org
6. Game Theory — www.game-theory-class.org
7. Probabilistic Graphical Models — www.pgm-class.org
8. Cryptography — www.crypto-class.org
9. Design and Analysis of Algorithms — http://www.algo-class.org/
10. Technology Entrepreneurship — www.entrepreneur-class.org
11. The Lean Launchpad — www.launchpad-class.org

Курсы проводят в основном преподаватели Стэнфорда, многие из которых являются признанными экспертами в своих областях и авторами книг.

Курсы можно проходить в одном из двух режимов: Basic или Advanced track. В Basic треке вы просматриваете лекции и отвечаете на еженедельные тесты. При этом никто ничего от вас не требует. В Advanced треке в дополнение нужно делать лабораторные работы, которые будут проверяться преподавателями. Работы оцениваются, их нужно сдавать вовремя, за опоздание начисляются штрафные баллы. В конце курса в случае Advanced трека будут подведены итоги, и вы получите письмо от преподавателя с вашими результатами. Никаких сертификатов и прочего – все знания, что успели ухватить – все ваше.

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

Я решил записаться на 3 курса: Machine Learning, Natural Language Processing и Game Theory. По первому очень хорошие отзывы, да и просто любопытно сравнить с тем, чему нас учили, вторым я немного занимался в университете, а третий просто интересно прослушать – на нашей специальности (ПОАС) теории игр не было, но встречаюсь с ней все чаще. Не уверен, что хватит времени пройти все по Advanced треку, но во-первых, всегда можно перейти на Basic или вообще отказаться, а во-вторых, я думаю начать проходить Machine Learning сейчас с первой группой, включая лабораторные работы, чтобы в январе-марте сэкономить себе время на этом курсе.

В общем, я считаю, что это действительно круто! Дистанционное образование, о котором так долго твердили большевики, становится реальностью. Наверняка в ближайшем будущем еще несколько серьезных университетов разразятся новыми курсами.

PS. Кстати, кому интересно, до середины декабря проходит AI Challenge. В этом году, к сожалению, совсем нет времени участвовать, а жаль.

PPS. Курсы добавляются как грибы после дождя. Появился еще один курс, на этот раз по дизайну и анализу алгоритмов: http://www.algo-class.org/

Tuesday, June 28, 2011

Будущее Silverlight

Очень странно наблюдать поднявшуюся в последний месяц истерию по поводу того, что Microsoft якобы “разочаровался в WPF/Silverlight” и планирует смену курса в сторону набирающего популярность HTML5. Тема вовсю обсуждается на форумах MSDN, в комментариях серьезных блоггеров, на Хабре и даже в твиттере. Несмотря на явную невозможность нативной разработки под Windows при помощи ыHTML5/JS, у этой истерии, безусловно, есть корни. Осенью прошлого года официальные лица Microsoft уже обронили несколько фраз о переосмыслении стратегии развития Silverlight, а в начале июня подлили масла в огонь, показав Windows 8 с возможностью разработки на HTML5/JS и ни словом не обмолвившись о Silverlight. Если погуглить по фразе “Windows 8 silverlight”, то можно найти кучу криков о смерти Silverlight и плач тысяч разработчиков, которые выбрали Silverlight своей основной платформой для разработки и теперь считают себя брошенными на произвол судьбы. Добил фанов технологии .NET Community Manager Pete Brown, который высказался ясно и в то же время очень неопределенно:

“You all saw a very small technology demo of Windows 8, and a brief press release. We’re all being quiet right now because we can’t comment on this. It’s not because we don’t care, aren’t listening, have given up, or are agreeing or disagreeing with you on something. All I can say for now is to please wait until September. If we say more before then, that will be great, but there are no promises (and I’m not aware of any plans) to say more right now. I’m very sorry that there’s nothing else to share at the moment. I know that answer is terrible, but it’s all that we can say right now. Seriously.”

Сентябрь, о котором идет речь – это конференция Build, на которой ожидается релиз Silverlight 5, Windows Phone 7 Mango, а также первые настоящие презентации Windows 8 с объяснениями дальнейшей стратегии компании.

Безусловно, можно подождать еще 2.5 месяца и узнать, какую роль Microsoft отводит для Silverlight в своей новой концепции. Но ждать еще долго, а некоторые решения нужно принимать уже сейчас. Попробуем разобраться сами.

Итак, что у нас есть из не очень хорошего:

  1. Microsoft, безусловно, немного разочарована скоростью распространения Silverlight и его положением на рынке. И хотя процент установки Silverlight в браузерах уже достаточно высок (на данный момент около 75%, http://www.riastats.com/), но он все равно еще недостаточен и не дает технологии стать по-настоящему популярной.
  2. Другая проблема Silverlight – его неполная кроссплатформенность. Поддержка Windows и Mac – это, конечно, где-то 90-95% рынка десктопов (а, может, и больше, если верить http://gs.statcounter.com/#os-ww-monthly-201005-201105), но с точки зрения разработки широкопользовательских веб-приложений остается непокрытым весь Linux’овый зоопарк. Не добавляет очков и слабая поддержка SEO.
  3. На мобильных платформах подержка Silverlight вообще стремится к нулю. Ни iOS, ни Blackberry, ни Android не поддерживают Silverlight и вряд ли будут стремиться к этому. Единственная платформа, где он поддерживается – это WP7, правда, не в браузере. Но доля WP7 на рынке мобильных устройств (http://itc.ua/news/gartner_android_yavlyaetsya_samoj_populyarnoj_os_dlya_smartfonov_53536) и количество заказов на разработку WP7 приложений пока настолько малы, что серьезно раздумывать о карьере разработчика мобильных приложений пока не получается.

В то же время несмотря на все эти недостатки Silverlight уже занял свою определенную нишу, где он очень силен, в первую очередь благодаря скорости разработки и возможностям, недоступным стандартному HTML/JS клиенту:

  1. Enterprise и LOB RIA приложения (нивелируются проблемы слабой кроссплатформенности и распространенности)
  2. веб-приложения, в которых пользователи готовы установить плагин ради получения доступа к продвинутым возможностям, а не уйти к конкурентам (не e-commerce)
  3. мультимедиа-приложения с красивой и сложной анимацией, поддержкой video streaming
  4. кроме того, Silverlight пока остается основной платформой для разработки под Windows Phone 7

С чем же связано то, что Microsoft, вложившая 4 года и миллионы долларов в разработку и продвижение кроссплатформенной .NET-технологии, потихоньку смотрит в сторону HTML5/JS? И что же все-таки будет с Silverlight дальше?

Во-первых, любой компании, которая производит ОС, важно привлекать как можно большее количество разработчиков на свою сторону. Silverlight и WPF требуют от не .NET-разработчиков изучения слишком многого. А возможность сделать пусть и простое, но все же приложение под Windows 8 на HTML5/JS – это шанс. Тем более, что Windows 8 позиционируется и как операционка для планшетов – а это очень перспективный рынок. Уверен на 99%, что в сентябре на Build будет сказано о полной поддержке WPF (а куда ж он денется?), а также Silverlight как минимум на уровне разработки таких же приложений, которые будут разрабатываться на HTML5/JS.

Во-вторых, есть ощущение, что Microsoft пойдет на еще один непопулярный, но очень важный с точки зрения развития своей мобильной платформы шаг – даст возможность разрабатывать нативные приложения на HTML5/JS в Windows Phone. Думаю, начиная с восьмой версии, чтобы поддержать версионирование, но, может, и в Mango (7.5) добавят. Криков о помощи будет еще больше, но Microsoft нужно догонять убегающие iOS и Android. Разработчики мобильных приложений под iOS и Android не торопятся переносить свои приложения под WP7 в том числе и потому, что это требует совсем других навыков. Если бы у Microsoft было хотя бы 40% рынка, они могли бы закрыть глаза на простоту разработки, но с текущими 6% им некуда деваться.

В-третьих, Silverlight никуда не уйдет из web’а в ближайшие 3-5 лет. Его доля будет по-прежнему неуклонно расти, приложения будут разрабатываться, но вот из своей ниши он вряд ли выйдет. Этому будет мешать развитие HTML5 и рост рынка веб-приложений под мобильные устройства. Конечно, Microsoft может попробовать разработать Silverlight-плагины для мобильных операционных систем и браузеров, но это огромные деньги, а эффекта практически не будет.

В поддержку Silverlight на нативном уровне верится еще меньше. Такое возможно лишь на Android, и то лишь благодаря Mono, который и сам находится в непонятном статусе. Еще возможно продвижение Silverlight на Symbian, благо с Nokia есть договор, но какой смысл? Ведь есть готовый WP7, который можно ставить на устройства. На фоне же прогнозов о росте использования мобильных веб-приложений и снижения нативной разработки (это банально намного проще и дешевле!) смысла вкладываться в эту сферу вообще нет.

Ну, и в-четвертых, отдельно стоит сказать пару слов о Silverlight vs. HTML5, вернее даже plugins (Flash/Silverlight) vs. HTML5 (это отдельная фишка: под угрозой HTML5 сейчас объединяются даже ранее враждовавшие разработчики Flash/Flex и Silverlight :)). На эту тему сломано уже очень много копий (почитайте отдельно, если вам интересно), но ясно одно: HTML5 не покрывает всех возможностей Silverlight и Flash/Flex, поэтому их рано списывать со счетов. Кроме того, как все правильно отмечают, плагины пополняются новой функциональностью быстрее, чем развивается HTML и обновляются версии браузеров. Если же отвечать на вопрос: что лучше использовать в качестве клиента в каждый конкретный момент времени, то советую почитать два отличных поста:

Лично я себя намного комфортнее чувствую в разработке обычных ASP.NET MVC приложений, чем Silverlight, но это не значит, что нет приложений, для которых использование Silverlight будет более выгодным или дешевым. Особенно если мы говорим о портировании WPF-приложений в веб.

А вы что думаете по всему этому поводу?

Tuesday, June 21, 2011

Итальянские впечатления – 4. Кухня

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

IMG_0741.1IMG_0859 

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

Паста в Италии считается первым блюдом (!). Привычных нам жидких супов в Италии почти нет, а то, что они называют супом, мы скорее можем назвать пюре. Паста – это общее название макаронных изделий, которые, как правило, подаются с различным соусом. Видов макарон в Италии очень много: кроме привычных нам maccheroni, vermicelli и spaghetti, есть еще пара десятков неизвестных bigoli, tagliatelli, tortiglioni, penne, fusilli, flocchi, fertalle, lasagne, raviolli, gnocci и т.д. Немного больше об итальянской пасте можно почитать в вики. Паста очень вкусная, но здесь важно подобрать подходящий соус. Мы пару раз ошибались. К пасте почти всегда подают тертый пармезан в отдельной посуде.

Основные блюда сильно зависят от региона. В Тоскане, например, больше мясной кухни, в Венеции и других “морских” городах – морепродуктов.

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

Итальянская кухня, несмотря на обилие мучных и мясных блюд, самих итальянцев не полнит. Вот уж не знаю, что является основной причиной этого: способы приготовления блюд, многовековая привычка, обилие овощей, спортивный образ жизни или чисто психологические факторы, например, почти безстрессовая жизнь и постоянное проживание среди предметов искусства. В любом случае, встретить полного итальянца или итальянку довольно сложно, даже пожилые люди выглядят спортивно и подтянуто.

Итальянцы употребляют много вина. Иногда даже кажется, что итальянцы ходят в кафе и рестораны просто попить вина и пообщаться с друзьями, перехватив пиццу-другую лишь для закуски. Пива сравнительно мало. На улицах алкоголь не употребляют, как и везде в Европе.

Ну, и напоследок о сладостях. Мы перепробовали большое количество “итальянского” мороженого (продается шариками), которое на удивление стоит дешевле, чем у нас. В основном очень вкусно. Также пробовали несколько пирожных и традиционные сиенские сладости.

На этом итальянская серия заканчивается и начинаем снова писать серьезные вещи :)

Sunday, June 19, 2011

Итальянские впечатления – 3. Венеция

После недели в Тоскане у нас еще оставалось неполных 2 дня на то, чтобы познакомиться с Венецией. Я поначалу был настроен очень скептически по отношению к этому городу. Венецию называют самым романтическим городом мира, но в нем также слишком много проблем. Здания потихоньку уходят под воду, морская соль разъедает архитектурные памятники, есть проблемы с качеством воды в каналах, недвижимость дорожает, что приводит к тому, что все больше венецианцев переселяется на материк. В общем, город потихоньку умирает.

Однако реальность оказалась все-таки не такой страшной. Несмотря на все эти проблемы город просто невероятно красив. У Венеции очень богатая история, и в наследство от предков современным венецианцам досталась восхитительная архитектура, уйма достопримечательностей и красочные традиции.

IMG_0982IMG_0968IMG_1041

Венецианская республика была одной из самых сильных морских и торговых держав Средневековья. Ее островное местоположение давало ей защиту от экспансии с суши, а со штапелей судостроительных верфей каждый день спускался на воду новый торговый или военный корабль. Венеция славно поживилась в IV Крестовом походе, когда в хитростью направила усилия крестоносцев на православную Византию с целью возврата власти свергнутому императору Исааку II Ангелу. В результате похода республике отошло больше трети территории бывшей Византийской империи, власть в Константинопольской гавани, торговая монополия на территории свежесозданной на руинах Византии Латинской империи, а также огромное количество богатств и предметов искусства, которые были вывезены в Венецию после разграбления Византии. Такой вот ход конем. Венецианская республика (которая на деле была аристократическим государством), по сути сидела между западом и востоком, зарабатывая на этом. Торговля и промышленность процветали, а народ постоянно богател. Однако это было начало конца.

Уничтожив Византию, которая защищала Европу от мусульманского Востока, Венеции пришлось самой столкнуться с турецкой экспансией после падения Константинополя в 1453 году. Европейские страны стали искать другие торговые пути и нашли их, открыв морской путь в Ост-Индию, а также заодно Америку. Великие географические открытия сместили акцент торговли в сторону Атлантики и Индийского океана, а постоянные войны с Османской империей ослабили республику. За два века османы отняли у Венеции значительную часть ее владений. Добил Венецию Бонапарт, захватив ее без сопротивления в 1797 году и уничтожив республику.

IMG_0857IMG_1136IMG_0983

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

Сердце города, без сомнения – площадь Сан-Марко, наверно, самое “голубиное” место Европы. Почти каждый турист считает своим долгом покормить здесь голубей (которых тут просто дофига) и сфотографироваться с ними. В остальном же площадь, хоть и красива, но слишком многолюдна.

IMG_0817IMG_0822

На площади находится без преувеличения один из красивейших соборов Европы – Собор Святого Марка. Собор назван в честь апостола Марка, мощи которого были тайно вывезены из Александрии венецианскими купцами. Внутри Собор смотрится очень красиво и наверно даже слишком богато. Глаза разбегаются, чтобы осмотреть мозаики на стенах и куполах, иконы, колонны, порталы и ниши. Преобладают желтые (даже золотые) и голубые цвета. Вход в алтарную зону, Сокровищницу и некоторые другие места платный.

IMG_0809IMG_0903IMG_0917

Рядом с Собором находится Дворец Дожей – шедевр итальянской готической архитектуры, в котором отчетливо видно влияние Востока – стрельчатые окна и арки. Мы не заходили внутрь из-за недостаточного количества времени, предпочтя этому прогулку по городу.

IMG_0811IMG_0815

Гулять по центру Венеции не очень интересно. Здесь одни туристические лавки, рестораны, отели, модные бутики и негры, продающие поддельные сумки Гуччи, Версаче и Дольче Габбана, а также яркие безделушки. Половина туристических лавок продают бесподобные изделия из муранского стекла, которые очень хочется привезти к себе домой, но меня все равно не покидал вопрос: зачем их так много?!

IMG_0802IMG_0804IMG_1045

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

IMG_1134IMG_0959IMG_1147 

Если же говорить о других местах, которые следует посетить, я бы посоветовал обязательно прогуляться к Арсеналу, бывшей морской верфи и нынешней базе ВМФ (район Кастелло), а также посетить районы Дорсодуро, откуда открывается отличный вид на центр города, и Сан-Поло, переходящий в Санта-Кроче, увидев по пути Академию, собор Санта-Мария-делла-Салюте, а также мосты Академии и Риальто. Там намного интереснее, чем гулять между витринами магазинов и бутиков на Сан-Марко. Нам даже повезло найти небольшую мастерскую по производству гондол – это на самом деле кусок истории города. Еще в Венеции есть музей Морского флота, и я очень жалею, что у нас не хватило времени его посетить.

 IMG_0841IMG_0990IMG_0993IMG_1023

И самое главное – не забудьте прокатиться на гондоле вапоретто по Гранд-Каналу! Вапоретто – это венецианский морской трамвай, единственный вид общественного транспорта в островной Венеции, где нет и намека на автомобили или автобусы. На один из маршрутов можно сесть на площади Сан-Марко и доехать до ж/д вокзала и Пьяццале Рома (автобусная станция), или наоборот. Вапоретто двигается медленно, останавлиясь по очереди на каждом берегу канала, давая возможность рассмотреть дворцы и мосты с таких ракурсов, которые недоступны с берега. Поездка занимает около часа. Насчет гондол – решайте сами. Удовольствие стоит 100 евро за 40 минут, в гондолу может сесть 5-6 человек. У нас не было компании, и мы посчитали, что 100 евро на семью – оно того не стоит.

IMG_1079IMG_1081IMG_1068

В общем, пребывание в городе оказалось намного более интересным и увлекательным, чем я мог предположить. Главное – уходить от центра и пытаться найти настоящую Венецию. Другие фотографии из Венеции находятся здесь.