Filtrar packages no NuGet

Esta é uma dica rápida.

Toda vez que você quiser procurar algum componente pelo Package Manager Console, digite:

get-package -listavailable -filter ‘palavra-chave’

Serão listados todos os packages que batem com a palavra-chave informada 🙂

Entendendo Action e Func

Quem nunca viu algum código parecido que atire a primeira pedra!

Pessoa[] pessoas = PessoaDao.Carrega();
var ordenadoPorNome = pessoas.OrderBy(p => p.Nome).ToList(); // ordena
pessoasOrdenadas.ForEach((p) => Console.WriteLine("Nome: {0}", p.Nome)); // exibe os nomes ordenadamente

Simples e fácil de entender!

Mas… E esses métodos OrderBy e ForEach, como que funcionam!?

Delegates

Pra entender isso, temos que ir lá atrás e entender o que é um delegate. Delegate significa “Delegar“, em Português. E delegar tem o sentido de transferir poder.

E é exatamente o que um delegate pode fazer em nosso código. Ele pode transferir responsabilidades entre classes ou métodos.

Em programação, um delegate é um ponteiro para uma função. Com ele é possível guardar referência de métodos armazenada em variáveis. O delegate e o método referenciado devem contem a mesma assinatura. Com delegates é possível fazer com que um método transite entre classes adicionando uma referência de uma determinada função a uma variável delegate. E assim transitar o delegate como uma variável normal, passando um delegate por parâmetro de função, por exemplo.

Action & Func – Abstraindo

Action e Func são tipos específicos de delegates. A principal diferença é que o Action é um delegate que não retorna valor (void), enquanto um Func é um delegate que retorna valor.

Assim como delegates puros, Action e Func aceitam métodos já definidos tanto quanto métodos anônimos.

Action

Criar um delegate do tipo Action é muito simples. Usa-se Generics para definir os parâmetros de entrada da função do delegate. E assim podemos atribuir a referência a um método:

Action<string, int> algumMetodoQueRecebeStringEInt;
algumMetodoQueRecebeStringEInt = (s, i) =>
{
    Console.WriteLine("Metódo anônimo que recebe string '{0}' e inteiro {1}", s, i);
};

O Action tem uma limitação de, no máximo, 16 parâmetros.

Func

Func é o delegate que retorna valor, e o tipo do retorno é definido pelo último Generic na assinatura do delegate.

Isso quer dizer que para definir um Func que receba duas strings e retorne a soma das strings, ele terá que ser definido assim:

Func<string, string, string> metodo = (a, b) => { return a + b; };

Entendendo o OrderBy & ForEach

Agora que temos o conceito de delegates, Func e Action mais frescos em nossa mente, agora é possível perceber como as funções OrderBy e ForEach apresentadas logo na introdução do post funcionam:

ForEach:

Vamos reparar na assinatura do ForEach:

public void ForEach(Action<T> action)

E internamente como é implementado (via .NET Reflector):

