<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Arquitetura em Pauta</title><subtitle type="html" /><id>http://blogs.msdn.com/otavio/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/otavio/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2009-07-29T19:25:58Z</updated><entry><title>Private Class ResumoPDC</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/11/21/private-class-resumopdc.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/11/21/private-class-resumopdc.aspx</id><published>2009-11-21T20:16:11Z</published><updated>2009-11-21T20:16:11Z</updated><content type="html">&lt;p&gt;1 semana de férias + 1 semana de PDC + rede lenta no hotel = -posts&lt;/p&gt;  &lt;p&gt;Então não devo ter notícias novas para vocês. &lt;a href="http://blogs.msdn.com/wcamb/default.aspx"&gt;Waldemir&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/conde/"&gt;Condé&lt;/a&gt;, &lt;a href="http://unplugged.giggio.net/default.aspx"&gt;Giovanni&lt;/a&gt; e &lt;a href="http://blogs.msdn.com/rogerioc/"&gt;Rogério&lt;/a&gt; falaram boa parte das novidades. Vou ficar com o que ficou de mais importante na minha memória:&lt;/p&gt;  &lt;p&gt;1) , é claro, a entrada do Azure no ar para valer em fevereiro;&lt;/p&gt;  &lt;p&gt;2) Tudo que tem de novo nesta última versão do Azure: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;a) A API de monitoração (&lt;a href="http://code.msdn.microsoft.com/windowsazuremmc"&gt;http://code.msdn.microsoft.com/windowsazuremmc&lt;/a&gt; ) onde você pode agora pegar o Log do IIS, eventos do Windows, iniciar/remover instâncias de roles do Azure, enfim, tudo para você começar a identificar quando aumentar ou diminuir o número de processos no Azure (elasticidade);&lt;/p&gt;    &lt;p&gt;b) Agora você define novos tipos de workers. Você cria endpoints e pode usar o WCF para a comunicação entre eles, o que implica em migração mais fácil para quem tem aplicativos multicamadas usando o WCF;&lt;/p&gt;    &lt;p&gt;c) Existe agora a noção de update domains: conjunto de workers que serão atualizados em conjunto. Com isto, podemos atualizar um update domain e testá-lo antes de atualizar os demais, garantindo uma instalação mais suave e controlável. Além disto, podemos pedir a atualização de um tipo de worker – nada de ter que baixar/levantar todo o conjunto de workers por causa de um oatch simples;&lt;/p&gt;    &lt;p&gt;d) O PinPoint: um Market Place para mostrar seus produtos que rodam no Azure para seus futuros clientes (ver &lt;a href="http://pinpoint.microsoft.com/en-US/"&gt;http://pinpoint.microsoft.com/en-US/&lt;/a&gt; );&lt;/p&gt;    &lt;p&gt;e) O Windows Azure Content Delivery Network (CDN), isto é, um cache global distribuido em 18 países que você pode usar para colocar imagens usadas no seu site do Azure (veja &lt;a href="http://blog.smarx.com/posts/using-the-new-windows-azure-cdn-with-a-custom-domain"&gt;http://blog.smarx.com/posts/using-the-new-windows-azure-cdn-with-a-custom-domain&lt;/a&gt;);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;3) Tudo que está para vir no Azure&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;a) O SQL Azure Data Sync: para sincronizar um ou mais bancos com o SQL Azure (mesmo o SQL Compact) (ver em &lt;a href="http://www.microsoft.com/windowsazure/developers/sqlazure/datasync/"&gt;http://www.microsoft.com/windowsazure/developers/sqlazure/datasync/&lt;/a&gt;);&lt;/p&gt;    &lt;p&gt;b) O Projeto Dallas: serviços de dados da Nasa e outros que você pode incorporar no seu aplicativo (ver em &lt;a href="http://www.microsoft.com/windowsazure/developers/dallas/"&gt;http://www.microsoft.com/windowsazure/developers/dallas/&lt;/a&gt;);&lt;/p&gt;    &lt;p&gt;c) A promessa de novos tamanhos limites para o SQL Azure;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;4) A palestra do Erik Meijer sobre o Reactive Extension (&lt;a title="http://blogs.msdn.com/somasegar/archive/2009/11/18/reactive-extensions-for-net-rx.aspx" href="http://blogs.msdn.com/somasegar/archive/2009/11/18/reactive-extensions-for-net-rx.aspx"&gt;http://blogs.msdn.com/somasegar/archive/2009/11/18/reactive-extensions-for-net-rx.aspx&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20321.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="san francisco 321" border="0" alt="san francisco 321" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20321_thumb.jpg" width="244" height="184" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4) O Silverlight 4 chegando e fazendo drag and drop entre aplicativos no Windows e o aplicativo Silverlight no Browser (&lt;a title="http://silverlight.net/" href="http://silverlight.net/"&gt;http://silverlight.net/&lt;/a&gt; );&lt;/p&gt;  &lt;p&gt;5) O RIA Services, levando o Silverlight para tratar aplicativos multicamadas e usando agora o WCF para levar queries Linq do cliente para o servidor, e dados em ambas as direções (ver &lt;a title="http://blogs.msdn.com/brada/archive/2009/11/19/pdc09-talk-building-amazing-business-applications-with-silverlight-4-ria-services-and-visual-studio-2010.aspx" href="http://blogs.msdn.com/brada/archive/2009/11/19/pdc09-talk-building-amazing-business-applications-with-silverlight-4-ria-services-and-visual-studio-2010.aspx"&gt;http://blogs.msdn.com/brada/archive/2009/11/19/pdc09-talk-building-amazing-business-applications-with-silverlight-4-ria-services-and-visual-studio-2010.aspx&lt;/a&gt;);&lt;/p&gt;  &lt;p&gt;6) O Container do Azure que estava a mostra:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20287.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="" border="0" alt="" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20287_thumb.jpg" width="244" height="184" /&gt;&lt;/a&gt; &lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20288.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="" border="0" alt="" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20288_thumb.jpg" width="184" height="244" /&gt;&lt;/a&gt; &lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20286.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="" border="0" alt="" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PrivateClassResumoPDC_FBF8/san%20francisco%20286_thumb.jpg" width="184" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Tem muito material para ser visto.&lt;/p&gt;  &lt;p&gt;Vale uma olhada nos vídeos do PDC em &lt;a href="http://microsoftpdc.com/Videos"&gt;http://microsoftpdc.com/Videos&lt;/a&gt; (os do Azure estão listados em &lt;a href="http://blogs.msdn.com/jnak/archive/2009/11/19/videos-of-the-windows-azure-sessions-at-pdc09.aspx"&gt;http://blogs.msdn.com/jnak/archive/2009/11/19/videos-of-the-windows-azure-sessions-at-pdc09.aspx&lt;/a&gt; )&lt;/p&gt;  &lt;p&gt;Os treinamentos no &lt;a href="http://channel9.msdn.com/learn/courses/Azure/"&gt;http://channel9.msdn.com/learn/courses/Azure/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;...e , claro, as últimas Ferramentas e SDK em &lt;a href="http://www.microsoft.com/windowsazure/tools/"&gt;http://www.microsoft.com/windowsazure/tools/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Abraços&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9926804" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Azure" scheme="http://blogs.msdn.com/otavio/archive/tags/Azure/default.aspx" /><category term="Silverlight" scheme="http://blogs.msdn.com/otavio/archive/tags/Silverlight/default.aspx" /></entry><entry><title>Faça seu Gerador de Código com o T4 do Visual Studio</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/10/31/fa-a-seu-gerador-de-c-digo-com-o-t4-do-visual-studio.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/10/31/fa-a-seu-gerador-de-c-digo-com-o-t4-do-visual-studio.aspx</id><published>2009-10-31T21:51:01Z</published><updated>2009-10-31T21:51:01Z</updated><content type="html">&lt;p&gt;Tenho visto poucos arquitetos utilizando uma tecnologia interessante para gerar código de acordo com templates e que já está embutida no Visual Studio, sejam 2005, 2008 ou 2010.&lt;/p&gt;  &lt;p&gt;Trata-se do &lt;a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx"&gt;T4 (Text Template Transformation Toolkit)&lt;/a&gt; Code Generation. Ele está contido no &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=59ec6ec3-4273-48a3-ba25-dc925a45584d"&gt;Visual Studio SDK&lt;/a&gt; e pode ser usado para gerar um código de acordo com um template que você ou seu time escreve. &lt;/p&gt;  &lt;p&gt;Pense nele como a metade de uma infraestrutura para um gerador de código.&lt;/p&gt;  &lt;p&gt;Um gerador completo costuma ter duas partes: a primeira é a responsável pela leitura dos metadados de uma especificação ou modelo; a segunda é a que lê estes metadados e gera algum artefato (código, html, etc.) a partir destes.&lt;/p&gt;  &lt;p&gt;O &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=59ec6ec3-4273-48a3-ba25-dc925a45584d"&gt;Visual Studio SDK&lt;/a&gt; já vem com o &lt;a href="http://msdn.microsoft.com/en-us/library/bb126259.aspx"&gt;Domain Specific Language Tools&lt;/a&gt; onde você pode especificar uma DSL visual (o &lt;a href="http://blogs.msdn.com/Hulot/"&gt;Carlos Hulot&lt;/a&gt; falou muito disto no seu blog) e utilizar dentro dos templates T4 um conjunto de classes que permitem ler estes metadados para gerar o código correspondente. &lt;/p&gt;  &lt;p&gt;Mas o DSL do SDK é um pouco complexo e você pode precisar de algo bem mais simples. Saiba que você pode construir seu próprio parser ou mero formulário para dar a entrada dos metadados que o template T4 usará para gerar seu código. Por exemplo, você pode fazer uma biblioteca para ler os metadados de um banco de dados e colocá-los a disposição para o template T4 percorrê-los gerando, por exemplo, classes com seus campos - como o Entity Framework faz.&lt;/p&gt;  &lt;p&gt;Como exemplo, veja a figura abaixo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/FaaseuGeradordeCdigocomoT4doVisualStudio_11709/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/FaaseuGeradordeCdigocomoT4doVisualStudio_11709/image_thumb.png" width="723" height="488" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Nela, você pode ver código que será rodado pelo template para gerar código (ele está sempre entre &amp;lt;# #&amp;gt; ). Em especial, o código no bloco que começa com &amp;lt;#+ é uma função de ajuda que retirar espaços de dentro de strings e é utilizado no bloco logo abaixo para gerar strings do nome de cidades sem espaços. Textos fora dos blocos &amp;lt;# #&amp;gt; são copiados diretamente para o arquivo de saída.&lt;/p&gt;  &lt;p&gt;Quando abrimos o arquivo gerado (genclass.cc) deste exemplo encontramos o seguinte texto:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="2" face="Courier New"&gt;Cidades sem &amp;quot; &amp;quot; entre nomes        &lt;br /&gt;NewYork         &lt;br /&gt;London         &lt;br /&gt;Seattle         &lt;br /&gt;SanFrancisco         &lt;br /&gt;NewDelhi&lt;/font&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Simples, não é?&lt;/p&gt;  &lt;p&gt;Existe um post ótimo do &lt;a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx"&gt;Scott Hanselmann&lt;/a&gt; que dá vários links interessantes sobre o assunto.&lt;/p&gt;  &lt;p&gt;Fica a dica: se você está querendo trabalhar com MDD e pensa em fazer seu próprio gerador, dê uma olhada no T4!&lt;/p&gt;  &lt;p&gt;Abraços &lt;/p&gt;  &lt;p&gt;(Dica 2: pense no Oslo como o parser e o T4 como gerador)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9915732" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Customiza&amp;#231;&amp;#227;o" scheme="http://blogs.msdn.com/otavio/archive/tags/Customiza_26002300_231_3B0026002300_227_3B00_o/default.aspx" /><category term="DSL" scheme="http://blogs.msdn.com/otavio/archive/tags/DSL/default.aspx" /></entry><entry><title>Quando usar o Azure?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/10/21/quando-usar-o-azure.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/10/21/quando-usar-o-azure.aspx</id><published>2009-10-21T15:53:30Z</published><updated>2009-10-21T15:53:30Z</updated><content type="html">&lt;p&gt;Existem dois tipos de respostas aqui: uma que visa o diferencial do aplicativo do ponto de vista Controle X Custo, já abordado em &lt;a title="http://msdn.microsoft.com/pt-br/azure/dd638038.aspx" href="http://msdn.microsoft.com/pt-br/azure/dd638038.aspx"&gt;http://msdn.microsoft.com/pt-br/azure/dd638038.aspx&lt;/a&gt;; outra que visa a adequação tecnológica no uso do Azure . Hoje vou tratar da segunda.&lt;/p&gt;  &lt;p&gt;Em minha opinião, nem todo tipo de arquitetura de aplicativo é susceptível de ir para o Azure, seja por impossibilidade técnica atual, seja por custo. &lt;/p&gt;  &lt;p&gt;Para ficar mais claro qual tipo de arquitetura eu creio ser viável no Azure, criei o seguinte quadro:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb.png" width="347" height="251" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Para tornar mais claro, vamos tratar de cada caso:&lt;/p&gt;  &lt;p&gt;1) Web 2.0 (Privado/Público): imagine cenários que precisam compartilhar um volume muito grande de dados não transacionais, podendo ter que escalar eventualmente para milhares ou mesmo milhões de usuários. Pense em Facebook, Youtube, sites de blogs, sites de notícias, etc. Neste caso você vai poder usar o Azure em todo seu potencial, utilizando a elasticidade de processamento e storage (Azure Tables), armazenando tudo num volume virtualmente infinito de recursos. Estes é um dos cenários mais favoráveis para o Azure!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_1.png" width="209" height="140" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2) SaaS (Privado/Público): imagine fazer um aplicativo para ser vendido para milhares ou mesmo milhões de clientes, cada um utilizando seus dados de forma exclusiva, tendo um máximo de 10G de banco SQL (limitação atual do SQL Azure), mas podendo guardar em Blobs e Tables do Azure um volume virtualmente infinito de documentos, fotos, vídeos, etc – o que diminui consideravelmente a limitação de volume máximo do banco. Imagine poder crescer/decrescer o número de clientes de acordo com a sazonalidade sem custo de compras ou ociosidade de recursos. Este é também um cenário para o Azure.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_2.png" width="198" height="214" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3) High Performance Computing: imagine um aplicativo que precise de um alto grau de processamento paralelo, para criar animações de filmes, analisar proteínas, construir plataformas de petróleo, etc, utilisando algoritmos como &lt;a href="http://blogs.msdn.com/otavio/archive/2009/09/12/mapreduce-no-windows-azure.aspx"&gt;MapReduce&lt;/a&gt;. Se não houver impeditivo na carga/descarga de dados a serem trabalhados (devido à latência ou volume), o Azure pode ser utilizado para a infraestrutura deste aplicativo, com a vantagem de você só alocar os servidores quando realmente necessitar rodar o processamento. Por que só bom? Ainda não existe framework MapReduce pronto, você terá que fazer o seu. Outra questão é o eventual volume de dados para ser carregado para uma análise.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_3.png" width="213" height="176" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4) Small/Medium Transaction Processing: se você tem um aplicativo para empresas pequenas e/ou médias, ou mesmo aplicativos departamentais, provavelmente você poderá usar o SQL Azure de 1G ou 10G, migrando o seu aplicativo para o Azure. Lembre-se que fotos, documentos e outros podem migrar do Banco para Tables e Blobs, pois isto diminui o risco do limite do SQL ser atingido. Por que só bom? O limite atual de 10 Gb pode ser um impeditivo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_4.png" width="117" height="102" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;5) Remote SQL: você pode utilizar o SQL remotamente, ganhando latência (o que é ruim), mas conseguindo tanto um custo pequeno quanto a possibilidade de compartilhar os dados com outras empresas, sites, etc. Porque não deixar a lista de produtos e preços da sua empresa disponível para terceiros? (leitura somente, é claro!). Por que só bom? A latência da Internet pode ser um impeditivo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_5.png" width="343" height="216" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;6) Internet Service Bus: se você precisa da comunicação com aplicativos externos à sua rede, eventualmente de terceiros, o Internet Service Bus é uma infraestrutura interessante. Ele permite a troca de mensagens com autenticação federada, diminuindo o custo de infraestrutura e gerenciamento de um EDI. Por que só bom? Latência, de novo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_14.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_6.png" width="317" height="256" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;7) Mistos: imagine uma loja online, onde pedidos são feitos pelo site no Azure (com lista de produtos no SQL Azure e fotos dos produtos nos blobs) e em que toda a infraestrutura de pagamento e entrega está na sua empresa, ou na empresa de terceiros. Neste caso, você poderá complementar sua loja online, que habita no Azure, com os demais sistemas de logística, meios de pagamentos, etc, utilizando o Internet Service Bus como mecanismo de troca de mensagens confiável. Este e muitos outros cenários podem utilizar o melhor de cada tipo de ambiente (nuvem, dispositivos, sistemas internos ou de terceiros), realizando uma verdadeira arquitetura Software+Serviços. Por que só bom? Latência e limite de SQL Azure…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_16.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_7.png" width="346" height="218" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Por fim, dois cenários, ao meu ver, não parecem ser convenientes para o Azure atualmente:&lt;/p&gt;  &lt;p&gt;1) eXtreme Transaction Processing: que necessitam de Base de Dados muito grandes e que não pode ser resolvido com particionamento (&lt;a href="http://blogs.msdn.com/otavio/archive/2009/10/17/padr-es-para-cloud-computing-no-azure-particionamento-com-o-sql-azure-sharding.aspx"&gt;vide post&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_18.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_8.png" width="240" height="180" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2) Sites HTMLs puros: neste caso, você até pode colocar o site no Azure, mas como você não estará compartilhando o IIS com outros usuários, o custo, potencialmente, será desvantajoso com o que praticado por hosters do mercado. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_20.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/QuandousaroAzure_C31B/image_thumb_9.png" width="37" height="56" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Esta é a minha análise dentro da situação atual. Você concorda?&lt;/p&gt;  &lt;p&gt;Abraços&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9910673" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author></entry><entry><title>Padrões para Cloud Computing no Azure – Particionamento com o SQL Azure (Sharding)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/10/17/padr-es-para-cloud-computing-no-azure-particionamento-com-o-sql-azure-sharding.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/10/17/padr-es-para-cloud-computing-no-azure-particionamento-com-o-sql-azure-sharding.aspx</id><published>2009-10-17T15:22:00Z</published><updated>2009-10-17T15:22:00Z</updated><content type="html">&lt;P&gt;O interessante da computação em sistemas elásticos, como o &lt;A href="http://www.microsoft.com/windowsazure/" mce_href="http://www.microsoft.com/windowsazure/"&gt;Azure&lt;/A&gt;, é que eles tornam factíveis padrões computacionais que costumam ser caros para as empresas.&lt;/P&gt;
&lt;P&gt;É claro que podemos utilizar o Azure para migrar sistemas convencionais de nossas empresas (como sistemas departamentais ou algum outro sistema LOB), tentando minimizar o custo total da nossa TI. Mas tudo fica mais divertido – e potencialmente lucrativo - quando pensamos nas oportunidades para modelos computacionais que lidam com uma massa grande de dados ou de computação. E, para compreender isto, vale descrever alguns padrões recorrentes nestes tipos de problemas.&lt;/P&gt;
&lt;P&gt;Imagine milhões de usuários visitando o seu site. Que padrões você pode utilizar para viabilizar tamanho número de acessos?&lt;/P&gt;
&lt;P&gt;Imagine um cálculo que pode levar milhões de MIPS. Tenho padrões similares?&lt;/P&gt;
&lt;P&gt;A resposta a estas perguntas costuma ser um grupo de padrões recorrentes. São eles:&lt;/P&gt;
&lt;P&gt;1) &lt;STRONG&gt;Replicação&lt;/STRONG&gt;: que se caracteriza pelo uso de uma estrutura repetitiva de computação e/ou armazenamento – o que proporciona a elasticidade pelo simples aumento ou diminuição desta “célula de computação”. &lt;/P&gt;
&lt;P&gt;Neste caso temos dois sub-padrões comuns:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;a. Sites convencionais compostos de WebFarms + storage: onde repetimos o mesmo código para cada servidor Web (web role, em bom &lt;I&gt;azurês&lt;/I&gt;) e colocamos os mesmos dados de leitura copiados (em memória cachê ou cópia em storages (Azure Tables, em bom azurês));&lt;/P&gt;
&lt;P&gt;b. Sites SaaS: onde repetimos a estrutura de cada célula (servidores+storage) onde, porém, tanto a estrutura de storage quanto a de código podem ser ligeiramente diferentes para cada usuário/inquilino, devido a customizações e/ou dados exclusivos;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;2) &lt;STRONG&gt;Particionamento&lt;/STRONG&gt;: que se caracteriza pela subdivisão da computação ou armazenamento com fins de distribuir as demandas para subsistemas diferentes, aliviando subsistemas e evitando potenciais gargalos.&lt;/P&gt;
&lt;P&gt;Os sub-padrões seriam:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;a. &lt;A href="http://en.wikipedia.org/wiki/Grid_computing" mce_href="http://en.wikipedia.org/wiki/Grid_computing"&gt;Grid&lt;/A&gt;: sites que trabalham com algoritmos de alto paralelismo, com a distribuição de subconjuntos (normalmente distintos) de dados para cada servidor, como acontece no MapReduce (&lt;A href="http://blogs.msdn.com/otavio/archive/2009/09/12/mapreduce-no-windows-azure.aspx" mce_href="http://blogs.msdn.com/otavio/archive/2009/09/12/mapreduce-no-windows-azure.aspx"&gt;ver post&lt;/A&gt;) ou processamentos em &lt;I&gt;&lt;A href="http://en.wikipedia.org/wiki/Pipeline_(computing)" mce_href="http://en.wikipedia.org/wiki/Pipeline_(computing)"&gt;pipeline&lt;/A&gt;&lt;/I&gt;;&lt;/P&gt;
&lt;P&gt;b. Sites que&amp;nbsp;possam ser particionados em&amp;nbsp;subsistemas distintos, como Vendas, Cobrança e Logística numa loja virtual, onde cada subsistema tem código e dados distintos, referentes à cada passo do processo de compra e entrega de um pedido, e cada sub-sistema se comunica com o outro por redirecionamento, compartilhamento de dados e/ou envio de mensagens (filas, em azurês);&lt;/P&gt;
&lt;P&gt;c. &lt;A href="http://en.wikipedia.org/wiki/Sharding" mce_href="http://en.wikipedia.org/wiki/Sharding"&gt;Sharding&lt;/A&gt;: O particionamento de dados em storages diferentes, visando distribuir estatisticamente o acesso aos dados e, assim, diminuir o tempo de espera médio para uma escrita ou leitura. Tables do Azure, por exemplo, têm este comportamento por natureza/construção;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;3) &lt;STRONG&gt;Misto&lt;/STRONG&gt;: o mais comum, onde padrões de replicação e particionamento são utilizados em conjunto formando arquiteturas complexas.&lt;/P&gt;
&lt;P&gt;O SQL Azure, em particular, nasce um pouco limitado devido à sua condição ACID (&lt;A href="http://blogs.msdn.com/otavio/archive/2008/11/22/acid-x-base.aspx" mce_href="http://blogs.msdn.com/otavio/archive/2008/11/22/acid-x-base.aspx"&gt;ver post&lt;/A&gt;). Porém isto não impede de você utilizar algumas destas estratégias visando arquiteturas para milhões de usuários. As estratégias possíveis são:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;a) SaaS: um banco de dados para cada inquilino ou pequeno grupo de inquilino (ver 1.b acima);&lt;/P&gt;
&lt;P&gt;b) Subsistemas distintos: um banco de dados para cada subsistema (ver 2.b acima);&lt;/P&gt;
&lt;P&gt;c) Particionamento: um banco de dados para cada subconjunto de dados (ver 2.c acima);&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Como o SQL Azure, ao contrário do MS SQL não tem infra-estrutura interna para particionamento, caberá a você construir uma :( &lt;/P&gt;
&lt;P&gt;A boa nova é que o &lt;I&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=413E88F8-5966-4A83-B309-53B7B77EDF78&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=413E88F8-5966-4A83-B309-53B7B77EDF78&amp;amp;displaylang=en"&gt;Windows Azure Platform Training Kit de outubro&lt;/A&gt;&lt;/I&gt; traz um lab com um código exemplo que implementa o particionamento com o SQL Azure usando o &lt;I&gt;&lt;A href="http://en.wikipedia.org/wiki/Sharding" mce_href="http://en.wikipedia.org/wiki/Sharding"&gt;sharding&lt;/A&gt;&lt;/I&gt;.&lt;/P&gt;
&lt;P&gt;Aos estudiosos, vale a pena baixar o Kit e ir direto para a Demo “&lt;I&gt;Scaling Out SQL Azure with Database Sharding&lt;/I&gt;” e dar uma olhada.&lt;/P&gt;
&lt;P&gt;Abraços&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908571" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Paralelismo" scheme="http://blogs.msdn.com/otavio/archive/tags/Paralelismo/default.aspx" /><category term="cloud computing" scheme="http://blogs.msdn.com/otavio/archive/tags/cloud+computing/default.aspx" /><category term="Azure" scheme="http://blogs.msdn.com/otavio/archive/tags/Azure/default.aspx" /></entry><entry><title>Arquitetura de Software – Boas Referências</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/10/15/arquitetura-de-software-boas-refer-ncias.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/10/15/arquitetura-de-software-boas-refer-ncias.aspx</id><published>2009-10-15T13:46:01Z</published><updated>2009-10-15T13:46:01Z</updated><content type="html">&lt;p&gt;Há muito venho recebendo pedidos de referências para o estudo e formação em arquitetura de software e soluções. Como este é um campo muito novo (cerca de 20 anos) poucos são os livros e artigos que consolidam as práticas mais atuais de uma forma estruturada, com linguagem simples, direta e com conteúdo atualizado.&lt;/p&gt;  &lt;p&gt;A boa notícia é que tenho duas referências que creio serão muito úteis para todos nós. &lt;/p&gt;  &lt;p&gt;A primeira referência é o livro &lt;b&gt;&lt;a href="http://www.amazon.com/gp/product/0470167742/ref=ox_ya_oh_product#noop"&gt;Software Architecture: Foundations, Theory, and Practice&lt;/a&gt;&lt;/b&gt;. Este talvez seja um dos melhores livros que já li sobre o tema. Tem uma excelente cobertura do assunto, abordando práticas reais e mais ágeis de fazer arquitetura. Ele aborda temas atuais, como &lt;i&gt;Domain Specific Software Architectures&lt;/i&gt;, tratando de assuntos que vão do básico “o que é arquitetura de software?“ até considerações de design, modelagem, análise, implementação e implantação. Um excelente livro para iniciantes. Um livro para os profissionais revisitarem seus conhecimentos que, dado a novidade do campo, foram muitas vezes adquiridos de forma empírica através de acertos e erros em projetos reais.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/ArquiteturadeSoftwareBoasReferncias_9762/51hsJUa7JxL__BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01__2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="51hsJUa7JxL__BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_" border="0" alt="51hsJUa7JxL__BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/ArquiteturadeSoftwareBoasReferncias_9762/51hsJUa7JxL__BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01__thumb.jpg" width="175" height="214" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;A minha segunda referência é o &lt;a href="http://cid-ac0dc53ca97927a5.skydrive.live.com/browse.aspx/ebookAS"&gt;e-book do Waldemir Cambiucci&lt;/a&gt;, nosso colega de blog de arquitetura aqui do time de arquitetura da Microsoft Brasil. Ele consolidou e reestruturou um conjunto grande de posts do &lt;a href="http://blogs.msdn.com/wcamb/default.aspx"&gt;seu blog&lt;/a&gt; em um e-book que pode ser usado como uma referência atual das abordagens de arquitetura de software utilizando as tecnologias da Microsoft. Waldemir é um incansável estudioso e escritor de posts, e aproveita cada projeto, cada preparação, para também divulgar o que está sendo experimentado e aprendido.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://cid-ac0dc53ca97927a5.skydrive.live.com/browse.aspx/ebookAS"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image1" border="0" alt="image1" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/ArquiteturadeSoftwareBoasReferncias_9762/image1_3.png" width="171" height="221" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Boa leitura!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9907666" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Arquitetura" scheme="http://blogs.msdn.com/otavio/archive/tags/Arquitetura/default.aspx" /><category term="Ci&amp;#234;ncia da Computa&amp;#231;&amp;#227;o" scheme="http://blogs.msdn.com/otavio/archive/tags/Ci_26002300_234_3B00_ncia+da+Computa_26002300_231_3B0026002300_227_3B00_o/default.aspx" /></entry><entry><title>Linguagens Funcionais, Internet Service Bus, SQL Azure e Windows Indentity Foundation</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/10/08/linguagens-funcionais-internet-service-bus-sql-azure-e-windows-indentity-foundation.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/10/08/linguagens-funcionais-internet-service-bus-sql-azure-e-windows-indentity-foundation.aspx</id><published>2009-10-08T21:32:19Z</published><updated>2009-10-08T21:32:19Z</updated><content type="html">&lt;p&gt;Com o feriado chegando sempre vale algumas recomendações (referentes a arquitetura de software) para as horas vagas.&lt;/p&gt;  &lt;p&gt;1) Que tal melhorar seu conhecimento no uso de linguagens funcionais e alguns padrões de código úteis para construir melhores bibliotecas, frameworks, etc. Minhas sugestões são:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;a. O artigo &lt;i&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/ee309512.aspx"&gt;Functional Programming for Everyday .Net Development&lt;/a&gt;&lt;/i&gt;. Este artigo vai mostrar alguns padrões e princípios interessantes como &lt;i&gt;essência/cerimônia&lt;/i&gt;, &lt;i&gt;Princípio da Segregação de Interfaces&lt;/i&gt; e outros, ilustrando tudo com &lt;i&gt;lambda expressions&lt;/i&gt; em C#. São conhecimentos e truques que podem ser úteis na sua próxima biblioteca;&lt;/p&gt;    &lt;p&gt;b. Motivado com o uso de expressões funcionais? Por que não continuar com as duas primeiras aulas do Erik Meijer (um dos autores do Linq) sobre os fundamentos da programação funcional? Você encontra &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1/"&gt;aqui a primeira aula&lt;/a&gt;, e &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-2/"&gt;aqui a segunda&lt;/a&gt;. Imperdível!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;2) Que tal colocar seu conhecimento de ISB em dia lendo uma série de 3 artigos do Juval Loy sobre Azure Services? Este talvez seja o futuro do EDI... será? Você pode achá-los em &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd569756.aspx"&gt;1&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd942847.aspx"&gt;2&lt;/a&gt; e &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee335696.aspx"&gt;3&lt;/a&gt;;&lt;/p&gt;  &lt;p&gt;3) Se você já se cadastrou no SQL Azure no sql.azure.com, talvez valha apena baixar o SQL Azure Explorer &lt;a href="http://sqlazureexplorer.codeplex.com/"&gt;http://sqlazureexplorer.codeplex.com/&lt;/a&gt; para o Visual Studio 2010. Ele vai te dar uma experiência interessante para administrar tabelas, views e stored procedures no SQL Azure;&lt;/p&gt;  &lt;p&gt;4) Por que não compreender melhor como você pode criar e testar um aplicativo no Azure que aceita identidades de um &lt;i&gt;identity provider&lt;/i&gt; externo (por exemplo, o ActiveDirectory da sua empresa ou de uma empresa parceira) usando o Windows Identity Foundation (WIF)? Neste caso, recomendo a leitura do &lt;a href="http://code.msdn.microsoft.com/wifwazpassive"&gt;WIF e Autenticação Federada no Windows Azure Web Role&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;…e, claro, reserve um tempo para passear e descançar.&lt;/p&gt;  &lt;p&gt;Bom feriado&lt;/p&gt;  &lt;p&gt;Otavio&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905101" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Azure" scheme="http://blogs.msdn.com/otavio/archive/tags/Azure/default.aspx" /><category term="Programação Funcional" scheme="http://blogs.msdn.com/otavio/archive/tags/Programa_E700E300_o+Funcional/default.aspx" /></entry><entry><title>Preços do Azure e simulação por Monte Carlo</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/10/01/pre-os-do-azure-e-simula-o-por-monte-carlo.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/10/01/pre-os-do-azure-e-simula-o-por-monte-carlo.aspx</id><published>2009-10-01T19:54:09Z</published><updated>2009-10-01T19:54:09Z</updated><content type="html">&lt;p&gt;Tenho recebido perguntas de como calcular o custo do Azure para compará-lo com o custo de outras alternativas.&lt;/p&gt;  &lt;p&gt;Já existem algumas calculadoras disponíveis para isto, mas, infelizmente todas as que eu vi fazem contas simples, que poderiam ser feitas com o Excel com pouco esforço, e que não levam em conta a variação probabilística de alguns fatores que influenciam no preço final. &lt;/p&gt;  &lt;p&gt;Quando temos variáveis como &lt;em&gt;GB de storage utilizados no mês&lt;/em&gt;, &lt;em&gt;trafego de mensagens&lt;/em&gt;, &lt;em&gt;número de transações&lt;/em&gt;, etc., melhor do que fazer uma conta com um número estimado (nosso “chute”) é utilizar uma estimativa estatística baseada em algum comportamento padrão – e aqui entram as distribuições normais, uniformes, binárias, etc. &lt;/p&gt;  &lt;p&gt;Vamos a um exemplo. &lt;a href="http://en.wikipedia.org/wiki/Normal_distribution"&gt;Distribuições normais&lt;/a&gt; são interessantes para modelar distribuições que tendem a se aglomerar perto de uma média – o que acontece, a meu ver, com todas as variáveis componentes do preço final do uso do Azure à exceção do custo de uso de CPU e SQL.&lt;/p&gt;  &lt;p&gt;Outro fator interessante de uma distribuição normal é que podemos simular seu comportamento empiricamente se soubermos dois dados que nos dão os limites do intervalo de confiança em que temos 90% de confiança (ver figura). &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PreosdoAzureesimulaoporMonteCarlo_A550/normal_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="normal" border="0" alt="normal" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PreosdoAzureesimulaoporMonteCarlo_A550/normal_thumb.jpg" width="240" height="163" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;E aqui um ponto importante: “chutar” um intervalo de confiança é mais fácil e preciso (!) do que “chutar” o valor esperado. Por exemplo, no Excel, bastaria utilizarmos a fórmula&lt;/p&gt;  &lt;p align="center"&gt;&lt;font color="#0000ff" face="Courier New"&gt;=norminv(rand(),média,desvioPadrão)&lt;/font&gt;&lt;/p&gt;  &lt;p align="left"&gt;onde &lt;/p&gt;  &lt;p align="center"&gt;&lt;font color="#0000ff" face="Courier New"&gt;média = (Limite 90% do Intervalo de Certeza + Limite 10% do Intervalo de Certeza)/2&lt;/font&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;font color="#0000ff" face="Courier New"&gt;desvioPadrão = (Limite 90% do Intervalo de Certeza - Limite 10% do Intervalo de Certeza)/3,29&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Levar em conta valores probabilísticos nos leva a um resultado probabilístico também. Isto é, ao invés de obtermos um único número obtemos uma curva probabilística que nos conta nossa variação com o risco. Por exemplo, podemos perceber que temos 10% de chance de pagar um valor de 800 quando o valor médio estaria em 700 e, ao final, saber estas chances pode nos levar a um processo de decisão mais realista – numa comparação entre preços ofertados no mercado, será factível compreender melhor quando ou com que probabilidade uma composição de preço é melhor que outra.&lt;/p&gt;  &lt;p&gt;Como isto é um instrumento útil não só para cálculo de preços, mas para planejamento de capacidades e outros, vale a pena mostrar o como calcular levando em conta as curvas de probabilidades.&lt;/p&gt;  &lt;p&gt;A maneira mais comum e genérica que temos hoje para calcular uma expressão que é constituída da composição de fórmulas probabilísticas é o &lt;a href="http://en.wikipedia.org/wiki/Monte_Carlo_method"&gt;método de Monte Carlo&lt;/a&gt;. O método de Monte Carlo é um método de simulação - isto é, são gerados vários números que obedecem as curvas de probabilidade de cada fórmula estatística da expressão. Por exemplo: se temos o custo em GB de storage e o custo de transferência de GB dados, podemos pensar que a expressão do custo dos dois é dado por &lt;font face="Courier New"&gt;P_usoGb()*custoPorGB + P_transfGB()*custoTransfPorGB&lt;/font&gt;. Como cada função P é de fato uma curva probabilística, podemos simular milhares de resultados ao gerar números (que obedeçam a curva de distribuição de cada função P_) para &lt;font face="Courier New"&gt;P_usoGb()&lt;/font&gt; e &lt;font face="Courier New"&gt;P_transfGB()&lt;/font&gt; e calculando milhares de resultados para esta expressão. &lt;/p&gt;  &lt;p&gt;Com milhares de resultados, podemos agora calcular intervalos e suas probabilidades contando quantos dados simulados ficaram abaixo de um determinado valor. Outra maneira de lidar com isto é ordenar o array de resultados e calcular, por exemplo, 10 intervalos a partir dos valores mínimos e máximos da amostra. Sabendo os intervalos, podemos contar o total de valores dentro de cada intervalo e, com isto, temos a probabilidade para cada intervalo.&lt;/p&gt;  &lt;p&gt;Um Excel ou um programa ajuda no cálculo. Como gosto de programas, vou contar como fiz minha versão 0.01 da minha calculadora do Azure.&lt;/p&gt;  &lt;p&gt;Passo 1: Interface – Usei WPF pensando em usar gráficos no futuro.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PreosdoAzureesimulaoporMonteCarlo_A550/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PreosdoAzureesimulaoporMonteCarlo_A550/image_thumb.png" width="406" height="366" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Passo 2: Funções de geração de distribuição aleatórias para serem usadas na simulação – Coloquei em uma biblioteca 3 tipos de distribuição, mas uso apenas a distribuição normal aqui (de um algorítmo achado na internet). Aqui vai o código:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;MathHelp
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Random &lt;/span&gt;r = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Random&lt;/span&gt;();

    &lt;span style="color: green"&gt;// Gera número randômico segundo a distribuição normal
    // decimal upper90 =&amp;gt; valor superior do Intervalo de 90% de Confiança
    // decimal low90 =&amp;gt; valor inferior do Intervalo de 90% de Confiança
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static double &lt;/span&gt;GenByNormal(&lt;span style="color: blue"&gt;double &lt;/span&gt;upper90, &lt;span style="color: blue"&gt;double &lt;/span&gt;low90)
    {
        &lt;span style="color: blue"&gt;double &lt;/span&gt;norminv = 0;

        &lt;span style="color: blue"&gt;double &lt;/span&gt;probability = r.NextDouble();
        &lt;span style="color: blue"&gt;double &lt;/span&gt;mean = (upper90 + low90)/2;
        &lt;span style="color: blue"&gt;double &lt;/span&gt;sigma = (upper90 - low90)/ 3.29; &lt;span style="color: green"&gt;// standard deviation

        &lt;/span&gt;&lt;span style="color: blue"&gt;double &lt;/span&gt;x = 0;
        &lt;span style="color: blue"&gt;double &lt;/span&gt;p = 0;
        &lt;span style="color: blue"&gt;double &lt;/span&gt;t = 0;
        &lt;span style="color: blue"&gt;double &lt;/span&gt;q = 0;

        &lt;span style="color: blue"&gt;const double &lt;/span&gt;c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
        &lt;span style="color: blue"&gt;const double &lt;/span&gt;d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;

        q = probability;
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(q == 0.5) norminv = mean;
        &lt;span style="color: blue"&gt;else &lt;/span&gt;{ 
            q = 1 - q;
            &lt;span style="color: blue"&gt;if &lt;/span&gt;((q &amp;gt;= 0) &amp;amp;&amp;amp; (q &amp;lt; 0.5)) p = q;
            &lt;span style="color: blue"&gt;else &lt;/span&gt;{
                &lt;span style="color: blue"&gt;if &lt;/span&gt;(q == 1.0) p = 1 - 0.9999999; &lt;span style="color: green"&gt;// JPR - attempt to fix divide by zero below, what is NormInv(1,x,y)?
                &lt;/span&gt;&lt;span style="color: blue"&gt;else &lt;/span&gt;p = 1 - q;
            }

            t = &lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Sqrt(&lt;span style="color: #2b91af"&gt;Math&lt;/span&gt;.Log(1 / (p * p)));

            x = t - (c0 + c1 * t + c2 * (t * t)) / (1 + d1 * t + d2 * (t * t) + d3 * (t * t * t));

            &lt;span style="color: blue"&gt;if &lt;/span&gt;(q &amp;gt; 0.5) x = -1 * x;

            norminv = (x * sigma) + mean;
        }

        &lt;span style="color: blue"&gt;return &lt;/span&gt;norminv;
    }


    &lt;span style="color: green"&gt;// Gera número randômico segundo a distribuição uniforme
    // decimal upper =&amp;gt; valor superior do Intervalo 
    // decimal low =&amp;gt; valor inferior do Intervalo 
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static double &lt;/span&gt;GenByUniform(&lt;span style="color: blue"&gt;double &lt;/span&gt;upper, &lt;span style="color: blue"&gt;double &lt;/span&gt;low)
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;r.NextDouble() * (upper - low) + low;
    }

    &lt;span style="color: green"&gt;// Gera número randômico segundo a distribuição binária
    // decimal oneProb =&amp;gt; probabilidade de dar 1
    &lt;/span&gt;&lt;span style="color: blue"&gt;public static double &lt;/span&gt;GenByBin(&lt;span style="color: blue"&gt;double &lt;/span&gt;oneProb)
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;((r.NextDouble()&amp;gt; oneProb)?1:0);
    }

}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Passo3: Criação dos arrays com valores aleatórios – Note que minha amostragem é de 1000 simulações para cada variável. Também vale a pena lembrar dos custos do Azure &lt;a href="http://blogs.msdn.com/otavio/archive/2009/07/16/modelo-de-neg-cio-e-pre-os-do-azure.aspx"&gt;aqui&lt;/a&gt; ou &lt;a href="http://www.microsoft.com/azure/pricing.mspx"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Cria array de 1000 posições para cada par Upp-Lower
&lt;/span&gt;&lt;span style="color: blue"&gt;double&lt;/span&gt;[] cpuRequest = GenNormalArray(1000, 0.15, convertDoubleToString(txReqUpp.Text), convertDoubleToString(txReqLow.Text));
&lt;span style="color: blue"&gt;double&lt;/span&gt;[] kTrans = GenNormalArray(1000, 0.001, convertDoubleToString(txKTransacoesUpp90.Text), convertDoubleToString(txKTransacoesLow10.Text));
&lt;span style="color: blue"&gt;double&lt;/span&gt;[] gbUsados = GenNormalArray(1000, 0.15, convertDoubleToString(txGBUsadosUpp.Text), convertDoubleToString(txGBUsadosLow.Text));
&lt;span style="color: blue"&gt;double&lt;/span&gt;[] storageRead = GenNormalArray(1000, 0.15, convertDoubleToString(txLeituraUpp.Text), convertDoubleToString(txLeituraLow.Text));
&lt;span style="color: blue"&gt;double&lt;/span&gt;[] storageWrite = GenNormalArray(1000, 0.15, convertDoubleToString(txEscritaUpp.Text), convertDoubleToString(txEscritaLow.Text));
&lt;span style="color: blue"&gt;double&lt;/span&gt;[] sqlRead = GenNormalArray(1000, 0.15, convertDoubleToString(txSQLLeituraUpp.Text), convertDoubleToString(txSQLLeituraLow.Text));
&lt;span style="color: blue"&gt;double&lt;/span&gt;[] sqlWrite = GenNormalArray(1000, 0.15, convertDoubleToString(txSQLEscritaUpp.Text), convertDoubleToString(txSQLEscritaUpp.Text));&lt;/pre&gt;

