MSDN Magazine - Julho 2008

7/18/2008 9:24:00 AM By Felipe Pessoto

Está disponível a edição de Julho da MSDN Magazine. Assuntos de capa:

  • Serviços de dados: Desenvolva aplicativos eficientes e escalonáveis com os Serviços de Dados do SQL Server
    Aqui o autor apresenta os Serviços de Dados do SQL Server, que expõem sua funcionalidade em relação a interfaces padrão de Web service. David Robinson

  • ADO.NET: Obtenha uma modelagem de dados flexível com o Entity Framework
    A autora responde a perguntas sobre o Entity Framework e permite entender como e por que ele foi desenvolvido. Elisa Flasko

  • Dados e WPF: Personalize a Exibição de Dados com Ligação de Dados e WPF
    Aqui, apresentamos técnicas para a ligação de dados programática e declarativa e a exibição com o Windows Presentation Foundation. Josh Smith

  • Transações: Construa sistemas escaláveis que gerenciam falhas sem perder dados
    Sistemas que gerenciam falhas sem perder dados são enganosos. Aprenda como conquistar sistemas escalonáveis e eficientes. Udi Dahan

  • WCF P2P: Como projetar compartilhamento de estado em redes de mesmo nível
    Saiba como habilitar recursos ponto a ponto em aplicativos de negócios, permitindo que compartilhem estado em uma rede de mesmo nível sem servidor. Kevin Hoffman

Download em Português

Google Code Jam - Saving the Universe

7/17/2008 11:52:00 PM By Felipe Pessoto

Infelizmente meus planos de participar do Google Code Jam já eram. Marquei pra competir no dia 26(Sábado), até ai tudo ok, mas pra ajudar fizeram as eliminatórias HOJE, numa quinta-feira. Claro, como a maioria das pessoas estava trabalhando, quando cheguei ja tinha acabado o tempo...
De qualquer forma fiz o primeiro desafio, em C#, vou postar o código fonte pra vocês.

O desafio é salvar o Universo =). Segundo o Google, se você buscar pelo nome de um buscador nele mesmo(Ex.: Buscar Google, no Google) o universo vai implodir. Você recebe uma lista de Buscadores e a lista de Palavras à buscar(que vai ser sempre o nome de um dos buscadores). Então tem que gerar um algoritmo que faça que a busca, sem buscar a Palavra no Buscador com mesmo nome(pra nao implodir o Universo). Até aí nada demais, seria só um if pra fazer o switch entre qual buscador vai usar cada vez.

O desafio é fazer esse switch da forma mais otimizada possível, dizendo qual o número mínimo de switchs em cada caso, exemplos:

5
Yeehaw
NSM
Dont Ask
B9
Googol
10
Yeehaw
Yeehaw
Googol
B9
Googol
NSM
B9
NSM
Dont Ask
Googol
5
Yeehaw
NSM
Dont Ask
B9
Googol
7
Googol
Dont Ask
NSM
NSM
Yeehaw
Yeehaw
Googol

O primeiro número indica a quantidade de Buscadores, seguido pelos nomes dos mesmo, depois o número de Searchs e as respectivas Buscas.

No caso acima, devemos retornar:

Case #1: 1
Case #2: 0

Segue o código:

class Saving_the_Universe
{
    const string CaminhoEntrada = @"C:\Documents and Settings\Felipe\Meus documentos\Visual Studio 2008\Projects\CodeJam\CodeJam\Saving_the_Universe_Entrada.txt";
    const string CaminhoSaida = @"C:\Documents and Settings\Felipe\Meus documentos\Visual Studio 2008\Projects\CodeJam\CodeJam\Saving_the_Universe_Saida.txt";
 
    static List<string> Buscadores = new List<string>();
    static List<string> Querys = new List<string>();
 
    static void Main(string[] args)
    {
        StreamReader Entrada = new StreamReader(CaminhoEntrada);
        if (File.Exists(CaminhoSaida))
            File.Delete(CaminhoSaida);
 
        StreamWriter Saida = new StreamWriter(CaminhoSaida);
 
        int CasoAtual = 1;
        int CasosTotais = int.Parse(Entrada.ReadLine());
 
        string Temp = "";
 
        while (CasoAtual <= CasosTotais)
        {
            Buscadores.Clear();
            Querys.Clear();
 
            Temp = Entrada.ReadLine();
            for (int i = 0; i < int.Parse(Temp); i++)
            {
                Buscadores.Add(Entrada.ReadLine());
            }
 
            Temp = Entrada.ReadLine();
            for (int i = 0; i < int.Parse(Temp); i++)
            {
                Querys.Add(Entrada.ReadLine());
            }
 
            Saida.WriteLine("Case #{0}: {1}", CasoAtual, Algoritmo());
 
            CasoAtual++;
        }
 
        Entrada.Close();
        Saida.Close();
        Console.ReadKey(true);
    }
 