public void ForEach(Action<T> action)
{
    if (action == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    for (int i = 0; i < this._size; i++)
    {
        action(this._items[i]);
    }
}

É simples, o método ForEach é um Syntatic Sugar! Ele é uma forma mais elegante de escrever código, mas internamente o código executado continua sendo um laço for.

Já o OrderBy segue na mesma linha, mas é mais complexo. O tipo de delegate que o OrderBy recebe é um Func. Então internamente o método OrderBy executará o delegate para cada item da lista de sua coleção, assim criando uma nova lista de valores e assim implementando a ordenação.

O assunto pode (e deve) ser estudado mais a fundo, minha intenção foi só dar um arranhão e clarear a mente sobre esses tipos específicos de delegates. 🙂

[]’s e até a próxima!

Design Patterns – Padrão Observer

Estou te observando!

Definição: O padrão Observer define uma dependência um-para-muitos entre os objetos de modo que quando um objeto muda de estado, todos os seus dependentes são notificados e atualizados automaticamente.

Ou seja, dentro do padrão Observer existe um objeto principal que tem uma relação com diversos outros, e quando o objeto principal tem uma alteração em seu estado todos os outros objetos relacionados são automaticamente notificados sobre a alteração no objeto principal.

Existem dois atores principais neste padrão:

Subject: O Subject é o objeto que é observado e envia notificações aos seus observadores.
Observer: O Observer é o objeto que fica observando o Subject e realiza uma ação quando é notificado que ocorreram alterações no Subject.

Utilizando Observer no .Net Framework

O .Net framework provê duas interfaces para aplicar o padrão Observer:

  • IObservable -> é o Subject, o objeto que envia notificações.
  • IObserver -> é o Observer, o objeto que recebe notificações.

A interface IObservable pede a implementação de apenas 1 método:

  • Subscribe: Que é utilizado para fazer a inscrição de um observer ao subject.

Já a interface IObserver pede a implementação de 3 métodos:

  • OnNext: É chamado pelo subject para passar o os novos dados.
  • OnError: É chamado quando o subject não consegue passar a informação, notificando que aconteceu algum erro.
  • OnCompleted: É chamado quando o subject termina de enviar notificações, assim o observer tem sua assinatura cancelada.

Exemplo

Agora que já conhecemos as interfaces e seus métodos, vamos imaginar o seguinte cenário para codificar um exemplo:

  1. Existe uma fábrica de refrigerantes.
  2. Existem as lojas, que recebem periodicamente refrigerantes da fábrica.
  3. A loja informa a fabrica que quer começar a receber periodicamente as remessas de refrigerante.
  4. A loja pode cancelar a assinatura que fez com a fábrica, sendo assim não receberá mais os refrigerantes.

Já dá para perceber que onde podemos aplicar o Observer Pattern nesta situação, não? 🙂

A Fabrica será nosso subject, onde ela notificará todas as lojas que estão inscritas sobre novos refrigerantes.
As lojas serão os observers, que inscrevem-se na fábrica e recebem notificações, que nesse caso são os refrigerantes.
E temos o refrigerante, que é o objeto que será transitado entre a fábrica e a loja.

Primeiro vamos ao código mais simples, o código da estrutura Refrigerante:

class Refrigerante
{
    public string Marca { get; private set; }

    public Refrigerante(string marca)
    {
        this.Marca = marca;
    }
}

Código da loja, que observa a fábrica de refrigerantes:

class Loja : IObserver<Refrigerante>
{
    private IDisposable unsubscriber;
    public string Nome { get; private set; }

    public Loja(string nome)
    {
        this.Nome = nome;
    }

    public virtual void Subscribe(IObservable<Refrigerante> fabrica)
    {
        if (fabrica != null)
            unsubscriber = fabrica.Subscribe(this);
    }

    #region IObserver<Refrigerante> Members

    public void OnCompleted()
    {
        Console.WriteLine("{0} não recebe refrigerantes.", this.Nome);
        Unsubscribe();
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("{0} não conseguiu receber o refrigerante corretamente.", this.Nome);
    }

    public void OnNext(Refrigerante value)
    {
        Console.WriteLine("{0} recebeu o refrigerante {1}.", this.Nome, value.Marca);
    }

    #endregion

    public virtual void Unsubscribe()
    {
        unsubscriber.Dispose();
    }
}

Aqui o código é relativamente simples. Foram implementados os métodos da interface IObserver que estão bem simples, também foram criados os método Subscribe e Unsubscribe, que faz a associação e a desassociação da loja com a fábrica.

Código da fábrica de refrigerantes:

class FabricaDeRefrigerante : IObservable<Refrigerante>
{
    private List<IObserver<Refrigerante>> lojas;

    public FabricaDeRefrigerante()
    {
        lojas = new List<IObserver<Refrigerante>>();
    }

    #region IObservable<Refrigerante> Members

    IDisposable IObservable<Refrigerante>.Subscribe(IObserver<Refrigerante> loja)
    {
        if (!lojas.Contains(loja))
            lojas.Add(loja);
        return new Unsubscriber(lojas, loja);
    }

    #endregion

    private class Unsubscriber : IDisposable
    {
        private List<IObserver<Refrigerante>> lojas;
        private IObserver<Refrigerante> loja;

        public Unsubscriber(List<IObserver<Refrigerante>> lojas, IObserver<Refrigerante> loja)
        {
            this.lojas = lojas;
            this.loja = loja;
        }

        public void Dispose()
        {
            if (loja != null && lojas.Contains(loja))
                lojas.Remove(loja);
        }
    }

    public void MandarNovoRefrigerante(Refrigerante refrigerante)
    {
        lojas.ForEach((loja) => {
            if (refrigerante != null)
                loja.OnNext(refrigerante);
            else
                loja.OnError(new RefrigeranteDesconhecidoException());
        });
    }

    public void FecharFabrica()
    {
        lojas.ForEach((loja) => loja.OnCompleted());
        lojas.Clear();
    }
}

O código é relativamente simples. A fábrica guarda uma lista de lojas. Ela também tem as funções de MandarNovoRefrigerante e FecharFabrica, que são auto-explicativas.

A peculiaridade dessa classe é a classe interna a ela: A classe Unsubscriber. Dentro dessa classe existe o código que desassocia a loja da fábrica, quando necessário. Quando alguém faz a associação da fábrica com algum objeto, uma instância de Unsubscriber é retornada ao chamador. Assim, para realizar a desassociação, basta chamar o método Dispose da instância de Unsubscriber.

Agora que já existe a FabricaDeRefrigerante, a Loja e o Refrigerante, vamos por em prática o código!

class Program
{
    static void Main(string[] args)
    {
        FabricaDeRefrigerante fabrica = new FabricaDeRefrigerante();

        Loja mercado2 = new Loja("Mercado 1");
        Loja mercado1 = new Loja("Mercado 2");

        mercado1.Subscribe(fabrica);
        mercado2.Subscribe(fabrica);

        fabrica.MandarNovoRefrigerante(new Refrigerante("Coca-cola"));

        mercado2.Unsubscribe();

        fabrica.MandarNovoRefrigerante(null);
        fabrica.MandarNovoRefrigerante(new Refrigerante("Pepsi"));

        fabrica.FecharFabrica();

        Console.ReadKey();
    }
}

E o seu resultado:

E pronto. Já temos o padrão Observer sendo utilizado, e ele é um dos padrões bastante conhecidos no mercado. Uma vantagem de utilizar as interfaces nativas do .Net Framework é que o Reactive Extensions da faz uso extensivo do padrão Observer, e as classes que forem criadas utilizando tais interfaces serão compatíveis com Rx (falando nisso, existe um post excelente sobre o reactive extensions).

Utilizando Observer no Java

O Java também dá suporte interno ao padrão observer através da classe abstrata Observable e da interface Observer. Existe um exemplo legal de implementação este padrão no Java, recomento a leitura.

O código fica mais simples, pois não é necessário programar com Generics e também não há necessidade de criar uma classe que é responsável por desassociar subject e observer.

O problema desse padrão interno no Java é que ao utilizar a classe abstrata Observable, nós ferimos dois dos princípios de projeto bastante conhecidos: “Programe para uma interface, e não para uma implementação” e “Dê prioridade à composição em relação à herança”.

Deste modo, ao utilizar o Java para fazer alguma implementação de Observer, nós matamos a herança do subject, pois necessariamente temos que herdar de (em vez de implementar)  Observable. 😦

.Net Framework vs Java

O .Net framework provê a implementação do padrão Observer através de interfaces, o que é muito bom. A desvantagem é que o código ganha mais de complexidade, pois temos que implementar manualmente as funções e criar uma classe para fazer a desassociação entre subject e observer. Porém temos total controle do código e temos integrações com outros componentes, como o Rx.

Já o Java torna essa tarefa mais simples, porém ferimos dois princípios de projetos e o nosso subject não pode herdar de nenhuma outra classe.

Bom, é isso, espero que tenham gostado e qualquer coisa podem falar comigo! 🙂

Referências:
http://www.dofactory.com/Patterns/PatternObserver.aspx
http://msdn.microsoft.com/en-us/library/ee817669.aspx
http://www.abhisheksur.com/2010/08/implementation-of-observer.html
http://www.mariosam.com/desenvolvimento/designpatterns/design-patterns-padrao-observer
http://msdn.microsoft.com/en-us/library/dd990377.aspx

Design Patterns – Strategy Pattern

Comecei a ler o livro Head First – Design Patterns para ter uma base mais sólida sobre os tão famosos padrões de padrões de projetos (Design Patterns) e pretendo fazer uma série de posts que explicam os padrões, irei publicando conforme avançar no livro.

Padrões de Projetos – Conceito

Na engenharia de software, um padrão de projeto (ou Design Pattern) é uma solução geral reutilizável para problemas comuns no design de software. Um padrão de projeto não é um design finalizado que pode ser transformado diretamente em código. Um padrão de projeto é uma descrição ou um modelo de como resolver um problema que pode ser utilizado em várias diferentes situações (tradução livre da Wikipédia).

Ou seja, os padrões de projetos são soluções comuns para problemas também comuns.

Os padrões de projetos são divididos em três categorias: Criacional, Estrutural e Comportamental. O livro Design Patterns: Elements of Reusable Object-Oriented Software foi o pontapé inicial onde o grupo conhecido como Gang of Four (GoF) descreveu uma lista com diversos problemas comuns de design de software e soluções para esses problemas.

Padrão de Projeto – Strategy (Estratégia)

O padrão Strategy é um padrão comportamental e sua definição oficial é a seguinte:

“Define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis. A estratégia deixa o algoritmo variar independente dos clientes que o utilizam.”

Simulação de um problema para aplicar o Strategy:

Vamos imaginar o seguinte cenário: Temos um simulador de corrida, esse simulador tem diversos corredores e cada corredor tem um carro, mas durante a execução do sistema o corredor tem a possibilidade de alterar de carro, que pode ser entre uma Ferrari ou uma McLaren.

Utilizando o padrão Strategy a solução para esse problema fica parecida com este diagrama de classes:

A classe Corredor tem uma dependência da interface ICarroDeCorrida. As classes Ferrari e McLaren implementam a interface ICarroDeCorrida, sendo que cada uma implementa o método correr de acordo com seu comportamento.

A classe Corredor tem o método MudarCarro qual permite a alteração em tempo de execução do tipo de carro utilizado pelo corredor.

public interface ICarroDeCorrida
{
    void Correr();
}
public class Ferrari : ICarroDeCorrida
{
    public void Correr()
    {
        Console.WriteLine("Estou Correndo com uma Ferrari!");
    }
}
public class McLaren : ICarroDeCorrida
{
    public void Correr()
    {
        Console.WriteLine("McLaren agora está correndo!");
    }
}
public class Corredor
{
    private ICarroDeCorrida carroDeCorrida;

    public Corredor(ICarroDeCorrida carroDeCorrida)
    {
        this.carroDeCorrida = carroDeCorrida;
    }

    public void MudarCarro(ICarroDeCorrida carroDeCorrida)
    {
        this.carroDeCorrida = carroDeCorrida;
    }

    public void RealizarCorrida()
    {
        this.carroDeCorrida.Correr();
    }
}

E assim podemos escrever o código e ver seu comportamento:

Corredor corredor = new Corredor(new Ferrari());
corredor.RealizarCorrida();

O padrão Strategy permite a alteração do comportamento do objeto em tempo de execução:

Corredor corredor = new Corredor(new Ferrari());
corredor.RealizarCorrida();
corredor.MudarCarro(new McLaren());
corredor.RealizarCorrida();

Uma vantagem desse padrão é que ele evita as famosas “Tags” dentro das classes. Uma solução não limpa (segundo Robert “Uncle Bob” Martin), porém comum, é utilizar uma propriedade chamada “TipoDeCarro” dentro da classe, e por meio de if’s/switch’s/whatever fazer a verificação do valor da propriedade e assim executar o código, deste modo aumentando bastante o tamanho do código da classe e dificultando a sua manutenção.

Com o padrão Strategy o código se torna orientado a objetos e não violamos dois princípios do SOLID: o Single Responsibility Principle (SRP) e o Open-Closed Principle (OCP).

Bom, já deu pra perceber que a Orientação a Objetos aliada aos Padrões de Projetos é uma forma de se escrever código robusto e limpo, e pretendo aprender mais e mais sobre os outros padrões já conhecidos.

Já li sobre o padrão Obeserver, quem sabe logo menos não sai um post aqui? 🙂

TechEd Brasil 2010 – Eu Vou!

Já é possível montar a sua agenda para o TechEd!

Montei minha agenda ontem e estou BEM anscioso com o conteúdo das palestras que confirmei minha presença.

13/09:

13:45 – 15:00 Título: ASP.NET MVC para desenvolvedores Web Forms
Palestrante (s): Giovanni Bassi, Victor Cavalcante
Sala: Cantareira 3
Público: Desenvolvedores / Profissionais de TI
15:30 – 16:45 Título: Teste de software com o Visual Studio 2010: Parte 1 de 2
Palestrante (s): Brian Keller, Rodrigo de Carvalho
Sala: Cantareira 4
Público: Desenvolvedores / Profissionais de TI
17:15 – 18:30 Título: Conhecendo Ruby e sua utilidade no mundo .NET
Palestrante (s): Fábio Akita
Sala: Santana 1
Público: Desenvolvedores / Profissionais de TI

14/09:

09:00 – 10:15 Título: Criando um cubo no Analysis Services em 50 minutos
Palestrante (s): Alexandre Nardi
Sala: Cantareira 7
Público: Desenvolvedores / Profissionais de TI
10:45 – 12:00 Título: Teste de software com o Visual Studio 2010: Parte 2 de 2
Palestrante (s): Brian Keller, Rodrigo de Carvalho
Sala: Cantareira 4
Público: Desenvolvedores / Profissionais de TI
13:45 – 15:00 Título: ASP.NET MVC 2: O que há de Novo?
Palestrante (s): Giovanni Bassi, Victor Cavalcante
Sala: Cantareira 3
Público: Desenvolvedores / Profissionais de TI
15:30 – 16:45 Título: Implementando Serviços RESTful usando o Microsoft .NET Framework
Palestrante (s): Israel Aece
Sala: Cantareira 5
Público: Desenvolvedores / Profissionais de TI
17:15 – 18:30 Título: Novidades do Windows Communication Foundation (WCF) no NET Framework 4
Palestrante (s): Evilázaro Alves
Sala: Jardim São Paulo
Público: Desenvolvedores / Profissionais de TI

15/09:

09:00 – 10:15 Título: Um mergulho no ADO.NET Entity Framework 4
Palestrante (s): Renato Haddad
Sala: Cantareira 5
Público: Desenvolvedores / Profissionais de TI
10:45 – 12:00 Título: Construindo aplicações de internet com Microsoft Silverlight and Microsoft
SharePoint Server 2010
Palestrante (s): Carlos Dietrich, Leandro Lopes
Sala: Cantareira 3
Público: Desenvolvedores / Profissionais de TI
13:45 – 15:00 Título: Discutindo sobre: Linq to Sql, Entity Framework Versus Stored Procedures
Palestrante (s): Luciano Condé
Sala: Cantareira 6
Público: Desenvolvedores / Profissionais de TI
15:30 – 16:45 Título: Paralelismo no .Net 4.0: Patterns, dicas e truques
Palestrante (s): Otavio Pecego Coelho
Sala: Jardim São Paulo
Público: Desenvolvedores / Profissionais de TI
17:15 – 18:30 Título: Explorando as ferramentas de arquitetura do Visual Studio 2010
Palestrante (s): Daniel Oliveira
Sala: Cantareira 5
Público: Desenvolvedores / Profissionais de TI

Só de ver tanta gente fera e conhecida no mundo do desenvolvimento, vai valer a pena!

TDD – Primeiras impressões

Depois de tanto ouvir falar sobre TDD nos podcasts do Tecnoretórica, nos podcasts do .Net Architects, nos posts do Vinicius Quaiato, Denis Ferrari e diversos outros, pensei: Acho que está na hora de aprender sobre TDD!

O Post do Denis Ferrari sobre TDD para iniciantes foi muito bom para mim, que sempre escutei, mas vi pouca implementação de código. Nesse post ele pega um problema e resolve 100% usando TDD.

Resolvi tentar fazer o meu primeiro código em TDD hoje. Eu fiz a implementação do problema do Integer Stack, do TDD Problems, e desde já pude perceber vantagens que esse tipo de padrão de desenvolvimento nos trás. Ao finalizar o código eu tive a sensação de que o código estava 100% seguro.

TDD

TDD

Se fosse o caso de uma empresa, imagino o quão valioso seria a utilização de TDD. Eu sempre tive a sensação de insegurança em ter que mexer em código de projetos que estavam parados por um tempo. Na implantação para produção eu fico receoso em que algo que alterei modificasse alguma parte que estava funcionando bem ou que tivesse efeitos colaterais em alguma outra funcionalidade. TDD parece resolver essa lacuna de alterar o código sem ter medo de quebrar alguma parte do sistema que já está funcionando.

Sou um iniciante nessa metodologia e quero praticar mais.

TDD, você ganhou mais um adepto!

Internacionalização

Estudando para tirar a certificação, me deparei com um trecho do livro que comenta a diferença entre Globalization (Globalização) e Localization (Localização).

Fiz a tradução livre do trecho do livro, vale a pena saber a diferença entre esses dois conceitos que estão dentro da Internationalization (Quantos “zation’s!)

Globalização: Em alguns países, o formato de se escrever o valor monetário é com um ponto (.) como um separador de milhares e uma vírgula (,) como um separador de decimais, enquanto outros países usam a convenção oposta. Uma aplicação globalizada formata o valor monetário com o separador de milhares e separador de decimais apropriados baseado na configuração cultural atual.

Localização: O título de um formulário é exibido de acordo com o idioma baseado no local qual ele foi implantado. Uma aplicação localizada recupera e exibe um texto baseado na configuração cultural atual”.

Ou seja, globalização é exibir corretamente o formato dos valores em sua aplicação de acordo com a cultura daquele país. Ex: Nos Estados Unidos exibiríamos o valor de 1,500.00 enquanto que no Brasil exibiríamos o valor de 1.500,00.

Já localização se refere a exibir a sua aplicação de acordo com o idioma da região. No Brasil poderíamos exibir a mensagem “Cliente gravado com sucesso!” enquanto nos Estados Unidos a mensagem seria “Client successfully saved!”.

Ao desenvolver aplicações é muito interessante ter em mente esses dois conceitos, pois uma aplicação internacionalizada é melhor aceita entre diferentes culturas e mais accessível para diferentes usuários!

Criando um formulário não-retangular

Estudando para a certificação de Windows Forms (eu sei, já existe WPF!) eu me deparei com uma situação qual eu nunca havia pensado em fazer: Criar um formulário não retangular.

É possível e muito fácil:

A propriedade Region de uma instância da classe Form define a forma em que ela aparece na tela. Para alterar a forma de seu formulário, é só valorizar esta propriedade com um novo valor.

Esta atribuição de valor deve acontecer dentro do evento Load do formulário, pois a alteração da forma acontece em runtime.

O modo mais fácil de criar um formulário não-retangular é utilizando a classe GraphicsPath (System.Drawing.Drawing2D.GraphicsPath). Basta criar uma instância de GraphicsPath e adicionar formas à ela. Depois deve-se criar uma instância da classe Region (System.Drawing) e passar ela para o valor da propriedade Region do formulário.

No exemplo abaixo eu criei um formulário em forma oval:

private void Form1_Load(object sender, EventArgs e)
{
    GraphicsPath graphics = new GraphicsPath();
    graphics.AddEllipse(0, 0, this.Width, this.Height);
    Region region = new Region(graphics);
    this.Region = region;
}

 E o resultado do código acima:

[]’s

O segundo post

Estava pensando em alguma coisa interessante para escrever no meu segundo post. O primeiro foi uma introdução ao blog e então logicamente o segundo post deveria falar sobre algum item do qual me propus a escrever (claro!). Andei pesquisando sobre Dependency Injection, já que é um termo mais avançado sobre Orientação a Objetos e é um assunto que pretendo conhecer mais. 

Então navegando pela internet me deparei com o post “A importância do tédio em nossas vidas”, no qual traduz para português um outro post: “Why I Returned my iPad”. Vale a leitura! 

 

Segue a tradução do texto Why I Returned my iPad: 

Porque eu devolvi meu iPad
por Peter Bragman (
link) 

Pouco mais de uma semana após comprar o meu iPad, eu o devolvi para a Apple. Mesmo tendo algumas falhas, o problema não estava exatamente no iPad. O problema estava em mim. 

Eu gosto de tecnologia, mas eu não sou uma pessoa que compra sempre a primeira versão, o quanto antes, de novos aparelhos e gadgets, eu espero as novas versões para que sejam corrigidas as possíveis falhas de projeto que possam ter passado despercebidas. Eu esperei pelo iPod de segunda geração, esperei pelo iPhone de segunda geração e esperei pelo Macbook Air de segunda geração. 

Mas o iPad é diferente. Tão elegante, tão legal, tão transformador… E, eu pensei, se ele é tão similar ao iPhone, a maioria das possíveis falhas de projeto que poderiam vir a existir já deveriam estar corrigidas. 

Assim, pela primeira vez na minha vida, me encontrei esperando por duas horas em uma fila na frente da loja da Apple para adquirir o meu iPad 3G, bem no meio da tarde do dia do seu lançamento. 

Fiz as configurações iniciais do aparelho na própria loja da Apple porque eu queria ter certeza que eu já poderia começar a usá-lo no momento em que eu o comprasse. E eu o usei bastante. O levava para qualquer lugar que eu fosse. Tão pequeno, tão leve, por que não trazê-lo junto comigo? 

Nele eu acessava o meu e-mail, escrevia artigos utilizando o aplicativo Pages, assistia a episódios da série Weeds no Netflix, lia notícias, verificava as condições e previsões climáticas, verificava o estado do tráfego, etc. É claro que eu mostrava orgulhosamente a minha nova aquisição a quem demonstrava um mínimo de interesse. (Isso por si só poderia gerar um novo texto. Eu mostrava o iPad 3G para qualquer um simplesmente por possuí-lo, como se fosse uma conquista. Por quê? Eu não criei o iPad, eu simplesmente comprei um!) 

Não demorou muito para que eu me deparasse com o lado negro desse revolucionário aparelho: ele é de fato maravilhoso. 

É tudo muito fácil, muito acessível, é rápido, a sua bateria dura muito. Claro que há alguns problemas, mas nada que chame muito a atenção. Na maior parte do tempo, eu conseguia fazer tudo o que eu queria e foi justamente isso que acabou se mostrando um grande problema. 

 

É claro que eu quero assistir a um episódio de Weeds antes de ir dormir. Mas será que eu deveria? É realmente difícil de parar tendo visto apenas um episódio, e duas horas depois, me pego entretido, mas bem cansado. Mas será que eu estou mesmo melhor assim? Ou será que eu estaria melhor tendo sete horas de sono ao invés de apenas cinco? 

A grande sacada do iPad é que ele é uma espécie de computador acessível em qualquer lugar, a qualquer hora. No metrô, no hall do elevador esperando o dito-cujo chegar, no taxi indo para o aeroporto, etc. Qualquer momento se torna um momento em potencial para se usar o iPad. O iPhone consegue fazer as mesmas coisas, mas não da mesma forma. Quem que quer ver um filme naquela telinha pequena do iPhone? 

Então, por que o iPad se mostrou um problema? Do jeito que eu falo ele parece super produtivo. De fato é, pois a cada minuto extra eu me encontrava produzindo ou consumindo. 

Mas algo – mais do que apenas a quantidade de horas que eu durmo, apesar de isso também ser crítico – foi perdido no tempo. Algo valioso demais para se perder. 

Tédio. 

Ficar entediado é uma coisa muito importante, um estado de espírito que devemos buscar. Uma vez que ficamos entediados, a nossa mente começa a vagar, buscando alguma coisa excitante, alguma coisa interessante para se estabelecer. E é justamente aí que a criatividade aparece. 

As minhas melhores idéias vêm à mim quando eu não estou produzindo nada: 

  • Quando eu estou correndo, mas não estou ouvindo nada no meu iPod;
  • Quando eu estou sentado, sem fazer nada, apenas esperando por alguém;
  • Quando estou deitado na minha cama esperando que o sono venha;

Esses momentos “perdidos” são vitais. 

Existem momentos em que nós, mesmo inconscientemente, organizamos as nossas mentes, colocamos sentido nas nossas vidas e ligamos os pontos. Existem momentos ainda em que falamos com nós mesmos e outros que ouvimos. Perder esses momentos, substituí-los com tarefas e eficiência, é um erro. O pior de tudo é que nós não apenas os perdemos, nós os jogamos fora. 

“Mas isso não é um problema com o iPad”, falou o meu irmão Anthony – ao qual sou compelido a mencionar que está produzindo um filme chamado “Meu Irmão Idiota”. “Isso é um problema seu. Você tem apenas que não usá-lo tanto!” 

Sim, culpado. O problema estava comigo. Eu não consigo simplesmente não usá-lo. E, infelizmente, ele está sempre ali, disponível! E, depois de ponderar, eu resolvi devolvê-lo. Pronto, problema resolvido. 

Essa experiência foi bem proveitosa para me ensinar o real valor do tédio. Agora eu estou bem mais consciente, de forma a utilizar melhor esses momentos extras para deixar a minha mente fluir em idéias e pensamentos. 

Mais ou menos na mesma época que eu devolvi o meu iPad, percebi que a minha filha de oito anos, Isabelle, estava inacreditavelmente ocupada do momento que ela chegava da escola até a hora que ela ia para a cama. Tomar banho, leitura, treino de violão, jantar, dever de casa, ela não parava um momento até eu lhe falar para ir dormir. Uma vez na cama, ela tentava falar comigo, mas eu, preocupado com o pouco sono que ela poderia ter, apressava esse momento e a impelia a dormir logo. 

Agora nós temos um novo ritual, um que tem se tornado a minha parte favorita do dia. Eu a tenho colocado para dormir 15 minutos mais cedo do que eu a colocava antes. Ela deita na cama, eu deito do lado dela e nós simplesmente conversamos. Ela fala sobre as coisas que aconteceram durante o seu dia, sobre coisas que a preocupam, coisas que ela está curiosa ou apenas sobre os seus pensamentos. Eu a ouço e faço perguntas. Nós rimos, e as nossas mentes simplesmente divagam…” 


 

Concordo 100% com Peter Bragman: são tantas coisas a se fazer que esses momentos importantes de “tédio” acabam sendo deixados de lado, ainda mais nos dias de hoje onde tem informação nova a cada minuto: Twitter, Orkut, Google Reader, Livros, Messenger , E-mail, TV, Video-Game, etc… 

Pelo menos eu consigo ter meus momentos de tédio produtivo, pois, morando em São Paulo, indo e voltando pro trabalho todo dia, é possível ter esses momentos de reflexão.

Hello World!

Por algumas vezes já tentei ter um blog sobre programação. Agora com o final (suado) da faculdade eu estou tendo tempo para realizar mais projetos pessoais e tempo para estudar o que gosto (seguindo a máxima: a faculdade atrapalha meus estudos!).

Pretendo postar aqui sobre novidades do que acontece no mundo da programação dentro da Microsoft e sobre conceitos de desenvolvimento de software.

Já vai aqui uma frase que um grande sábio disse:
“Any fool can write code that a computer can understand.  Good programmers write code that humans can understand.”

[]’s