&lt;p&gt;onde &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;private double &lt;/span&gt;convertDoubleToString(&lt;span style="color: blue"&gt;string &lt;/span&gt;s)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;( s==&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Empty || s == &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot; &lt;/span&gt;) s = &lt;span style="color: #a31515"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;double &lt;/span&gt;result = 0;
    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        result = &lt;span style="color: #2b91af"&gt;Convert&lt;/span&gt;.ToDouble(s);
    }
    &lt;span style="color: blue"&gt;catch &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Exception &lt;/span&gt;err)
    {
        &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Erro de digitação: &amp;quot; &lt;/span&gt;+ err.Message);
    }
    &lt;span style="color: blue"&gt;return &lt;/span&gt;result;
}

&lt;span style="color: blue"&gt;private double&lt;/span&gt;[] GenNormalArray(&lt;span style="color: blue"&gt;int &lt;/span&gt;size, &lt;span style="color: blue"&gt;double &lt;/span&gt;value, &lt;span style="color: blue"&gt;double &lt;/span&gt;upper90, &lt;span style="color: blue"&gt;double &lt;/span&gt;low90)
{
    &lt;span style="color: blue"&gt;double&lt;/span&gt;[] arr = &lt;span style="color: blue"&gt;new double&lt;/span&gt;[size];
    &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; size; i++)
    {
        arr[i] = &lt;span style="color: #2b91af"&gt;MathHelp&lt;/span&gt;.GenByNormal(upper90, low90) * value;
    }
    &lt;span style="color: blue"&gt;return &lt;/span&gt;arr;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Passo 4: Cálculo do custo total para cada linha&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;double&lt;/span&gt;[] total = &lt;span style="color: blue"&gt;new double&lt;/span&gt;[1000];
