Acompanhe e assine o Reverb Vodcast!

03/07/2010 13:41

Agora no Reverb você poderá se inscrever no canal Reverb Vodcast e acompanhar os vídeos abordando diversos assuntos relacionados ao desenvolvimento de software, entre outros temas. O termo “Vodcast” é uma abreviação de “Video Podcast” e o formato e distribuição é bem semelhante ao dos podcasts, com a diferença de ser um vídeo.

podcast

Para assinar o Reverb Vodcast você pode utilizar o ícone ao lado. Os vídeos serão, na sua maioria, bem objetivos, práticos e curtos. O primeiro Vodcast sai daqui a pouco, espero que gostem. Opiniões, sugestões e críticas serão muito bem-vindas.

Podcasts



SharePoint 2010 Guidance

30/06/2010 16:04

Foi disponibilizado ontem o download do SharePoint 2010 Guidance. Além do download, também foi atualizado no site patterns & practices a área de desenvolvimento para SharePoint.

Seguem os links:


Abaixo você confere uma ilustração sobre as áreas cobertas na documentação:

SharePoint2010GuidanceDocumentation

Boa leitura!

SharePoint ,



Lançada a Easy .net Magazine 2

21/06/2010 22:30

capa_easynet2_g Acaba de ser lançada a segunda edição da revista Easy .net Magazine da DevMedia. A revista é voltada para o público iniciante, que está tendo os primeiros contatos com tecnologias de desenvolvimento. É possível ler todos os artigos através do Leitor Digital do portal.

Participei desta edição escrevendo um artigo sobre os meios de acesso a dados mais comuns no desenvolvimento de soluções baseadas na plataforma .NET.

Na maioria das aplicações desenvolvidas existe a necessidade de armazenarmos as informações em algum repositório de dados para posterior recuperação. No artigo vemos os métodos mais utilizados para recuperação de dados no desenvolvimento de aplicações .NET, além de entender quais são os requisitos necessários para garantir a integridade das informações.

Boa leitura!

Easy .net Magazine, Artigos ,



Você se preocupa com os IFs, suficientemente?

16/06/2010 16:47

Um dos problemas combatidos pela utilização de boas práticas de desenvolvimento, e que parece ser bastante comum, é a negligência. Aquela falta de atenção, seja por desleixo, ou por desconhecimento, que faz pequenos detalhes se tornarem desastrosos.

Quer ver um exemplo simples? O IF: essa natural instrução condicional, duas letrinhas, “I” e “F”,  simples assim (desculpem o tom sarcástico, mas assim é mais engraçado). Aparentemente, não existe tanto segredo assim num IF, certo? Analisamos uma ou algumas condições, e executamos algum código caso o IF seja satisfeito. Mas vamos analisar o código abaixo, que peguei num code review.

if ((txtWord.Text != "" || cblWords.Items.Count != 0)
     && VerifyAlias(txtAlias.Text, true)
     && (txtWord.Text == "") ? true : VerifyKeyword(txtWord.Text))
{
    // Código aqui...
}


Sim, é um IF trabalhoso de ler e entender, não o escolhi por acaso. Temos algumas condições simples a serem checadas, como o txtWord.Text != “” ou cblWords.Items.Count != 0. Mas isso, combinado com outra verificação, que utiliza uma função VerifyAlias, já complica mais um pouco. Para complicar, sensivelmente, temos um ternário no final, sendo que a condição negativa leva a uma nova verificação através da função VerifyKeyWord(txtWord.Text).

No geral, temos um IF com uma desnecessária complexidade na sua construção, a leitura não é rápida, além disso, possivelmente você teria dificuldades para escrever testes unitários que cubram todas as possibilidades.

Isso posto, vamos considerar algumas práticas úteis para codificarmos IFs.

“Escreva primeiro o caminho normal de execução, só depois escreva os casos alternativos.”

O ensinamento aqui é que devemos nos preocupar em escrever primeiros as condições normais de uso, ou os caminhos esperados de execução de um código. Após isso devemos pensar em escrever as condições de exceção. Essa prática vai muito bem, aplicada juntamente, com a seguinte:

“Ordene os testes pela frequência.”

Ou seja, procure colocar os testes que tem a maior chance de ocorrer antes dos demais. Isso é interessante inclusive para quem lê o código, posteriormente, pois terá uma ideia rápida das condições mais importantes.

“Simplifique checagens complicadas com variáveis e funções booleanas.”