    static int Algoritmo()
    {
        Dictionary<string, int> QuerysContadas = new Dictionary<string, int>();
        //Pra cada buscador, conta quantas Querys existem chamando eles
        foreach (var item in Buscadores)
        {
            QuerysContadas.Add(item, Querys.Count<string>(p => p == item));
        }
 
        if (QuerysContadas.Values.Min() == 0)
            return 0;
 
 
        int UltimoIndice = 0;
        List<string> PalavraBuscadasNaOrdem = new List<string>();
 
        for (int i = 0; i < Querys.Count; i++)
        {
            if (PalavraBuscadasNaOrdem.Count == 0 || Querys[i] == PalavraBuscadasNaOrdem[PalavraBuscadasNaOrdem.Count - 1])
            {
                foreach (var NomeBuscador in Buscadores)
                {
                    if (Querys.IndexOf(NomeBuscador, i) == -1)
                        return PalavraBuscadasNaOrdem.Count;
 
                    if (UltimoIndice < Querys.IndexOf(NomeBuscador, i) && (PalavraBuscadasNaOrdem.Count == 0 || NomeBuscador != Querys[i]))
                        UltimoIndice = Querys.IndexOf(NomeBuscador, i);
                }
                PalavraBuscadasNaOrdem.Add(Querys[UltimoIndice]);
            }
        }
 
        return 1;
    }
}

Desafio I - Dynamic Iterators

7/16/2008 12:46:00 PM By Felipe Pessoto

Vou propor um desafio: Qual o resultado do seguinte código? E por quê?

    public class MainClass
    {
        static bool DeveMudar = false;
 
        public static void Main()
        {
            Console.WriteLine(DeveMudar);
            MetodoQualquer();
            Console.WriteLine(DeveMudar);
            Console.ReadKey();
        }
 
        public static IEnumerable<int> MetodoQualquer()
        {
            DeveMudar = true;
            yield return 1;
        }
    }
 

Design Patterns (Padrões de Projeto de Software) II: Observer

7/14/2008 11:01:00 PM By Felipe Pessoto

Continuando a série de artigos sobre Design Patterns, vamos discutir o Observer.

Vou novamente recorrer a definição da Wikipedia:

Define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes sejam notificados e atualizados automaticamente. Isto é o padrão Observer e permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto.

O padrão Observer é também chamado de Publisher-Subscriber, Event Generator, Dependents.



O Observer é composto de duas partes, o Subject que é o objeto que muda de estado com uma frequência imprevisível e os Observers que devem pedir que sejam notificados das mudanças de estado do Subject.

Os Observers podem se "cadastrar" e "descadastrar" para receber essas notificações.

Veja um diagrama do pattern:

E vamos partir para os códigos:

ISubject.cs:

    public interface ISubject
    {
        void Registrar(IObserver observador);
 
        void Desregistrar(IObserver observador);
 
        void Notificar();
    }

IObserver.cs:  

    public interface IObserver
    {
        void Atualizar();
    }​

SubjectConcreto.cs

        private string _SubjectState = "ON";
 
        public string SubjectState
        {
            get
            {
                return _SubjectState;
            }
            set
            {
                _SubjectState = value;
            }
        }
 
        private List<IObserver> Observers = new List<IObserver>();
 
        #region ISubject Members
 
        public void Registrar(IObserver observador)
        {
            Observers.Add(observador);
        }
 
        public void Desregistrar(IObserver observador)
        {
            Observers.Remove(observador);
        }
 
        public void Notificar()
        {
            foreach (IObserver Observador in Observers)
            {
                Observador.Atualizar();
            }
        }
 
        #endregion
    }​

ObserverConcreto.cs

    public class ObserverConcreto : IObserver
    {
        private string _Nome;
        private string _ObserverState;
        private SubjectConcreto _Subject;
 
        public SubjectConcreto Subject
        {
            get { return _Subject; }
            set { _Subject = value; }
        }
 
        public ObserverConcreto(SubjectConcreto pSubject, string pNome)
        {
            this._Subject = pSubject;
            this._Nome = pNome;
        }
 
        #region IObserver Members
 
        public void Atualizar()
        {
            _ObserverState = _Subject.SubjectState;
            Console.WriteLine("Novo estado do Observer {0} é {1}", _Nome, _ObserverState);
        }
 
        #endregion
    }​

Agora que temos nossas classes, vamos testa-las:

        static void Main(string[] args)
        {
            SubjectConcreto s = new SubjectConcreto();
 
            s.Registrar(new ObserverConcreto(s, "X"));
            s.Registrar(new ObserverConcreto(s, "Y"));
            s.Registrar(new ObserverConcreto(s, "Z"));
 
            s.SubjectState = "ABC";
            s.Notificar();
 
            Console.ReadKey();
        }​

Iniciamos nossos Observers e já passamos como argumento no método Registrar. Quando mudamos o valor de s que é nosso Subject e Notificamos, o método Atualizar() dos Observers é executado e você verá o seguinte resultado:

No .Net também temos uma forma otimizada de fazer isso, usando delegates e events, que é muito mais simples e elegante, mas nada impede você de implementar essas classes da forma que vimos.

