27 de fevereiro de 2012

Design Patterns com Delphi: Visitor - Parte I

Coleções de objetos são uma das estruturas mais comumente usadas na construção de programas de computador. Elas podem aparecer na forma de listas, vetores ou em agregações e composições, onde diferentes tipos de objeto são mantidos juntos para representar um objeto mais complexo.

Um dos propósitos que nos leva a agruparmos objetos numa mesma estrutura é facilitar a execução de operações envolvendo as partes que constituem esse objeto. Ou seja, operações nas quais percorreremos todos os elementos e aplicaremos a cada um deles a operação desejada. Nesse processo, a existência de objetos de tipos distintos deve ser levada em conta porque uma mesma operação pode ter significado diferente, dependente do tipo de objeto. Isto nos leva a ter que escolher a versão correta da operação que deve ser executada em cada elemento. Por exemplo, considere que você tem uma classe representando a lista de recursos necessários para fabricar um produto. A lista inclui as matérias primas, as máquinas envolvidas e até roteiros descrevendo o processo de fabricação. Uma operação que imprima a estrutura terá que considerar as diferenças entre cada uma dessas partes pois elas têm informações específicas distintas.

Em princípio, parece que uma herança simples pode resolver a questão. Mas, e se for necessário acrescentar novos tipos de operação, com nomes e parâmetros diferentes - salvar em formato XML, por exemplo ? Teríamos que alterar a estrutura da agregação para que ela comporte a nova operação.

O intuito do Design Pattern comportamental Visitor é facilitar a manutenção desse tipo de estrutura heterogênea. Ele nos obriga a manter separada a estrutura de um objeto e os algoritmos das operações que podem ser aplicadas sobre seus componentes. Com isso, podemos introduzir novas operações à estrutura sem que seja preciso modificar as classes onde essas operações serão aplicadas. Em outras palavras, o que o Visitor propõe é transferir a implementação das operações, removendo-as das classes que compõem a agregação e passando-as para classes próprias. Com isso, preserva-se a estrutura original tanto da agregação quanto das partes que a compõem.

O diagrama abaixo mostra um exemplo prático da aplicabilidade desse padrão. Nele, um Produto Acabado é composto de uma lista de recursos, incluindo as matérias primas, máquinas e instruções para a fabricação dele. São definidas duas operações externas : uma para exportar a arquitetura do produto para XML e outra para imprimí-la.
Diagrama UML para o padrão Visitor
De acordo com o papel que exercem na implementação de uma solução para o padrão Visitor, as classes envolvidas são formalmente conhecidas pelos nomes que seguem:
O Visitor é uma abstração que define quais classes de objetos poderão ser submetidas às operações que serão disponibilizadas. Ele faz isso ao introduzir métodos sobrecarregados, um para cada tipo de elemento da agregação que sofrerá a operação. Por convenção, este método é nomeado Visit. No diagrama, este é o papel da classe TWOperacoesPA.

A implementação das operações em si é feita em classes chamadas Concrete Visitor. Essas classes são heranças simples do Visitor, o que significa que elas terão que fornecer sua própria versão de cada método Visit definido na classe base. Com isso, a operação tratará de forma condizente os diferentes componentes da coleção. No exemplo, as classes TWRecursoImprimir e TWRecursoSaveToXml fazem esse papel.

Chamamos de Visitable (ou Element) a classe que define um método Accept capaz de receber uma instância da classe de operação e executar a versão correta do método Visit dessa operação. Ela, portanto, serve de ponto de entrada da execução, definindo o comportamento esperado para todas as heranças que poderão ser "visitadas". São às vezes chamadas de Element por coincidir com a classe base dos elementos que compõem uma agregação. A classe que exerce esse papel no diagrama de exemplo é a TWRecursoProducao.

Os Concrete Visitable (ou Concrete Element) são as classes que efetivamente implementam o método Accept, direcionando a execução da operação para o tipo de objeto que representam. Isto é, chamando o método Visit correto da operação passada como parâmetro. As classes TWMateriaPrima, TWMaquina e TWRoteiro são exemplos disso no diagrama.

O Object Structure é a classe que contém a coleção de elementos sobre os quais uma operação será executada. Ela, então, terá que prover um meio para que a coleção seja percorrida de modo que todos os seus componentes possam ser submetidos à operação desejada. Este é o papel da classe TWProdutoAcabado no diagrama.

O Client é responsável por manter a instância tanto do Object Structure quanto da operação que será executada. Ela também navega os elementos da estrutura, executando em cada um a operação solicitada.