Em detrimento de algumas linhas a mais, podemos melhorar a leitura do código usado anteriormente fazendo conforme vemos abaixo.

bool IsWordNotEmpty = (txtWord.Text != "");
bool IsExistsWordsList = (cblWords.Items.Count != 0);
bool IsFilterOk = IsWordNotEmpty || IsExistsWordsList;

bool IsAliasOk = VerifyAlias(txtAlias.Text, true);
bool IsKeywordOk = !IsWordNotEmpty ? true : VerifyKeyword(txtWord.Text);

if (IsFilterOk && IsAliasOk && IsKeywordOk)
{
    // Código aqui...
}

Observe que foram criadas algumas variáveis booleanas para dividirmos o resultado de cada parte da checagem em etapas. Na linha 1 eu checo se o textbox txtWord possui algum valor. Na linha seguinte verifico se existe algum item no combobox list cblWords. Na linha 3 foi criada uma variável booleana que armazena o resultado da verificação das duas primeiras “etapas”, pois no exemplo deste código, tanto a primeira ou a segunda satisfazem o esperado. Reparem que podemos utilizar as variáveis a partir daqui. Por fim, as linhas 5 e 6 fazem o mesmo processo para as demais verificações. Para melhorar a leitura do código devemos colocar nomes mais significativos. Para não ter que entrar nos detalhes de implementação deste negócio, vamos assumir apenas uma notação com “Ok” para as variáveis, como em IsFilterOk, IsAliasOK e IsKeywordOk.

Como resultado, podemos ver na linha 8 um IF muito simples, contendo apenas três condições, bastante auto-explicativas. Como vantagem desse método, você pode utilizar as variáveis com os resultados em outras checagens posteriores, dentro do mesmo contexto.

A quebra da checagem em variáveis e expressões booleanas podem realmente simplificar uma condicional IF complexa, tornando o código mais elegante. Mas, como nem tudo são flores, pode trazer outros problemas. Você pode, por exemplo, ter um resultado inválido se durante o código alguma condição for alterada e a variável booleana não. Outro grande problema é a realização de trabalho desnecessário.

Veja essas outras duas dicas na codificação de IFs:

“Pare o teste quando você obtiver a resposta.”


“Utilize avaliação preguiçosa.”


Caso a linguagem não suporte as chamadas “avaliações de curto-circuito” é melhor evitar uso de “AND” e “OR”. Por exemplo, no código a seguir:

if (txtWord.Text != "" && VerifyKeyword(txtWord.Text))
{
    // Código aqui...
}

Se a primeira condição for falsa, consequentemente o IF já falhou, então não é necessário checar a segunda condição VerifyKeyword(txtWord.Text). Esse é o comportamento padrão do C#, mas em algumas linguagens isso não ocorre, sendo preferível você codificar da seguinte forma:
 

if (txtWord.Text != "")
{
	if (VerifyKeyword(txtWord.Text))
         {
              // Código aqui...
         } 
}

 

Seguindo a última dica, utilizar uma avaliação preguiçosa é fazer algo semelhante às estratégias just-in-time, que executam o trabalho no momento mais próximo de quando ele é necessário. Isso significa não fazer trabalhos “caros” antes do tempo, ou da necessidade. Voltando ao código que utilizava checagens com booleanas, é o caso das seguintes linhas:
 

bool IsAliasOk = VerifyAlias(txtAlias.Text, true);
bool IsKeywordOk = !IsWordNotEmpty ? true : VerifyKeyword(txtWord.Text);


Se as funções VerifyKeyword e VerifyAlias realizam uma operação dispendiosa, como por exemplo um full scan numa matriz muito grande, não vale a pena utilizar uma variável booleana para armazenar esses resultados se temos boas chances dessas checagens nem ao menos serem necessárias.

Percebemos então, que o satisfatório é acharmos um equilíbrio entre todas essas abordagens, escolhendo o que vale mais a pena em cada caso. Ironicamente, o primeiro código apresentado não causa problemas maiores que o de legibilidade (claro, dentro do contexto em que é utilizado), muito graças ao C#, que interrompe as checagens do IF quando necessário.

O assunto poderia se estender mais, pois muitas discussões ainda podem ser adicionadas aqui. Mas o que eu queria com esse post é suscitar o interesse em boas práticas de programação. Vimos que até mesmo nas instruções mais cotidianas, podemos incorrer em erros capciosos, portanto, fique atento.