Há quem diga que Designs Patterns são na verdade "defeitos" das linguagens, se persarmos bem estão certos. O Observer é seria uma forma de usar delegates e events nas linguagens que não tem esses recursos, assim como vimos com o Singleton que pode ser implementado de forma muito mais simples no .Net. Até a herança que temos hoje, antigamente era um Design Pattern pra linguagens como C. Em assembly tinhamos um Pattern pra criar métodos! Que até então eram codigos que se repetiam por todo o programa, dificultando a manutenção. Mas continuando ao assunto principal...

Delegates são equivalentes aos ponteiros de função, mas orientado à objetos e "type-safe". Uma instncia de delegate mantém uma referência à um método instanciado ou de classe.

Events por sua vez, são construções declaradas numa classe pra ajudar a expor mudanças de estado aos objetos interessados, que são definidos em tempo de execução.  Um event representa os métodos Registrar, Desregistrar e Notificar que usamos no Observer, mas suportado diretamente pelo compilador e pela CLR.

Os delegates são registrados pra cada event desejado em tempo de execução e quando o event é chamado, todos os delegates registrados são invocados.

Fazendo uma comparação direta com o Design Pattern Observer, a classe que declara o event, seria o Subject, mas sem precisarmos criar Interfaces. E o Observer deve instanciar um delegate passando o nome do método a ser notificado e registrá-lo ao event. Também é possível desregistrar os delegates. A notificação do Subject acontece quando o event é invocado.

Pra quem não está acostumado com delegates e events pode parecer um pouco complicado, mas na verdade é bem mais simples, pois você não tem que se preocupar com Interfaces ou classes Base. Veja um exemplo:

    public class Estoque
    {
        //Declaração do delegate
        public delegate void DelegatePerguntaPreco(decimal pPreco);
        //Declaração do event
        public event DelegatePerguntaPreco PrecoMudou;
 
        //Variável observada
        decimal _Preco;
 
        public decimal Preco
        {
            set
            {
                _Preco = value;
 
                //Dispara o event
                PrecoMudou(_Preco);
            }
        }
    }
 
    public class TelaEstoque
    {
        public void MetodoPrecoMudou(decimal pPreco)
        {
            Console.Write("O novo preço é:" + pPreco.ToString("c") + "\r\n");
        }
    }
 
    public class MainClass
    {
 
        public static void Main()
        {
            TelaEstoque objTela = new TelaEstoque();//Observer
            Estoque objEstoque = new Estoque();//Subject
 
            //Cria novo delegate e associa ao método
            //objTela.MetodoPrecoMudou do Observer
            Estoque.DelegatePerguntaPreco aDelegate = new
               Estoque.DelegatePerguntaPreco(objTela.MetodoPrecoMudou);
 
            //Adiciona o delegate ao event
            objEstoque.PrecoMudou += aDelegate;
 
            //Muda o preco 10 vezes
            for (int i = 0; i < 10; i++)
            {
                objEstoque.Preco = i;
            }
 
            //Remove o delegate do event
            objEstoque.PrecoMudou -= aDelegate;
 
            Console.ReadKey();
        }
 
    }​

 

A vantagem dos delegates além da simplicidade é que permite que qualquer classe atue como um Observer, independente das Interfaces implementadas ou da classe Base, só precisamos criar um método com a mesma assinatura do delegate.

MSDN Magazine - Junho 2008

7/10/2008 1:35:00 PM By Felipe Pessoto

Está disponível a edição de Junho da MSDN Magazine. Assuntos de capa:

  • SAAS (software como serviço): Conecte aplicativos empresariais com serviços BizTalk hospedados
    Neste artigo, apresentamos os Serviços BizTalk, uma nova tecnologia que oferece os recursos de Barramento de Serviços Corporativos do BizTalk Server como um serviço hospedado. Jon Flanders e Aaron Skonnard

  • Simultaneidade: Ferramentas e técnicas para identificar problemas simultâneos
    Aplicativos paralelos eficientes não aparecem simplesmente executando um antigo aplicativo em um computador com processadores paralelos. É necessário fazer ajustes para aproveitar todas as vantagens. Rahul V. Patil e Boby George

  • Robótica: Simulando o mundo com o Microsoft Robotics Studio
    O Microsoft Robotics Studio não serve apenas para brincar com robôs. Ele também permite criar aplicativos baseados em serviço para uma ampla gama de dispositivos de hardware. Sara Morgan

  • Preenchimento de formulário: Crie fluxos de trabalho para capturar dados e criar documentos
    Saiba como criar um fluxo de trabalho que usa formulários InfoPath e outros documentos do Office a fim de passar dados para atividades direcionadas e para uso em documentos do Office. Rick Spiewak

  • Biblioteca GUI: A simplicidade do Windows Forms para aplicativos nativos
    Neste artigo, o autor John Torjo apresenta um guia para sua biblioteca de GUI C++ chamado eGUI++ e explica como ela torna a programação da interface do usuário mais fácil. John Torjo

Download em Português