O padrão Iterator também é projetado para permitir a navegação entre elementos que compõem um objeto. A diferença é que no Iterator os elementos devem ser herança de uma mesma classe enquanto no Visitor isso não é obrigatório.

O cenário onde o padrão Visitor é aplicável se assemelha ao uso de interfaces, já que em ambos os casos, uma estrutura externa estabelece as operações que a classe é capaz de executar. No entanto, interfaces forçam a implementação das operações dentro da classe ao invés de fazê-lo em classes separadas, como no Visitor. Obviamente, ambos os recursos podem ser utilizados em conjunto para produzir uma solução mais flexível.

Alguns críticos alegam que o Visitor fere o encapsulamento das classes ao obrigar que parte de seu funcionamento seja delegada a outra classe. Mas, podemos encarar essa classe extra como uma operação distinta, minimizando ou até mesmo eliminando o efeito da quebra de encapsulamento.

No próximo post eu mostro uma sugestão de implementação desse pattern usando o Delphi.

Mais Informações
Posts sobre Design Patterns

14 de fevereiro de 2012

Aplicando recursos de localização em Asp.Net

por Tiago Oliveira*

Embora seja referenciado por uma palavra um tanto quanto estigmatizada - globalização - o fato é que o mundo ficou mesmo menor e os fabricantes de aplicações também passaram a levar isso em consideração. Ao planejar a construção de programas e sites, eles têm agora que incluir o conceito de localização na arquitetura, de uma forma que a aplicação se adeque à linguagem preferida pelo usuário sem que seja necessária uma reengenharia nas linhas de código.

O ASP.NET possui recursos de localização para que possamos fazer aplicações globalizadas, ou seja, para que a aplicação se adeque à região onde ela está sendo executada. A configuração utilizada pelo ASP.NET é a informada no navegador (no caso do IE, está no seguinte caminho : Opções de Internet/Geral/Idiomas), sendo considerado tanto o Idioma quanto a Região estipulados. Segue abaixo um exemplo de configuração:
en-US – Inglês região dos EUA.
pt-BR – Português região do Brasil.
As duas primeiras letras no código representam o Idioma e as duas últimas a região.

Agora vamos aplicar os recursos de localização disponíveis no ASP.NET para modificar esse comportamento padrão e fornecer um mecanismo para que o usuário opte pelo idioma de sua preferência na própria aplicação. Adicione um WebForm contendo 2 botões que, no caso, irão representar os possíveis idiomas suportados para visualização da aplicação : português e inglês.

Adicione um outro WebForm contendo alguns componentes Label, TextBox, etc. Para aplicar a localização às páginas da aplicação, o ASP.NET utiliza arquivos de Resources; por isso, vamos adicionar um arquivo de resource em nossa aplicação: clique no WebForm e selecione na guia Tools do Visual Studio a opção “Generate Local Resource”. Ao escolher essa opção. um arquivo de extensão .RESX com o mesmo nome da página será gerado dentro de uma pasta chamada App_LocalResources que será automaticamente adicionada ao seu projeto.

Dentro desse arquivo .RESX existe a relação de todos os componentes que comportam o recurso de localização, juntamente com a descrição dos campos. No nosso exemplo, esse arquivo irá representar a versão em português da aplicação; para gerarmos o arquivo contendo a versão em inglês, faça uma cópia do arquivo NomeDaSuaPagina.aspx.resx gerado pelo Visual Studio e altere o nome para NomeDaSuaPagina.aspx.en-US.resx. Nesse novo arquivo, faça a tradução dos campos para o Inglês.

No WebForm onde colocamos os 2 botões para identificar os idiomas, iremos passar a localização através de Query String, conforme código abaixo associado ao clique de cada um dos botões:
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
Response.Redirect("Conteudo.aspx?Language=pt-BR");
}

protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
Response.Redirect("Conteudo.aspx?Language=en-US");
}
Na página Conteudo.aspx (representando a página principal da aplicação), precisamos inicializar a cultura de exibição para considerar a que passamos por parâmetro e não aquela que está configurada no navegador. Para isso precisamos sobrescrever o método InitializeCulture da página e ajustar a variável interna UICulture, que é a responsável por controlar o idioma em que a aplicação está sendo exibida:
protected override void InitializeCulture()
{
UICulture = Request.QueryString["Language"];
base.InitializeCulture();
}
Ao exibir os textos da página, o ASP.Net passará a considerar automaticamente o conteúdo do arquivo .RESX referente ao idioma e região escolhidos.

* Tiago Oliveira é desenvolvedor na ABC71, onde trabalha com os módulos fiscais, de faturamento e de vendas.


10 de fevereiro de 2012

Microsoft abre extensão do C++ para uso em outros compiladores