C#



Controles úteis pra quem desenvolve websites

13/06/2010 23:24

Segue uma seleção de links contendo diversos controles e bibliotecas úteis para utilização em seu desenvolvimento web.

ASP.NET, Dicas , , , ,



Evento codificando.net 2010 com participação do .Net Architects

09/06/2010 10:53

A comunidade codificando.net realizará no dia 19/06 um grande evento onde será apresentado o que existe de mais novo em tecnologia de desenvolvimento por profissionais de grande capacidade e experiência!

O .Net Architects foi convidado para participar deste evento apresentando uma mesa redonda, da qual eu farei parte junto com outros amigos do grupo.

Horário: 14:00 às 16:00 hs - Discutindo arquitetura no Visual Studio 2010 e .NET 4
Neste encontro a comunidade .Net Architects irá discutir sobre arquitetura de software no ambiente .NET. Serão apresentadas algumas das novidades do Framework 4.0, Visual Studio 2010 e Team Foundation Server abrindo a sessão para que os congressistas participem e discutam sobre arquitetura de software e boas práticas utilizando-se destas novidades e entendendo como estas novas features ajudam e facilitam alcançar a arquitetura desejada: extensível, de fácil manutenção, estável e coesa.

Acompanhe as notícias sobre o evento no Twitter com a hashtag #Codificando2010.

Codificando2010Participem e divulguem!

Eventos, Palestras ,



Duck Typing com C# 4.0 e Dynamic Type

06/06/2010 21:22

O estilo Duck Typing é muito comum para programadores de linguagens dinâmicas, como por exemplo, Ruby. Ele permite que um objeto seja passado para um método que espera um certo tipo, mesmo que o objeto não seja deste tipo. Popularmente, o Duck Typing é definido pela frase a seguir:

If it walks like a duck and quacks like a duck, it must be a duck.

Numa tradução livre, seria algo como: “Se isso anda como um pato e fala como um pato, isso deve ser um pato”. Observe com bastante atenção o código abaixo. Repare que da linha 24 a 27 o método FazerQuack recebe um objeto do tipo dynamic, e usa a propriedade FazQuack() desse objeto. Não importa se o objeto é do tipo Pato ou Humano, desde que ele “faça quack” ele atenderá ao objetivo do método.

Experimente descomentar o código das linhas 18 e 19, e observe que ocorrerá um erro. Isso porque ao utilizarmos o tipo dynamic a checagem será realizada apenas em tempo de execução.

using System;

public class Program
{
    static void Main()
    {
        Executar();
    }

    private static void Executar()
    {
        var pato = new Pato();
        var homem = new Humano();

        FazerQuack(pato);
        FazerQuack(homem);

        //var cao = new Cachorro();
        //FazerQuack(cao);  // Essa linha gera um erro.

        Console.ReadKey();
    }

    private static void FazerQuack(dynamic ser)
    {
        ser.FazQuack();
    }
}

internal class Pato
{
    public void FazQuack()
    {
        Console.WriteLine("Quack!");
    }
}

internal class Humano
{
    public void FazQuack()
    {
        Console.WriteLine("Eu sei falar 'Quack!'");
    }
}

internal class Cachorro
{
    public void FazAu()
    {
        Console.WriteLine("Au!");
    }
}


Esse tipo de abordagem nos faz refletir sobre o equilíbrio entre o valor da tipagem forte e a produtividade de trabalharmos em um contexto dinâmico. Com o advento do C# 4.0 e suas bibliotecas dinâmicas, ficou bem mais fácil adotar esse estilo de programação.

Para exemplificar um dos possíveis problemas do Duck Typing, imagine termos métodos com o mesmo nome mas que não desempenham a mesma atividade. Claro que isso dependerá de quem estiver programando, mas o fato é que quando trabalhamos com dinamismo temos muito poder nas mãos, e erros serão mais desastrosos ao código do que dentro de um contexto estático e fortemente tipado.

O código-fonte de exemplo demonstrado pode ser baixado aqui:

C# ,



Fluent Interfaces e Method Chaining

01/06/2010 11:33

Conversando com um amigo que não conhecia Fluent Interfaces, acabei criando um exemplo simples para explicar o conceito, e achei bacana postar aqui a solução. Fluent Interfaces (ou interfaces fluentes) é uma técnica para escrita de interfaces que descrevam suas classes, métodos e propriedades. Elas recebem este nome porque a sua semântica é clara, seja individualmente, seja seguindo a sequência lógica da execução.