&lt;span style="color: blue"&gt;double &lt;/span&gt;custoCPUs = convertDoubleToString(txNumCPUs.Text) * 24 * 30.5 * 0.12;
&lt;span style="color: blue"&gt;double &lt;/span&gt;custoSQL = convertDoubleToString(txNumSQL10GB.Text) * 99.99 + convertDoubleToString(txNumSQL1GB.Text) * 9.99;

&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 1000; i++)
{
    &lt;span style="color: green"&gt;// calcula custo Azure
    &lt;/span&gt;total[i] = custoCPUs + cpuRequest[i] + gbUsados[i] + storageRead[i] + storageWrite[i] + kTrans[i];
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(custoSQL != 0)
    {
        total[i] += custoSQL + sqlRead[i] + sqlWrite[i];
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Passo 5: Criação dos intervalos – Neste código deixei um valor fixo de 10 intervalos.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Sort nos resultados para poder achar os intervalos
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Array&lt;/span&gt;.Sort(total);

&lt;span style="color: green"&gt;// cria 10 intervalos de acordo com o s valores mínimos e máximos encontrados
&lt;/span&gt;&lt;span style="color: blue"&gt;double &lt;/span&gt;interval = (total[999] - total[0]) / 10;
&lt;span style="color: blue"&gt;int&lt;/span&gt;[] counters = &lt;span style="color: blue"&gt;new int&lt;/span&gt;[10]; &lt;span style="color: green"&gt;// array para contar número de resultados a cada intervalo

&lt;/span&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;index = 0;
counters[index] = 0;
&lt;span style="color: blue"&gt;double &lt;/span&gt;toCompare = total[0] + interval; &lt;span style="color: green"&gt;// valor de teste
// inicia a contagem
&lt;/span&gt;&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;j = 0; j &amp;lt; 1000; j++)
{
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(total[j] &amp;gt;= toCompare)
    {
        index++;
        toCompare += interval;
    }
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(index &amp;lt; 10) counters[index]++;
    &lt;span style="color: blue"&gt;else break&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Passo 6: Mostra dos resultados – Nesta versão, só um MessageBox&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;s = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;
&lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 10; i++)
{
    s += &lt;span style="color: #a31515"&gt;&amp;quot;\n Maior Igual a &amp;quot; &lt;/span&gt;+ &lt;span style="color: #2b91af"&gt;Convert&lt;/span&gt;.ToString(total[0] + interval * i) + &lt;span style="color: #a31515"&gt;&amp;quot; val &amp;quot; &lt;/span&gt;+ counters[i];
}

&lt;span style="color: #2b91af"&gt;MessageBox&lt;/span&gt;.Show(s);&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PreosdoAzureesimulaoporMonteCarlo_A550/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PreosdoAzureesimulaoporMonteCarlo_A550/image_thumb_1.png" width="642" height="434" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Note, neste exemplo, que temos uma variação de custo em dólares de ~290 a ~385, com valor mais provável no intervalo entre 322 a 354 (com ~78,5% de chance).&lt;/p&gt;

&lt;p&gt;É claro que é uma versão draft com muitos defeitos. Por exemplo, o tratamento de erros é fraco e um gráfico final seria bom para melhorar sua venda. Mas a intenção é só mostrar um método de avaliação quando temos a composição de valores probabilísticos. Qualquer erro, por favor, e-mail para mim.&lt;/p&gt;

&lt;p&gt;O importante é que este método de cálculo pode ser usado com o Azure, com preços de terceiros ou mesmo com o cálculo dos custos da sua TI. Lembre-se, de no custo total, colocar preços como eletricidade, custo de pessoal, etc.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Abraços&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9901920" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Algoritmos" scheme="http://blogs.msdn.com/otavio/archive/tags/Algoritmos/default.aspx" /><category term="Azure" scheme="http://blogs.msdn.com/otavio/archive/tags/Azure/default.aspx" /></entry><entry><title>Revisitando o Agile</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/09/26/revisitando-o-agile.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/09/26/revisitando-o-agile.aspx</id><published>2009-09-26T21:15:00Z</published><updated>2009-09-26T21:15:00Z</updated><content type="html">&lt;P&gt;As metodologias de desenvolvimento ágeis são baseadas em conceitos simples: rapidez para modificar, entregas menores e contínuas, alinhamento constante com o usuário, etc. Muitos falam de seu uso e suas virtudes, mas nem sempre é muito bem explicada a filosofia de otimização de ROI (retorno de investimento) também existente nelas.&lt;/P&gt;
&lt;P&gt;A melhor explicação que tive (e recomendo a leitura) veio do livro “&lt;A href="http://www.amazon.com/Agile-Management-Software-Engineering-Constraints/dp/0131424602/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1253988586&amp;amp;sr=1-1" mce_href="http://www.amazon.com/Agile-Management-Software-Engineering-Constraints/dp/0131424602/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1253988586&amp;amp;sr=1-1"&gt;agile management for software engineering applying the theory of constraints for business results&lt;/A&gt;”. Nele o autor nos relembra que a produção de software pode ser vista como um processo em etapas para a produção como, por exemplo, análise, desenvolvimento e teste. Cada etapa recebe insumos e produz seus produtos/artefatos: a análise recebe pedidos de &lt;EM&gt;features&lt;/EM&gt; e entrega especificações para o desenvolvimento, este entrega código para o teste que, por fim, entrega softwares para a produção.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/SemRealimentacao_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/SemRealimentacao_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=SemRealimentacao border=0 alt=SemRealimentacao src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/SemRealimentacao_thumb.jpg" width=652 height=98 mce_src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/SemRealimentacao_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;O que o autor nos chama a atenção é que esta esteira de processos retilínea não é realista. Cada processo tem suas perdas e estas perdas podem voltar para as pilhas dos processos anteriores de um modo que denominamos de &lt;I&gt;realimentação negativa&lt;/I&gt;. O alarmante é que esta realimentação negativa pode causar, no limite, uma parada total da produção, já que podemos encher cada pilha de insumos com os retornos de falhas, consumindo toda a produção nestes acertos… sem mais produzir nada de novo. Já encontrei esta roda viva em projetos reais - não é agradável.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/Realimentacao_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/Realimentacao_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Realimentacao border=0 alt=Realimentacao src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/Realimentacao_thumb.jpg" width=655 height=175 mce_src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/RevisitandooAgile_D691/Realimentacao_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Um ponto interessante é que estes artefatos são feitos tanto de diagramas e documentos quanto de &lt;B&gt;conceitos&lt;/B&gt; e, por isto, &lt;B&gt;deterioram&lt;/B&gt; com o tempo. Por exemplo, o código errado, quando volta para o desenvolvedor, deve ser re-estudado. O tempo de re-estudo, por sua vez, é muito maior do que se ele tivesse sido revisto e acertado enquanto o desenvolvedor estava com todos seus conceitos frescos na sua mente. O mesmo acontece com o processo de design. &lt;/P&gt;
&lt;P&gt;Uma última conclusão simples: um erro no design tem custo potencialmente maior do que um erro no desenvolvimento. O motivo é simples: ele gasta à toa as pilhas de desenvolvimento e teste com linhas de código e testes errados.&lt;/P&gt;
&lt;P&gt;A teoria é boa, mas ela garante o bom resultado das metodologias ágeis? Parece que não.&lt;/P&gt;
&lt;P&gt;Um pequeno artigo, que dá uma foto resumida do que temos agora, pode ser encontrado na revista IEEE Software que você pode encontrar em &lt;A href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0909/rW_SW_WhatDoWeKnow.pdf" mce_href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0909/rW_SW_WhatDoWeKnow.pdf"&gt;http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0909/rW_SW_WhatDoWeKnow.pdf&lt;/A&gt;. Ele mostra que ainda temos muito a pesquisar e melhorar tanto neste tipo de processo quanto nos processos não ágeis. O artigo também nos dá em separado uma lista de estudos empíricos sobre o Desenvolvimento Ágil (veja em &lt;A href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0909/rW_SW_WhatDoWeKnow2.pdf" mce_href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0909/rW_SW_WhatDoWeKnow2.pdf"&gt;http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0909/rW_SW_WhatDoWeKnow2.pdf&lt;/A&gt; ) .&lt;/P&gt;
&lt;P&gt;Pode ser útil.&lt;/P&gt;
&lt;P&gt;Abraços&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899886" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Agile" scheme="http://blogs.msdn.com/otavio/archive/tags/Agile/default.aspx" /></entry><entry><title>Capacidades, Arquitetura e SOA</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/09/19/capacidades-arquitetura-e-soa.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/09/19/capacidades-arquitetura-e-soa.aspx</id><published>2009-09-19T20:56:53Z</published><updated>2009-09-19T20:56:53Z</updated><content type="html">&lt;p&gt;Uma das armas mais importantes usadas pelos arquitetos de TI ao longo dos últimos tempos tem sido a noção de &lt;b&gt;capacidade&lt;/b&gt;. &lt;/p&gt;  &lt;p&gt;Por definição, capacidade é a habilidade de executar uma determinada ação, e compreender de antemão que capacidades um sistema ou uma infraestrutura deve ter é função do arquiteto. Com esta análise em mãos ele pode trabalhar em subsistemas ou serviços que poderão fornecer estas habilidades respeitando a separação de propósitos (SoC - &lt;i&gt;separation of concerns&lt;/i&gt;).&lt;/p&gt;  &lt;p&gt;Vamos aos exemplos: poder enviar uma mensagem; autorizar e/ou autenticar um usuário; acessar dados; chamar serviços; executar fórmulas; etc.&lt;/p&gt;  &lt;p&gt;Em cada um destes exemplos podemos conceber sistemas como o Exchange ou o Active Directory, bibliotecas como o Entity Framework, executáveis como um interpretador, e assim por diante.&lt;/p&gt;  &lt;p&gt;Pensar em capacidades é elevar a abstração a um ponto relativamente estável. Ela indica &lt;i&gt;o que&lt;/i&gt; queremos fazer e não &lt;i&gt;o como&lt;/i&gt; fazer. Continuando o exemplo acima: podemos pensar em um dia substituir o Exchange por um processo smtp ou um Exchange na Nuvem – quem sabe? No entanto, ainda demorará a chegar o dia em que o conceito de envio de e-mail não existirá mais.&lt;/p&gt;  &lt;p&gt;Outro benefício é que capacidades têm grande possibilidade de virarem Serviços. Exatamente porque a SoC foi alcançada, poderemos pensar em utilizar serviços remotos ou locais (com patterns de IoC ou uso de Interfaces), estruturando melhor a arquitetura e aumentando, provavelmente, o reuso.&lt;/p&gt;  &lt;p&gt;O grande inimigo desta análise das capacidades é identificar os subsistemas ou serviços e &lt;u&gt;pular direto para a sua implementação&lt;/u&gt; sem antes garantir outros atributos importantes para o(s) sistema(s). Exemplo: desempenho. Alguns serviços podem estar em uma localidade distante, criando uma latência inaceitável para quem o chama. Outro: escalabilidade. Alguns serviços funcionam bem em regime de baixa demanda, mas podem tornar-se sofríveis com o aumento da demanda.&lt;/p&gt;  &lt;p&gt;Ambos os exemplos não são problemas da noção da capacidade, mas da adequação de uma implementação desta capacidade num contexto real.&lt;/p&gt;  &lt;p&gt;Em resumo: bons arquitetos pensam abstratamente para organizar o espaço da implementação de suas soluções e infraestruturas. Pensar em capacidades é comprovadamente uma boa heurística.&lt;/p&gt;  &lt;p&gt;Abraços&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9897150" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Arquitetura" scheme="http://blogs.msdn.com/otavio/archive/tags/Arquitetura/default.aspx" /><category term="SOA" scheme="http://blogs.msdn.com/otavio/archive/tags/SOA/default.aspx" /><category term="Lat&amp;#234;ncia" scheme="http://blogs.msdn.com/otavio/archive/tags/Lat_26002300_234_3B00_ncia/default.aspx" /></entry><entry><title>MapReduce no Windows Azure</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/09/12/mapreduce-no-windows-azure.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/09/12/mapreduce-no-windows-azure.aspx</id><published>2009-09-13T04:30:43Z</published><updated>2009-09-13T04:30:43Z</updated><content type="html">&lt;p&gt;Hoje vou descrever a vocês um pouco do que é o famoso &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Mapreduce"&gt;MapReduce&lt;/a&gt;&lt;/i&gt; e como podemos simulá-lo no Azure.&lt;/p&gt;  &lt;p&gt;Formalmente, o framework foi apresentado em um &lt;a href="http://labs.google.com/papers/mapreduce-osdi04.pdf"&gt;artigo de 2004 na OSDI por Jeff Dean e Sanjay Ghemawat&lt;/a&gt;, ambos da Google, e é hoje usado por vários sites (Facebook, Yahoo, e muitos outros).&lt;/p&gt;  &lt;p&gt;O MapReduce é um framework para processamento em paralelo baseado em um meta-algoritmo. Meta-algoritmos são padrões de resolução de problemas, como os conhecidos &lt;i&gt;divisão-e-conquista&lt;/i&gt;, &lt;i&gt;backtracking&lt;/i&gt; e outros. &lt;/p&gt;  &lt;p&gt;No caso do MapReduce a idéia foi a de implementar um padrão simples e bem conhecido que, por sua vez, já era realizado há muito no Lisp e no C++ (neste, com a API do &lt;a href="http://en.wikipedia.org/wiki/Message_Passing_Interface"&gt;MPI (Message Passing Interface)&lt;/a&gt; – usada em computação em grid, como no &lt;a href="http://www.microsoft.com/hpc"&gt;Windows HPC 2008&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;A idéia é simples: se quisermos aumentar o paralelismo de uma operação, um processo Mestre deve dividir a tarefa em diversas partições, uma para cada processo Trabalhador. Chamamos este passo de &lt;b&gt;Map&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;Em seguida, cada processo retorna seu resultado parcial para o processo Mestre, que aglutina e retorna todas as respostas a quam requisitou o processamento. Chamamos este passo de &lt;b&gt;Reduce&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;Nada como um bom exemplo (neste caso, retirado do livro &lt;a href="http://www.amazon.com/Art-Concurrency-Monkeys-Parallel-Applications/dp/0596521537/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1252804855&amp;amp;sr=1-1"&gt;The Art of Concurrency&lt;/a&gt;): Imagine o processo de contar quantas letras ‘e’ existem numa frase. Ao passar para o computador mestre a frase “&lt;i&gt;The quick brown fox jumps over the lazy dog&lt;/i&gt;.” ele deverá criar e enviar à cada Trabalhador um conjunto de pares com uma parte da frase e a letra a ser procurada (uma ordem para computação). Veja a figura abaixo.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/MapReducenoWindowsAzure_13C81/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/MapReducenoWindowsAzure_13C81/image_thumb.png" width="523" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Feito isto, cada Trabalhador faz sua procura em paralelo retornando seus resultados. Ao Mestre cabe juntar os resultados parciais e calcular o resultado final.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/MapReducenoWindowsAzure_13C81/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/MapReducenoWindowsAzure_13C81/image_thumb_1.png" width="525" height="267" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Pronto! Simples, elegante, podendo alcançar um altíssimo grau de paralelismo.&lt;/p&gt;  &lt;p&gt;Realizar isto no Azure é simples também. Mostrei no TechEd um pouco do código exemplo que consegui com o &lt;a href="http://simonguest.com/blogs/smguest/archive/2009/08/24/Patterns-for-Cloud-Computing.aspx"&gt;Simon Guest&lt;/a&gt; e vale a pena falar dele aqui também.&lt;/p&gt;  &lt;p&gt;O exemplo trata de achar todos os números primos dentro de uma série &lt;em&gt;(range) &lt;/em&gt;de inteiros.&lt;/p&gt;  &lt;p&gt;Para isto são utilizados vários processos: um processo com o papel &lt;b&gt;Web&lt;/b&gt; e vários com o papel &lt;b&gt;Worker&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/MapReducenoWindowsAzure_13C81/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/MapReducenoWindowsAzure_13C81/image_thumb_2.png" width="515" height="296" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Para a comunicação entre estes, são criadas duas filas e duas tabelas. &lt;/p&gt;  &lt;p&gt;A primeira tabela guarda as ordens de serviço de acordo com o nó Trabalhador. Caberá a cada trabalhador fazer uma query para pegar a sua ordem e processá-la.&lt;/p&gt;  &lt;p&gt;A segunda tabela é utilizada para que os nós Trabalhadores coloquem seus resultados. Caberá ao processo mestre fazer a query para consolidar os resultados processados pelos Workers.&lt;/p&gt;  &lt;p&gt;Quanto às filas, elas são usadas para dar a cada nodo um número (&lt;i&gt;node assignment&lt;/i&gt;), dar a ordem de início do processamento em paralelo aos Trabalhadores e, por fim, avisar ao Mestre que o processamento terminou. &lt;/p&gt;  &lt;p&gt;Deixo aqui como exercício para vocês implementarem este processo. É simples e é um bom exercício.&lt;/p&gt;  &lt;p&gt;Para facilitar, aqui vai uma função que indica se um número é primo ou não.&lt;/p&gt;  &lt;p&gt;public bool IsPrime(int number)    &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (number == 0||number==1)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return false;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (int i = 2; i * i &amp;lt;= number; i++)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (number % i == 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return false;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Bom trabalho e abraços&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9894595" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Arquitetura" scheme="http://blogs.msdn.com/otavio/archive/tags/Arquitetura/default.aspx" /><category term="Framework" scheme="http://blogs.msdn.com/otavio/archive/tags/Framework/default.aspx" /><category term="Algoritmos" scheme="http://blogs.msdn.com/otavio/archive/tags/Algoritmos/default.aspx" /><category term="cloud computing" scheme="http://blogs.msdn.com/otavio/archive/tags/cloud+computing/default.aspx" /><category term="Azure" scheme="http://blogs.msdn.com/otavio/archive/tags/Azure/default.aspx" /></entry><entry><title>Divagando sobre modismos e computação</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/09/05/divagando-sobre-modismos-e-computa-o.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/09/05/divagando-sobre-modismos-e-computa-o.aspx</id><published>2009-09-06T01:40:52Z</published><updated>2009-09-06T01:40:52Z</updated><content type="html">&lt;p&gt;Lembro-me sempre de uma história real relatada num livro do &lt;a href="http://en.wikipedia.org/wiki/Carl_Sagan"&gt;Carl Sagan&lt;/a&gt; sobre como a população em volta de um lago no Japão gerou o desenho de um samurai nas costas dos sapos que habitavam este lago. Segundo o livro, uma lenda de reencarnação de samurais como sapos fez com que a população não se alimentasse daqueles sapos cujas listas nas costas lembrassem os desenhos de um rosto de um samurai. Com o tempo, os sapos que sobraram eram justamente os que tinham estes traços e estes, por sua vez, levaram esta característica genética para seus filhos. Lembro-me até hoje da foto de um sapo em que algumas linhas na sua costa realizavam uma reprodução perfeita de um desenho japonês de um samurai.&lt;/p&gt;  &lt;p&gt;Os produtos e software de informática parecem sofrer deste mesmo processo. Ao longo do tempo vamos acreditando em certas qualidades, copiando e “melhorando” processos ou linhas de produto de tal forma que, ao final, todos se comportam de uma forma semelhante.&lt;/p&gt;  &lt;p&gt;Hoje temos a Arquitetura Orientada a Objetos, a Web 2.0, a computação na nuvem (ou em nuvem), a orientação a objetos, etc. Alguns chamam isto de paradigmas. Gosto de chamar de teleologias: lógicas que criamos par explicar ou determinar o propósito final de um design, natural ou não.&lt;/p&gt;  &lt;p&gt;Querem um exemplo clássico de teleologia? A idéia de que as espécies visam a sua perpetuação. Está é uma possibilidade, mas existem outras. Por exemplo, podemos pensar que as espécies vão sofrendo modificações aleatórias e que acasos, como mudança de clima, etc., façam com que os animais com algumas características particulares sobrevivam enquanto os outros não. Assim, a espécie não se modificou visando a sua perpetuação, mas se perpetuou porque tinha casualmente a modificação correta para o novo contexto.&lt;/p&gt;  &lt;p&gt;Arquitetos são mestres evangelizadores de teleologias. Eles criam as regras que definem as boas qualidades de um projeto de software e tentam fazer com que os projetos sigam estas regras. É um poder e tanto – &lt;strong&gt;&lt;font color="#ff0000"&gt;para o bem ou para o mal!&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Outro dia, em conversa com MVP’s da Microsoft, contei uma estória antiga sobre teleologias que podem ser úteis neste contexto. Aqui vai...&lt;/p&gt;  &lt;p&gt;“No Egito Antigo, havia uma crença de que um único homem era Deus. Por causa desta idéia, milhares de homens/mulheres dedicaram a vida para construir as pirâmides fantásticas que temos até hoje.&lt;/p&gt;  &lt;p&gt;Na Idade Média e Renascença, havia a crença de um Deus criador a que todos nós devíamos dedicação e obediência. Por causa desta idéia, a humanidade criou igrejas de arquiteturas magníficas mais todo um conjunto de artes, como a pintura, a escultura, etc., que nesta época floresceram. Temos estas igrejas como monumentos de visitação até hoje.&lt;/p&gt;  &lt;p&gt;Na idade moderna um novo deus surgiu, chamado razão. E se há algum objeto que incorpore melhor a razão, este é o computador. Isto explica porque milhares de homens/mulheres se dedicam a construir monumentos de milhões de linhas como os Sistemas Operacionais e ERP’s, que a cada 5 anos jogamos fora para construir um mais moderno.”&lt;/p&gt;  &lt;p&gt;Bom feriado!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9891853" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Arquitetura" scheme="http://blogs.msdn.com/otavio/archive/tags/Arquitetura/default.aspx" /></entry><entry><title>Promessa do TechEd – código do exemplo do Oslo</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/08/28/promessa-do-teched-c-digo-do-exemplo-do-oslo.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/08/28/promessa-do-teched-c-digo-do-exemplo-do-oslo.aspx</id><published>2009-08-28T22:19:56Z</published><updated>2009-08-28T22:19:56Z</updated><content type="html">&lt;p&gt;Prometi na palestra sobre MDD e Oslo neste TechEd colocar neste blog o código do exemplo de como usar uma gramática Mgrammar no .Net. Pois aqui vai....&lt;/p&gt;  &lt;p&gt;A gramática que mostrei na demo é simples. Ela lê textos da forma “X tem Y anos.”. Um exemplo seria: &lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;“Otavio tem 50 anos.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;Paula tem 29 anos.”&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Para isto, preciso declarar a gramática de reconhecimento em uma variável da forma:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;static private string contactGrammar = @&amp;quot;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; module lingContato {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; language Contatos {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; syntax Main = c:Contato * =&amp;gt; Contatos { valuesof(c) };         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; syntax Contato =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; n:Nome &amp;quot;&amp;quot;tem&amp;quot;&amp;quot; i:Idade &amp;quot;&amp;quot;anos.&amp;quot;&amp;quot; =&amp;gt; { Nome = n, Idade=i };         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; token Nome = ('A'.. 'Z' | 'a'..'z')+;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; token Idade = '0'..'9'+;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; interleave espaco = ' ' | '\r' | '\n' | '\r\n';         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;quot;;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;O passo 2 é compilar a gramática e criar o “parser”:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;CompilationResults resultsContatos = Compiler.Compile(        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; new CompilerOptions         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Sources = {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new TextItem {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Reader = new StringReader(contactGrammar),         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ContentType = TextItemType.MGrammar         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;); &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;DynamicParser parserContatos = resultsContatos.ParserFactories[&amp;quot;lingContato.Contatos&amp;quot;].Create(); &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;parserContatos.GraphBuilder = new NodeGraphBuilder();&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;O passo 3 é fazer o “parsing”do texto de entrada (na variável inText), gerando um grafo que representa a &lt;a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree"&gt;AST (Abstract Syntax Tree).&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;Node nContato = (Node)parserContatos.Parse(new StringTextStream(inText), null);&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Por fim, estamos prontos para navegar o texto e preencher uma lista do tipo Contato:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;Contato c = new Contato(); &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;foreach (Node record in tree.ViewAllNodes() )        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var member in record.Edges )         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string s = member.Label + &amp;quot;: &amp;quot; + member.Node; &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (member.Label == &amp;quot;Idade&amp;quot;)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c.Idade = member.Node.ToString();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lc.Add(c);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c = new Contato();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; saida += s + &amp;quot; \r\n&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; c.Nome = member.Node.ToString();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; saida += s + &amp;quot; &amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;onde Contato é dado pela classe:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public&lt;b&gt; &lt;/b&gt;class&lt;b&gt; &lt;/b&gt;Contato &lt;b&gt;{&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public&lt;b&gt; &lt;/b&gt;string&lt;b&gt; Nome { &lt;/b&gt;get&lt;b&gt;; &lt;/b&gt;set&lt;b&gt;; }&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public&lt;b&gt; &lt;/b&gt;string&lt;b&gt; Idade { &lt;/b&gt;get&lt;b&gt;; &lt;/b&gt;set&lt;b&gt;; }&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;&lt;font color="#0000ff" face="Courier New"&gt;}&lt;/font&gt;&lt;/b&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Você vai precisar destas declarações de namespaces do Oslo (no diretório bin da instalação do SDK dele):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff" face="Courier"&gt;using Microsoft.M;        &lt;br /&gt;using Microsoft.M.Parser;         &lt;br /&gt;using Microsoft.M.Grammar;         &lt;br /&gt;using System.Dataflow;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Aqui abaixo vocês podem ver como fica esta exemplo no Intellipad do Oslo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PromessadoTechEdcdigodoexemplodoOslo_E5A6/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/otavio/WindowsLiveWriter/PromessadoTechEdcdigodoexemplodoOslo_E5A6/clip_image002_thumb.jpg" width="829" height="279" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Na esquerda desta figura temos exemplos de frases de entrada. No meio, a gramática que consegue analisar sintaticamente este texto de entrada. Na esquerda vocês vêem a saida depois da análise. É um texto com chaves que representa uma AST (ou grafo).&lt;/p&gt;  &lt;p&gt;Para quem não viu, temos um webCast similar em: &lt;a title="https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=pt-BR&amp;amp;EventID=1032416175&amp;amp;CountryCode=BR" href="https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=pt-BR&amp;amp;EventID=1032416175&amp;amp;CountryCode=BR"&gt;https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=pt-BR&amp;amp;EventID=1032416175&amp;amp;CountryCode=BR&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vale a pena também ler os artigos: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd441702.aspx"&gt;Textual Domain Specific Languages for Developers - Part 1&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd548006.aspx"&gt;&lt;b&gt;Textual&lt;/b&gt; &lt;b&gt;Domain&lt;/b&gt; Specific Languages for Developers - &lt;b&gt;Part&lt;/b&gt; 2&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd789404.aspx"&gt;&lt;b&gt;Textual&lt;/b&gt; &lt;b&gt;Domain&lt;/b&gt; Specific Languages for Developers - &lt;b&gt;Part&lt;/b&gt; &lt;b&gt;3&lt;/b&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Creio que com isto você consegue criar o seu parser, não consegue?&lt;/p&gt;  &lt;p&gt;Promessa é divida. Com isto acabei de pagar a minha!&lt;/p&gt;  &lt;p&gt;Abraços,&lt;/p&gt;  &lt;p&gt;Otavio&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9888756" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author></entry><entry><title>Sobre Chefes, Algoritmos e Pérolas</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/08/15/sobre-chefes-algoritmos-e-p-rolas.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/08/15/sobre-chefes-algoritmos-e-p-rolas.aspx</id><published>2009-08-15T21:16:07Z</published><updated>2009-08-15T21:16:07Z</updated><content type="html">&lt;p&gt;Num &lt;a href="http://blogs.msdn.com/otavio/archive/2007/11/17/est-tica-e-arquitetura-de-sistemas.aspx "&gt;blog antigo&lt;/a&gt; comentei sobre estilos de arquitetura e, em particular, sobre o estilo barroco, onde o excesso é uma virtude. Isto também é real para algoritmos.&lt;/p&gt;  &lt;p&gt;Uma vez fui chamado pelo presidente da empresa em que trabalhava para otimizar o tempo de processamento de uma análise financeira. O produto dava ao usuário uma espécie de planilha, como o Excel, em que várias fórmulas do usuário eram interpretadas, chamando queries do banco de dados, potencialmente, a cada fórmula. Com isto em mãos, os usuários podiam construir o planejamento do custo financeiro de seus projetos com dados reais de um ERP e valores futuros de moedas, juros, etc. Nesta ocasião alguns clientes reclamavam que o cálculo estava levando mais de uma hora e o pedido era simples: diminuir este tempo.&lt;/p&gt;  &lt;p&gt;Como arquiteto, já estava com idéias de uso de cachê, queries feitas em batch e outras otimizações comuns neste cenário, quando dei início à engenharia reversa no código.&lt;/p&gt;  &lt;p&gt;O código não estava ruim de todo. Engenharia reversa feita, comecei a planejar as mudanças quando o bom senso me fez rodar um profile antes de começar as modificações.&lt;/p&gt;  &lt;p&gt;Com o relatório na mão, algo me assustou: a maior parte do tempo de execução estava numa única função: a concatenação de strings, uma função feita em casa.&lt;/p&gt;  &lt;p&gt;Curioso, abri o código da função e o que eu vi foi algo interessante. Era uma função que chamava a si mesmo, recursivamente, em pelo menos em 3 ocasiões. Levei algum tempo analisando se havia algum truque. Por que não, simplesmente, criar um array com o tamanho da soma dos dois strings para depois copiá-los?&lt;/p&gt;  &lt;p&gt;Desistindo de entender o porquê, criei a função correta e testei com uma planilha real. Resultado: cerca de 4 minutos para algo que antes levava 1 hora.&lt;/p&gt;  &lt;p&gt;Com o resultado na mão fui ao presidente da empresa e anunciei o bom resultado. Quando me perguntou o que havia de errado, mostrei a ele a listagem da função e anunciei: o culpado era esta “pérola do barroco”!&lt;/p&gt;  &lt;p&gt;Lembro que ele riu, mas um pouco sem graça. Desconfiado, fui investigar e descobri que ele tinha sido o autor desta pérola!&lt;/p&gt;  &lt;p&gt;Moral 1) Pratique o profile antes de iniciar uma re-arquitetura;&lt;/p&gt;  &lt;p&gt;Moral 2) Investigue quem fez a besteira antes de anunciá-la.&lt;/p&gt;  &lt;p&gt;Abraços &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9871204" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author></entry><entry><title>Arquitetura no Kernel do Windows 7</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/08/09/arquitetura-no-kernel-do-windows-7.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/08/09/arquitetura-no-kernel-do-windows-7.aspx</id><published>2009-08-09T15:55:17Z</published><updated>2009-08-09T15:55:17Z</updated><content type="html">&lt;p&gt;Talvez eu tenha sido um dos últimos a instalar o Windows 7 na Microsoft. Tenho dezenas de softwares e SDKs instalados na minha máquina e costumo demorar dias para uma instalação completa – algo muito arriscado quando estamos tão perto de apresentações com demonstrações que irei fazer no TechEd. Nestas horas, “&lt;i&gt;não mecha!”&lt;/i&gt; é meu mantra. Além disto, há muito esperava a chegada do versão final do Windows 7. Não gostaria de multiplicar o trabalho da instalação mais vezes enter Betas, RTCs e RTMs.&lt;/p&gt;  &lt;p&gt;Nesta semana que passou tive a grata surpresa de receber uma máquina nova – menos poderosa que a atual, porém, mas leve e com os mesmos 4G que tenho hoje. Animado, instalei o Windows 7 Enterprise e muitos dos outros softwares do meu dia a dia enquanto continuava trabalhando na antiga. Estou hoje há 4 dias operando 100% só com ela e aqui vão algumas impressões:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A instalação foi suave. Coloquei a versão 64 bits e migrei os dados com o Easy Transfer via disco externo. Muito bom ver depois de ½ hora todos meus muito gigas de docs espalhados serem migrados sem falha. &lt;/li&gt;    &lt;li&gt;A nova interface é ótima. Senti falta do “Show Desktop” no início, mas fiquei em casa depois que me contaram que está no botão mais à direita do taskbar depois do relógio. &lt;/li&gt;    &lt;li&gt;O W7 parece ser mais rápido que o Vista que tenho no hardware antigo, mais poderoso. Quando rodei algoritmos de teste em C# verifiquei que a máquina antiga é mesmo mais poderosa. Porém, o reajuste no kernel e a resolução de dependências que geravam lock e enfileiramentos são responsáveis por esta melhor &lt;i&gt;responsividade&lt;/i&gt; real (alguém conhece um bom adjetivo para que eu não use este anglicismo?). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;E aqui vem meu ponto sobre arquitetura. Vale a pena ver a conversa com &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Arun-Kishan-Farewell-to-the-Windows-Kernel-Dispatcher-Lock/"&gt;Arun Kushan no channel 9&lt;/a&gt;. Ele é o arquiteto que mudou o esquema de lock do Windows 7 e Windows Server 2008 R2, liberando-os para lidar com 256 processadores (a limitação antes era de 64). &lt;/p&gt;  &lt;p&gt;Estamos muito acostumados em pensar sobre arquitetos de software como aqueles responsáveis pela escolha de tecnologias de middleware, sistemas de identidade, estruturas de camadas, etc. Arquitetos como o Arun e o &lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt; trabalham com estruturas lingüísticas ou com estruturas granulares que têm um impacto imenso no desempenho e capacidade dos softwares envolvidos. São partes fundamentais de um projeto que, se não forem bem estruturadas antes, causam desastres.&lt;/p&gt;  &lt;p&gt;Muitos arquitetos, devido aos diagramas de bloco, se vêem construindo a fachada da solução de software. Gosto de lembrar que a consistência interna, muitas vezes não representável por diagramas de blocos, são fundamentos essências de um bom arquiteto. &lt;/p&gt;  &lt;p&gt;Abraços&lt;/p&gt;  &lt;p&gt;PS: Para quem quer melhorar seu aplicativo usando o que tem de novo no Windows 7, vale a pena baixar o XP2Win7 – uma aplicação exemplo que mostra como usar o Taskbar, sensores, multitouch, Windows Search, Transaction File System e muitos outros. Basta dar uma olhada em &lt;a title="http://code.msdn.microsoft.com/XP2Win7" href="http://code.msdn.microsoft.com/XP2Win7"&gt;http://code.msdn.microsoft.com/XP2Win7&lt;/a&gt; e ver como é simples usar o que a infraestrutura te dá de graça.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9862294" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author><category term="Paralelismo" scheme="http://blogs.msdn.com/otavio/archive/tags/Paralelismo/default.aspx" /><category term="Ci&amp;#234;ncia da Computa&amp;#231;&amp;#227;o" scheme="http://blogs.msdn.com/otavio/archive/tags/Ci_26002300_234_3B00_ncia+da+Computa_26002300_231_3B0026002300_227_3B00_o/default.aspx" /></entry><entry><title>Dupla Elegância</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/otavio/archive/2009/07/29/dupla-eleg-ncia.aspx" /><id>http://blogs.msdn.com/otavio/archive/2009/07/29/dupla-eleg-ncia.aspx</id><published>2009-07-30T00:25:58Z</published><updated>2009-07-30T00:25:58Z</updated><content type="html">&lt;p&gt;Uma vez, numa conversa em grupo com o &lt;a href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;Anders Hejlsberg&lt;/a&gt;, criador do C# e Turbo Pascal, ele confessou que sua leitura preferida (pelo menos naquele tempo) eram os livros e palestras do &lt;a href="http://en.wikipedia.org/wiki/Richard_Feynman"&gt;Richard Feynman&lt;/a&gt; devido a sua clareza e simplicidade em assuntos complexos.&lt;/p&gt;  &lt;p&gt;Confesso que também gosto muito dos textos deste importante físico e daí minha pressa em contar para vocês que as palestras dele, filmadas pela BBC, estão disponíveis pela Microsoft Research em &lt;a href="http://research.microsoft.com/apps/tools/tuva/index.html"&gt;http://research.microsoft.com/apps/tools/tuva/index.html&lt;/a&gt; (e você ainda testa seu inglês :-)&amp;#160; ).&lt;/p&gt;  &lt;p&gt;Vale olhar este site por dois motivos. Primeiro, a própria elegância, humor e brilhantismo do Feynman. Segundo, a interface gráfica do projeto Tuva, onde você pode acompanhar comentários de terceiros, adicionar os seus, fazer procuras, etc. É um excelente exemplo de como a interatividade e a riqueza gráfica pode fazer diferença – neste caso, na educação.&lt;/p&gt;  &lt;p&gt;Boa interface é um diferencial competitivo e tenho percebido que existem cada vez mais empresas atentas a este ponto. Nossos parceiros e clientes chegam cada vez mais com bons exemplos de Silverlight. Vejo também um grande interesse no uso dos novos aspectos do Windows 7 (veja em &lt;a href="http://blogs.msdn.com/alexschulz/archive/2009/06/08/windows-7-taskbar-cone-e-barra-de-progresso.aspx"&gt;1&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/alexschulz/archive/2009/06/05/windows-7-taskbar-thumbnails.aspx"&gt;2&lt;/a&gt; e &lt;a href="http://blogs.msdn.com/alexschulz/archive/2009/06/05/windows-7-taskbar-como-utilizar-em-suas-aplica-es.aspx"&gt;3&lt;/a&gt;). Com a provável grande aceitação do Windows 7, esta diferenciação começa a ser procurada com grande interesse.&lt;/p&gt;  &lt;p&gt;Em tempos de crise, diferenciação é sobrevivência, diria Darwin. Você não concorda?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9852561" width="1" height="1"&gt;</content><author><name>OtavioC</name><uri>http://blogs.msdn.com/members/OtavioC.aspx</uri></author></entry></feed>