Já há algum tempo que os computadores vêm sendo montados com placas gráficas - as chamadas GPUs - cada vez mais poderosas. No início, elas eram requisitadas apenas por quem apreciava jogos no PC pois esse tipo de software exige cálculos complexos intensos para apresentar a parte gráfica, o que usa massivamente as GPUs. Essa história começou a mudar com o Windows Vista, quando o próprio sistema operacional passou a fazer uso mais intenso da capacidade dessas placas, oferecendo aos usuários uma experiência visualmente mais agradável no uso do computador. Com isso, a preocupação de melhorar a apresentação dos programas aproveitando a GPU entrou na lista das empresas desenvolvedoras de software.

Já que se trata de uma CPU extra no computador, muitas vezes a GPU ainda acaba sendo sub utilizada. Mas, acessar plenamente os recursos das GPUs não é uma tarefa trivial. Atenta a isso, a Microsoft vem trabalhando em uma biblioteca para facilitar a utilização desses recursos por qualquer desenvolvedor.

Na verdade, a solução proposta pela Microsoft é estender a linguagem C++, introduzindo nela uma forma nativa e transparente de se ter acesso aos recursos da GPU, fornecendo junto os mecanismos de controle inerentes à computação paralela - notadamente, a sincronização de processamentos.

Abaixo segue uma tradução da reportagem publicada pela Infoworld dando mais detalhes dos planos da Microsoft. A reportagem original em inglês pode ser acessada no link Microsoft opens C++ extension for other compilers.
A Microsoft abriu sua especificação do C++ AMP de modo que ela agora pode ser usada por compiladores de outros fabricantes para aproveitar o poder das GPUs (graphics processing units).

"Estamos vendo cada vez mais gente procurando tirar proveito das GPUs em suas aplicações", disse Tony Goodhew, gerente de produto na Microsoft para o Visual Studio.

A proposta do C++ Accelerated Massive Parallelism (C++ AMP), primeiro desenvolvido para o Visual Studio 11 e liberado junto com a versão preliminar desse software para desenvolvedores em setembro, é permitir que os programadores C++ possam escrever programas que executem em paralelo em ambientes computacionais heterogênios.

Agora, ele é livre para ser utilizado por outros fabricantes de compiladores C++, como a Embarcadero, Intel, e a Free Software Foundation.

Cada vez mais, os fabricantes de GPU, tais como a Nvidia, vêm oferecendo suas GPUs para incrementar a performance de programas, auxiliando a CPU a concluir tarefas que demandam muitos cálculos. Tradicionalmente, programar para computação paralela tem sido uma tarefa complicada, apenas dominada por codificadores altamente especializados que normalmente trabalharam com super computadores em laboratórios ou empresas do mercado financeiro.

Com o C++ AMP, "Não precisarei ser um especialista altamente treinado para alcançar esse hardware," diz Goodhew.

Os engenheiros da Microsoft trabalharam para minimizar a quantidade de mudanças em relação à versão canônica do C++. O C++ AMP realmente traz algumas restrições adicionais necessárias quando se executa um código através de múltiplos processadores. Ele também tem recursos adicionais, como tipos array multidimensionais, bem como suporte para transferência assíncrona em memória, memória compartilhada e sincronização.

Em sua implementação, a Microsoft usou a biblioteca DirectCompute para DirectX do Windows para interagir com as GPUs, embora os fabricantes de compiladores possam se valer de outras interfaces para GPU, como a Cuda da Nvidia. Segundo Goodhew, embora esta versão do AMP tenha sido projetada especificamente para GPUs, ela também assenta as bases para eventualmente suportar outros tipos de aceleradores de hardware.

A especificação está publicada sob a licença Microsoft Community Promise.

A Microsoft lançou o C++ AMP em setembro passado, como parte da versão prévia para desenvolvedores do Visual Studio 11, depois de ter anunciado em junho a intenção de abrir a especificação para o mercado. A próxima release do Visual Studio 11 Beta incluirá suporte adicional para a especificação, que foi apresentada pela empresa sexta-feira na conferência GoingNative 2012 C++, ocorrida semana passada em Redmond, Washington.

A companhia está trabalhando com o comitê de padronização do C++ na esperança de que o grupo usará as ideias do C++ AMP como parte do núcleo da especificação da linguagem C++. Levará um tempo até que isso ocorra, entretanto, dado o longo intervalo entre as atualizações no padrão. A versão mais recente do padrão para o C++, informalmente chamada de C++2011, foi lançada no ano passado, no que foi a primeira grande mudança em quatro anos.

O documento com a especificação do C++ AMP está disponível no formato PDF neste link.