Em C#, a base para construção de Fluent Interfaces é o suporte oferecido pela linguagem ao chamado Method Chaining (ou “encadeamento de métodos”, termo cunhado por Martin Fowler, por volta de 2006).

Abaixo vemos um exemplo de utilização de código com Fluent Interfaces. Observe que da linha 10 a 13 a leitura do código fica muito simplificada, pois codificamos da mesma forma que encadeamos as ações a serem feitas. Ou seja, o código além de semântico é fluente.

using System;

namespace Estudo.FluentInterface.App
{
    class Program
    {
        static void Main()
        {
            // Escrita de código fluente.
            var vendedora = new Vendedora()
                .Oferecer(Produto.Fogao)
                .ComDescontoDe(15)
                .ValendoAte(new DateTime(2010, 7, 1));

            vendedora.Escrever();
            vendedora.Falar();

            Console.ReadKey();
        }
    }
}

 
O que vemos no código acima é um encadeamento de métodos da classe Vendedora. Mas como isso é possível?

O código abaixo mostra como foi criada a interface utilizada pela classe Vendedora. Note que ao criarmos os métodos “Oferecer”, “ComDescontoDe” e “ValendoAte” como sendo do tipo IFluentConversa estamos criando o encadeamento dos métodos, por inferência de tipos.
 

using System;

namespace Estudo.FluentInterface
{
    public interface IFluentConversa
    {
        IFluentConversa Oferecer(Produto produto);
        IFluentConversa ComDescontoDe(decimal desconto);
        IFluentConversa ValendoAte(DateTime data);

        void Falar();
        void Escrever();
    }
}


A seguir, temos a enumeração de produtos existentes.

namespace Estudo.FluentInterface
{
    public enum Produto
    {
        Cafeteira,
        Liquidificador,
        Batedeira,
        Fogao
    }
}

 
Abaixo vemos como fica a implementação da classe Vendedora. Apenas para tornar o exemplo um pouquinho mais interessante, o método Falar utiliza o a classe SpeechSynthesizer (disponível no Windows 7) que permite informarmos um texto para o sintetizador de voz do Windows para que o mesmo seja narrado por uma mulher (“Microsoft Anna”).

using System;
using System.Text;
using System.Speech.Synthesis;

namespace Estudo.FluentInterface
{
    public class Vendedora : IFluentConversa
    {
        Produto produto;
        decimal desconto;
        DateTime data;

        public IFluentConversa Oferecer(Produto produto)
        {
            this.produto = produto;
            return this;
        }

        public IFluentConversa ComDescontoDe(decimal desconto)
        {
            this.desconto = desconto;
            return this;
        }

        public IFluentConversa ValendoAte(DateTime data)
        {
            this.data = data;
            return this;
        }

        public void Falar()
        {
            var speech = new SpeechSynthesizer();
            speech.SelectVoice("Microsoft Anna");
            speech.Speak(MontarTexto());
        }

        public void Escrever()
        {
            Console.Write(MontarTexto());
        }

        private string MontarTexto()
        {
            var texto = new StringBuilder();
            texto.Append("Você gostaria de comprar ");

            switch (produto)
            {
                case Produto.Batedeira: texto.Append("uma batedeira "); break;
                case Produto.Cafeteira: texto.Append("uma cafeteira "); break;
                case Produto.Fogao: texto.Append("um fogão "); break;
                case Produto.Liquidificador: texto.Append("um liquidificador "); break;
            }

            texto.Append("com incríveis " + desconto.ToString() + "% de desconto? ");
            texto.Append("Essa promoção é valida até " + data.ToShortDateString() +  ".");

            return texto.ToString();
        }
    }
}


Apesar de simples, implementar Fluent Interfaces traz suas particularidades e questões que precisam ser avaliadas. Elas podem ser uma boa opção para criação de DSL’s ou para descrever abstrações de uso de uma API. Em contrapartida, pode ser trabalhoso manter todas as chamadas de métodos encadeadas. Outro problema comum é que podemos não entender quando e qual método finaliza a cadeia de ações. Por conta disso, muitos criticam o uso de Fluent Interfaces por elas dificultarem a compreensão de conceitos de design e até mesmo de orientação a objetos.

Abaixo, você pode fazer o download da solução com este exemplo.

C#