Olá Pessoal,

Aproveitando a deixa da palestra, vou falar hoje um pouco dessa pequena grande promessa: JavaFX.

O que é JavaFX?

Uma linguagem de programação. Apenas isso. Quer dizer, não é bem “apenas” por inúmeros motivos, mas o que faz ela não ser “apenas mais uma linguagem” acredito ser uma coisa principal: ABSTRAÇÃO. E por abstração, entenda como o fato de podermos fazer coisas realmente complexas de maneira simples. JavaFX, com sua linguagem e APIs, abstrai toda a parte de GUI e multimidia de uma app de maneira bem interessante.

Pra que mais uma linguagem se já temos tantas, como Java?

Java, como linguagem, atende um propósito geral. Geral no sentido de que ela nos permite construir aplicações para TUDO (celular, tv, blu-ray, desktop, microcontroladores), sem precisarmos recorrer a outra tecnologia (exceto em casos que precisamos de recursos nativos). Mas ainda assim, ela nos atende muito bem. Daí vem a pergunta: por que mais uma linguagem? A resposta é: ESPECIALIZAÇÃO. Você pode cortar carne com um canivete, mas acredito ser bem mais apropriado (por facilitar o corte) utilizar uma faca bem amolada para tal atividade. Da mesma forma, o Java se vira bem em interfaces gráficas, mas JavaFX por ser mais especializado, proporcionaria uma facilidade maior no desenvolvimento de GUIs mais amigáveis.

RIA e a evolução da Web

O termo RIA (Rich Internet Applications) veio para definir um novo conceito de mãos dadas com a evolução da Web e toda essa participação do usuário na geração de conteudo da rede. Hoje em dia, podemos observar que o conteúdo da internet quase que em sua totalidade é feito pelos próprios usuários através de blogs, foruns, microblogs, fotologs, redes sociais, etc. Essa “valorização” do usuário , elevando-o de mero observador a um administrador e editor, fez com que as antigas páginas web se transformassem em verdadeiras aplicações. Aplicações Web (Web Applications), por assim dizer. Pois além de simplesmente exibir conteúdo, agora elas tem que se preocupar também com controle de autenticação de usuários, gerenciamento de conteúdo, regras de negócio e tudo mais que uma aplicação precisa suportar.

O browser em si só entende HTML, CSS e Javascript. Então percebeu-se que era necessário estender essas funcionalidades do browser para a adoção de novas tecnologias. Java já tinha algo desse tipo com os queridos Applets, ao qual você instalava uma Java Virtual Machine e então seu browser adquiria a capacidade de executar aplicações Java, fazendo com que a interface fique mais “rica” em detalhes e em experiência.

Essa abordagem tinha alguns contras pois deixava o carregamento do site meio lento. Assim, a empresa francesa Macromedia veio com uma tecnologia muito inovadora: o Flash Player. Ele, como uma tecnologia baseada em desenho vetorial e animações, era muito mais rapido, além de possuir uma gama de componentes bem desenhados e agradaveis visualmente. Acredito que essa foi a primeira grande revolução no desenvolvimento de interfaces para Web, o que provocou toda essa nova onda de tecnologias.

E onde o JavaFX entra nisso tudo?

Ela é a linguagem que a SUN Microsystems desenvolveu para entrar no mercado de tecnologias RIA. Ela ainda continua utilizando a Virtual Machine, como os antigos Applets, mas a partir da versão 1.6_10 a JVM sofreu diversas melhorias e entre elas houve uma grande preocupação com seu desempenho na nos browsers. Uma das coisas mais interessantes é a interação entre a JVM do browser e do desktop, que permite entre outras coisas, que se arraste uma aplicação do browser para o desktop e, se fecharmos o browser, a aplicação continua rodando normalmente.

A linguagem é também OO assim como Java. Sua grande característica é sua sintaxe, totalmente inovadora. Um exemplo de código:

public class Fly extends CustomNode {

// Have the invoker set these to be the maximum width and height
 // that they would like the fly to travel (basically the screen borders)
 public-init var width : Number;
 public-init var height: Number;

// Create the utility that lights our fly up
 var flyLighter = Lighter { }

// Create a fly
 var fly = Circle
 {
 // Bind the color of the fly to the ligher
 fill: bind flyLighter.flyColor;
 // Set up the standard characteristics
 stroke: Color.AQUAMARINE;
 strokeWidth: 2;
 radius: 6;
 }

// Override the base node creation
 override function create():Node {
 // Start the lighter immediately
 flyLighter.startLighter();
 // Create the flight path and start the animation of that path up
 Flight{ fly:fly
 height:height
 width: width}.createAndPlayAnimation();
 // Return our fly as the node
 return fly
 }
 }

Links, links e mais links…

http://www.javafx.com/
http://www.javafree.uol.com.br/f-68-JavaFX.html
http://jfxstudio.wordpress.com/
http://www.javafxgame.com/

E um tópico bem legal, feito pelo meu amigo William Antônio no JavaFree

http://javafree.uol.com.br/topic-874710-Quer-aprender-JavaFX.html

Olá pessoal,

Hoje venho falar de uma tecnologia muito interessante e que vem sendo adotado cada vez mais em arquiteturas de aplicações enterprise, o SOA – Service Oriented Architeture (Arquitetura Orientada a Serviços). O objetivo desse artigo é mostrar a necessidade da adoção dessa abordagem, além das dificuldades encontradas em sua implementação.

O que é SOA?

Como o nome diz, SOA é um estilo de arquitetura que é orientada a serviços, ou seja, ela possui como princípio fundamental o fato de que as funcionalidades implementadas pelas aplicações devem ser disponibilizadas na forma de serviços. As aplicações interagem entre si utilizando um protocolo que define toda a estrutura desses serviços. Um protocolo muito popular é o SOAP (Simple Object Access Protocol) que, por meio de um arquivo WSDL (Web Service Definition Language), define uma maneira comum de conversação entre as aplicações e os serviços. Esses serviços são gerenciados e conectados normalmente por um ESB (Enterprise Service Bus) que disponibiliza interfaces por meio de WebServices. Vale lembrar que SOA não é a tecnologia. Ela é uma arquitetura que se baseia em serviços como forma de troca de mensagens e pode ser implementada com qualquer tecnologia padronizada baseada em web como por exemplo SOAP, REST, WSDL, WebServices.

Serviço

Um serviço, no mundo SOA, é uma funcionalidade ou função disponibilizada para qualquer sistema. Ele deve ter uma interface bem definida, uma espécie de contrato do tipo “você me passa tais parâmetros, que eu te devolvo esse resultado”. Imagine uma declaração de método em uma linguagem qualquer (Java, por exemplo):

public Integer somar(Integer n1, Integer n2) {
 return n1 + n2;
}

Acima temos definido o seguinte contrato: “me passe 2 números inteiros que eu te devolvo a soma dos mesmos”. Essa declaração simples de método pode perfeitamente representar um serviço (claro que com sua devida infraestrutura). Este por sua vez, disponibilizado na web em um servidor de aplicação (como o Glassfish, por exemplo) é chamado de WebService. Este WebService poderá ser “consumido” (ou executado) de qualquer outra aplicação que entenda o protocolo SOAP (e siga o contrato do WSDL).

O WSDL define o contrato (parâmetros de entrada e retorno) a ser utilizado entre as duas aplicações. O processo de consumação de um serviço é conhecido como “Find-Bind-Execute” e segue um paradigma bem definido para sua concretização.

No fim das contas, onde eu uso isso?

Um dos cenários mais indicados para a utilização de uma arquitetura desse tipo, é na integração de sistemas legados, onde um não faz a mínima idéia da existência do outro. A criação de interfaces de serviços de ambos os lados permite um intercâmbio de informações sendo trafegadas de maneira transparente para as aplicações. No meio disso tudo, pode existir um software chamado ESB, ao qual faz o roteamento e promove a conversação entre esses vários sistemas, servindo como um middleware, pois faz o “meio-de-campo” entre as aplicações. Uma outra funcionalidade muito importante do ESB é a abstração das cadeias de chamadas de serviços (vários serviços numa ordem definida, como sendo um só).

Eu já vi isso em algum lugar…

Sim, naquelas máquinas de cartão. As empresas que possuem o serviço (Redecard, Visa, American Express) possuem um serviço disponível na web que autentica e valida transações de usuários. Quando você digita sua senha numa máquina, ela envia uma requisição para o servidor da bandeira correspondente, perguntando se: a máquina está autorizada a realizar requisições (se está com a mensalidade paga, etc.), se a senha informada é válida e se o cliente tem saldo suficiente na conta para realizar aquela operação. O serviço, por sua vez, responde sim ou não. O mesmo serviço fica disponível para consumo em qualquer plataforma que entenda o contrato que a bandeira possui, como por exemplo uma loja virtual.

Já que é tão legal, por que todo mundo não sai implementando?

Imagine que, para isso tudo funcionar, é requerida uma grande infraestrutura, servidores de aplicação robustos e muito, muito conhecimento técnico. Isso custa caro. Muito caro. E, principalmente, essa arquitetura não é aplicável a todas as situações, como muitos “profissionais” de TI pensam (claro que vender uma solução desse porte pode render muito $$$$). Outro grande problema é a complexidade técnica necessária para a implementação de algo desse tipo, as consultorias cobram caro e nem sempre sai como o esperado.

Olá pessoal,

Venho hoje aqui falar de um dos eventos mais importantes para a comunidade Java, o Sun Tech Days. Eu tive a oportunidade de comparecer ao primeiro dia do evento em São Paulo (do ladinho do meu trabalho) e posso dizer que foi muito legal poder participar de um evento desse porte. Lá tivemos palestras, labs (hands-on), stands, brindes e ainda interagimos com muitas pessoas, inclusive estrangeiros que foram especialmente para o evento.

Palestras

Quanto as palestras, achei bem legal o esquema que montaram, com tradução simultânea ocorrendo em diversas palestras ao mesmo tempo. Com o aparelho, você conseguia sintonizar uma das 3 palestras que estavam rolando no momento. O problema as vezes era que o tradutor, pelo jeito, não tinha conhecimento nenhum sobre o assunto, ocasionando algumas bizarrices do tipo “cache” do processador ser traduzido como “dinheiro” (cash) do processador. Mas a maioria dos palestrantes falava devagar, possibilitando o entendimento mais facilmente. No começo houveram demonstrações de JavaFX (um editor muito interessante no estilo Flash) e uma luva especial para Touch Screen numa superficie que rodava uma app feita em JavaFX.

Houve muito Open Solaris no evento. Se você o instalasse em seu notebook (normalmente no VirtualBox), ganhava uma camiseta, além de livros e mais livros sobre o SO da Sun. Palestras não faltaram abordando esse tema.

James Gosling

Houve também uma palestra com o “Java’s Dad” James Gosling, ao qual ele deu enfoque nas novidades que estavam surgindo (JavaFX, JEE 6, Java 7, Glassfish V3, NetBeans 6.8, etc.). Pude observar nele um certo carinho pelo Glassfish – “Glassfish is not a toy” – disse ele algumas vezes, devido ao grande questionamento se este era mesmo um AppServer escalável e profissional, talvez por ser a implementação de referência do JEE.

Brindes

Bom mesmo foram os brindes (rs). Eu ganhei uma miniatura do Duke, algumas camisas, muitas revistas, livros, além de ter comprado uma mochila bem legal da Sun.

Uma coisa legal foram as camisas que preparamos com o tema do OSUM, criado pela nossa talentosa amiga Dru. Créditos também para a Marcela que correu atrás da confecção da camisa (em tempo recorde!).

O pessoal ficou bastante empolgado com o evento, acredito que tenha sido bem interessante para todos presentes. A tendência é agora participarmos mais desse tipo de encontro, para a comunidade ter mais contato com as novidades que vem surgindo. Temos ainda muito trabalho pela frente, mas pude ver nessa experiência que podemos crescer de uma maneira bem interessante, dado o potencial das nossas pessoas.

Abraços e até a próxima!

topo

Olá pessoal,

Nos próximos dias 8 e 9 de dezembro, será realizado em São Paulo um dos maiores eventos tecnológicos de programação do mundo, Sun Tech Days. Você que é estudante e/ou profissional da área de TI não pode perder a oportunidade de conhecer grandes profissionais da área, além de interagir com várias outros desenvolvedores, compartilhando experiências e ampliando seu networking.

O pai do Java

goslingEsse evento contará com um atrativo a mais, uma presença ilustre. Nada mais, nada menos do que James Gosling, considerado o “pai” da linguagem e plataforma Java.

Gosling é Bacharel em Ciências da Computação pela Universidade de Calgary, Canadá e Ph.D. em Ciência da Computação pela Carnegie-Mellon University, quando defendeu sua tese intitulada “A Manipulação Algébrica das Restrições”. Construiu sistemas de aquisição de dados via satélite, uma versão multiprocessador do Unix, vários compiladores, sistemas de email e gerenciadores de janela. Ele também desenvolveu o editor de texto WYSIWYG, um editor de desenhos restritos e um editor de texto chamado ‘Emacs’ para sistemas Unix. Na Sun, começou como engenheiro líder do sistema de janelas NeWS. Foi ele que fez o design original da linguagem de programação Java e implementou o seu primeiro compilador e máquina virtual. Em fevereiro de 2007, James foi nomeado um oficial da Ordem do Canadá.

Install Fest

No evento será possível também levar seu notebook para a instalação gratuita da versão mais atualizada do OpenSolaris. No site oficial ainda fala que tem brinde!

Requerimentos para instalação:

  • Memória mínima recomendada: 512MB;

  • Disco de 4GB de disco;

  • Processadores recomendados: Intel ou AMD.

Você também pode instalar o OpenSolaris no VirtualBox (http:/www.virtualbox.org) .

Sessões

O Sun Tech Days contará também com uma série de sessões práticas sobre os mais diversos assuntos, abaixo seguem alguns deles (a lista completa pode ser vista no menu Sessões do site oficial):

  • JavaEE 6: A nova geração para a Plataforma de Aplicações Corporativas (Destaques do JavaEE 6);

  • Introdução ao JavaFX;

  • Desenvolvimento e Implementação de Clientes WebServices em REST (Clientes e Segurança);

  • JDK7: O que ficou e o que não ficou;

  • Melhores Práticas e Ajuste de Performance AJAX;

  • Programação JavaFX para Dispositivos Móveis.

Inscrições

As inscrições podem ser realizadas no site oficial do evento (http://www.suntechdays.com.br) até o dia 3 de dezembro. Em caso de dúvidas, entre em contato com o time do Sun Tech Days pelo e-mail techdays@sun.com.

Local

Amcham Business Center – Rua da Paz, 1431 – Chácara Santo Antônio / São Paulo – SP
CEP: 04713-001
Fone: 55 11 5180 3730
www.amcham.com.br



Hoje vou falar de um dos recursos mais interessantes, encontrados nas linguangens que rodam sobre a plataforma .NET, os Delegates. Delegates também podem ser encontrados em Javascript, C e C++, sendo algo que facilita o desenvolvimento em diversos cenários. Há pouco tempo, quando me veio a idéia de fazer esse post, me deparei com uma dúvida referente a Delegates vs Closures (algo que pode ser conferido aqui e aqui).

Delegates (eu já vi isso em algum lugar… ponteiros de função???)

No fim das contas sim, Delegates são referências que apontam para um método específico que podem ser guardadas em variáveis e até passadas como parâmetro para outros métodos. A grande diferença entre ponteiros de função e os Delegates do C# é que os Delegates são Type Safe, ou seja, delimitam em tempo de compilação o tipo do retorno e dos parâmetros que o método deverá possuir para ser atribuido aquele Delegate.

//Delegate
public delegate void DelegateExemplo(string parametro);

//Método
public  void MetodoExemplo(string parametro)
{
 Console.Writeln(parametro);
}

//Utilização
DelegateExemplo Del = MetodoExemplo;
//ou
DelegateExemplo Del = new DelegateExemplo(MetodoExemplo);
Del("teste");

//Ele também pode ser passado como parâmtro para outro método
public void TesteDelegate(string parametro, DelegateExemplo del)
{
 del(parametro);
}

//Temos também no .NET Framework 3.0 delegates anonimos:
TesteDelegate("teste", delegate(string parametro) { Console.Writeln(parametro) });

Um delegate é um método declarado no mesmo escopo dos outros métodos e somente captura o objeto referente à classe onde foi declarado, diferente de Closures, que capturam todo o contexto em que elas estão inseridas. Quem conhece Javascript, C ou C++ sabe como esse recurso pode ser utilizado de maneira interessante.

public class TesteDelegates
{
 public void Main()
 {
 new Thread(delegate() {while(true) {Console.Writeln("Usando Delegate");}}).Start();
 }
}

A grande vantagem de utilizar delegates, é que você não precisa passar um objeto inteiro como parâmetro para utilizar apenas um comportamento (método) específico, economizando um bom esforço com a criação e instanciação do objeto ao qual se deseja invocar o método. Java possui uma enorme “deficiência” em relação a essa característica, ao qual procura compensá-la com a utilização de Annonimous Inner Classes:

public class TesteDelegates {
 public static void main(String[] args) {
 new Thread(new Runnable() {
 public void run() {
 while(true) {
 System.out.println("Usando Annonimous Inner Classes");
 }
 }
 }).start();
 }
}

Em Javascript utilizamos esse recurso quando declaramos objetos:

function TesteDelegates {
 this.teste = function() { alert('Teste'); }
}

Conclusão

Esse post falou sobre delegates, um recurso muito interessante, que pode ser observado em diversas linguagens. Ele possui certa semelhança com Closures, diferindo apenas em questão de acessibilidade de escopo. Java, como pudemos ver, utiliza classes anônimas para representar códigos onde os delegates podem ser aplicados. Isso é algo que, em meu ver, dificulta um pouco a expressividade e legibilidade do código. Em breve falarei um pouco sobre os recursos de Event Handling em .NET, algo que está intimamente ligado com os delegates. Abraços e até a próxima.

Essa série de posts irão discorrer sobre um tema muito discutido na web, algo que gerou certa “polêmica” para quem sempre teve como base o uso de Design Patterns em seus projetos. Seria ou não Singleton um anti-pattern? Bom, para tomarmos qualquer tipo de decisão nesse sentido devemos primeiro nos ater aos conceitos principais: o que é um Singleton e o que é Injeção de Dependência.

A série está dividida em 3 partes, sendo que a parte 1 demonstrará a motivação e a utilização do Singleton, além de suas vantagens e desvantagens na implementação do pattern. Já a parte 2 introduzirá o conceito e aplicações do IoC ou Inversão de Controle, além de frameworks Java que possibilitam sua utilização. Finalmente a parte 3 fará um balanço das duas abordagens, mostrando o que uma tem a ver com a outra, além de algum código para comparação.

Singleton

Esse Design Pattern pertence a categoria chamada “Criacional”, pois cuida da maneira que determinados objetos são criados. Ele é um dos mais simples dentre os padrões propostos pela Gangue dos Quatro, sendo amplamente utilizado, em alguns casos até de maneira abusiva.

Seu propósito é prover um mecanismo para que classes permitam criar apenas UMA ÚNICA instância na aplicação. Esse tipo de abordagem permite a criação de técnicas de cache por exemplo, mas temos que tomar cuidado em seu uso, pois muitas vezes esse Singleton acaba fazendo o papel de um tipo de “variável global”, algo bem estranho do ponto de vista Orientado a Objetos, até porque essa não é a responsabilidade do pattern, definido pela Gangue dos Quatro.

Exemplo do uso de um Singleton

Imaginemos um cenário de uma camada de abstração de um banco de dados (um DAO – Data Access Object, talvez) de uma aplicação qualquer. Teríamos uma classe DAO para cada entidade do sistema (ClienteDAO, ProdutoDAO, PedidoDAO por exemplo) onde teríamos métodos do tipo findById(Integer id), findByExample(DAO example), findAll(), etc.

class ClienteDAO {

public boolean create(Cliente cliente) { }

public Cliente findById(Integer id) { }

public List<Cliente> findAll() { }

}

Até aí tudo bem, mas sabemos que para qualquer tipo de operação realizada no banco de dados, precisamos abrir uma conexão e passá-la para que o comando (INSERT, UPDATE, DELETE, XPTO) possa ser executado no SGBD. Um jeito simples de resolver isso é criar uma classe MySQLConnection, onde temos método do tipo getConnection(), closeConnection(), onde teríamos a abstração da conexão que necessitamos.

import java.sql.*;

class ClienteDAO {

public boolean create(Cliente cliente) {
try {
Connection conn = MySQLConnection.newConnection().getConnection();
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO TB_CLIENTE VALUES (?, ?)");
pstmt.setInt(cliente.getId());
pstmt.setNome(cliente.getNome());
} catch(SQLException ex) {
ex.printStackTrace();
} finnaly {
pstmt.close();
conn.close();
}
}
}

O que podemos fazer para que a instância de conexão seja única para a aplicação inteira? A primeira vista, resolvemos isso transformando a classe MySQLConnection em um Singleton.

import java.sql.*;

public class MySQLConnection {

private static MySQLConnection conn;
private Connection sqlConn;

private MySQLConnection() {

try {
Class.forName("com.mysql.jdbc.Driver");
sqlConn = DriverManager.getConnection("url", "user", "pass");
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
}
}

public static MySQLConnection newConnection() {
if(conn == null) {
conn = new MySQLConnection();
}

return conn;

}

public Connection getConnection() {
return sqlConn;
}

public void closeConnection() {

try{
conn.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
}

Que legal, agora temos uma bela implementação de um Singleton!

Opa, problemas a vista…

Bom, o Singleton realmente garante UMA instância na memória. Mas há um problema. Pense o que poderia acontecer se houvessem várias Threads disputando essa instancia. Mas espera! Podemos sincronizar o método! Threads não serão mais problemas de agora em diante!

Bom, eu sou chato. A primeira abordagem resolve o problema das Threads (apesar de causar um overhead a cada chamada do método Singleton), mas ainda há um problema. O Singleton é único POR CLASSLOADER. E o que isso implica? Pensando num ambiente JEE, temos o nosso container JEE (Tomcat, JBoss, Weblogic, Glassfish, etc…) que segue a especificação… advinha… JEE! Mas como o JEE é uma especificação, ele não diz COMO deve ser a implementação. Se seu Container Web favorito internamente aloca diversos classloaders, por performance talvez (sei lá, essa possibilidade não é tão remota assim), isso quer dizer que teremos uma instancia de seu Singleton para cada classloader. Pronto, quebrou nosso esquema. Outro cenário em que temos esse problema é num cluster, onde cada máquina contém uma Virtual Machine diferente, e por consequência, um classloader diferente para cada JVM.

Não bastando esses problemas, e pensando agora no conceito de Orientação a Objetos, porque queremos ter um objeto de instancia única no sistema? Será que existe algum desses no mundo real?

Não sei se é tão vantajoso assim usarmos Singleton, apesar de que em muitos casos ele é uma solução simples que resolve o problema (nem sempre teremos clusters, nem multiplos classloaders, ou estaremos num ambiente JEE de verdade!). Uma busca no google por “singleton anti pattern” pode nos trazer muito mais assunto sobre isso.

Acabou?

Sim, a parte 1 termina aqui, onde vimos como e porque usar (e não usar) o Singleton. Recomendo fortemente uma leitura em artigos na web sobre “singleton anti pattern” e “singletonitis”, ao qual serão muito interessantes em questão de esclarecer todo esse “preconceito” dirigido a esse pattern.

Abraços a todos e espero vocês na parte 2.

Olá pessoal,

Devido a correria de sempre fiquei fora daqui por uns tempos, mas estou voltando para postar sobre um mini-projeto que venho desenvolvendo há um tempo e só agora pude acabar: o JDaVelha, uma implementação de jogo da velha feito com Java que pode ser jogado em rede.

Espero que gostem e que o projeto lhes seja útil de alguma maneira. Abraços.

[EDIT] Para aqueles que desejarem baixar o código fonte, deverão ter o subversion instalado. O projeto foi desenvolvido com o Java 1.6.0_16-b01 no NetBeans 6.7.1.

Endereço: http://jdavelha.googlecode.com/svn/trunk jdavelha-read-only

Olá pessoal,

Hoje vou falar sobre O/R Mapping (Mapeamento Objeto/Relacional), suas características, vantagens, desvantagens e como essa abordagem é utilizada, além de frameworks que tem como objetivo suprir essa necessidade.

Mapeamento?

Sim, mapeamento. Pelo nome, podemos observar que relacional refere-se a base de dados e objeto refere-se à linguagem que é orientada a objetos. No final das contas estamos tentando juntar os dois: nossa aplicação desenvolvida num contexto orientado a objetos e nossa base de dados desenvolvida num contexto relacional. Dizemos mapeamento porque acabamos mapeando nossos objetos com nossas tabelas, algo que, se feito de maneira displiscente, pode causar uma estrutura de domínio fraca e deficiente devido a separação dos dados em relação as regras de negócio.

Como funciona

O conceito é relativamente simples, o complicado mesmo é desenvolver toda a infra estrutura que realiza o trabalho sujo por baixo dos panos. Basicamente temos nossas entidades de negócio, definidas na fase da análise com seus atributos e comportamentos, além de nosso banco relacional, com suas tabelas, campos e registros. A abordagem consiste em atribuir uma tabela para cada entidade e cada atributo da entidade para cada campo da tabela. Simples assim. Dessa maneira conseguimos abstrair o lugar e a maneira que os dados são obtidos / persistidos, pois não precisamos nos preocupar com comandos SQL (afinal eles estão abstraidos em simples métodos save() ou find()), possibilitando o manuseio dos objetos devidamente preenchidos num contexto de negócio totalmente orientado a objetos. Essa atribuição tabela / entidade não precisa ser realizada de maneira explícita, mas uma abordagem interessante é a configuração desse mapeamento em um documento XML ou qualquer outro tipo de técnica que contenha metadados (Annotations, por exemplo, nos Javas 5+). Assim podemos dizer que a tabela “TB_PEDIDO” tem correspondencia com a classe “Pedido” e que o campo “dt_compra_pedido” representa o atributo “data” no objeto Pedido.

Vantagens

A grande sacada da utilização dessa abordagem é o nível de abstração das operações com os dados, pois dependendo da estratégia utilizada, temos a nítida sensação de que estamos trabalhando com os dados sempre em memória, devido as chamadas a base estarem totalmente isoladas e “automáticas” do ponto de vista da camada de domínio da aplicação. Em Java, temos o JPA (Java Persistence API), que descreve uma especificação dizendo como os fabricantes devem desenvolver seus frameworks, algo que é muito interessante, pois isso possibilita a troca de uma implementação por outra quase sem alterações (a menos que esteja usando algum recurso fora da especificação). Se mudamos nossa base Oracle, podemos trocar nosso ORM de Hibernate para TopLink, por exemplo, em troca de um possível ganho de performance. Em outras linguagens temos o ADO.NET para .NET, ActiveRecord para Ruby, no próprio Java temos IBates, etc.

Desvantagens

Como nem tudo são flores, temos alguns contras que existem quando se decide usar algum tipo de ORM. A primeira grande desvantagem é a performance. Num ambiente relacional, temos todos aqueles algorítimos que os bancos de dados usam para a recuperação dos dados, são de longe muito mais performáticos do que qualquer outro tipo de tratamento dos dados na aplicação. Outra desvantagem é a complexidade e o nível de entropia que é necessário para construir-se um bom design. Não é tão simples desenhar a arquitetura de um sistema utilizando uma estratégia desse tipo, o que pode ocasionar designs fracos e ruins, como disse anteriormente. As vezes, utilizado de maneira incorreta, o mapeamento pode acabar separando das entidades os dados e as regras de negócio. Do ponto de vista OO isso é um pouco estranho, pois um carro, por exemplo, contém tudo dentro de um objeto carro, certo? Ou na vida real existe um objeto Carro e outro DadosCarro? Para resolver esse problema podemos recorrer a alguns padrões (Factory, DAO, Repository), mas como percebe-se, a complexidade foi elevada.

E então, vale a pena?

Como em informática é um pouco complicado definir o certo e o errado, posso dizer que vale a pena, mas isso não significa que é a verdade absoluta. Existem pessoas que usam e existem pessoas que não usam. Ambas são felizes e suas abordagens funcionam. A grande sacada é observar no teu cenário se as vantagens de uma vão suprir, além das vantagens da outra, as suas próprias desvantagens. Sendo assim, recomendo o estudo dessa estratégia, pois ela pode ser realmente útil em muitos casos.

Abraços, e até a próxima!

Olá pessoal,

Hoje vou falar sobre um conceito muito interessante, presente em Ruby e em algumas outras linguagens dinâmicas que consiste em ter suas classes “abertas”. É um recurso que facilita a vida do desenvolvedor/analista/arquiteto na hora de modelar e definir as classes/interfaces do sistema.

O que são classes abertas?

Primeiro vamos entender como funciona o mecanismo de classes do Java, por exemplo, que é uma linguagem que não possui essa característica. Temos a tão conhecida classe Integer. Ela foi definida por um fulano da Sun com sua lista de métodos e atributos e servia muito bem para a realidade da época em que foi criada. Mas hoje eu preciso de um jeito de descobrir se o número que esse objeto representa é par ou ímpar. Ah, podemos criar um IntegerUtils com um método estático isEven(Integer n1, Integer n2). Certo? Ah até podemos, mas cheira a procedural orientado a objeto… não parece tão agradável assim. Outra solução: podemos estender a classe, algo como MyInteger extends Integer. Mas espere, Integer (e todas as classes Wrappers) não são final? Ah então vamos usar a composição! No final das contas ficaria assim:

package main;

public class MyInteger {
private Integer number;

public MyInteger(Integer number){
this.number = number;
}

public boolean isEven(){
return number % 2 == 0;
}
}

Hum, não sei se ficou tão bom assim… toda vez que quisermos usar esse método teremos que encapsular o Integer dentro de MyInteger. Isso seria um pouco incomodo.

A solução

Sabemos que na hora da modelagem das classes é muito complicado para o profissional definir quais elementos são relevantes e devem estar presentes nos objetos. Como as necessidades mudam, talvez o que seja necessário hoje não atenda as necessidades de amanhã, mas não temos como prever o QUE irá mudar. Seria bom se pudéssemos abrir e adicionar métodos as nossas classes sempre que quisermos, mas nem sempre é possível, vide exemplo da classe Integer.

class Integer
def is_even
return self % 2 ==0
end
end

i = 50
puts i.is_even

Este código mostra como podemos estender a linguagem de uma maneira mais elegante, sem a necessidade da criação de classes utilitárias lotadas de métodos estáticos (StringUtils da apache, Collections do pacote java.util, classe Math e por aí vai) . Esse conceito, junto com a possibilidade trabalhar com blocos de código sendo objetos, pode ser muito bem aproveitada na criação de estruturas arquiteturais reutilizáveis, APIs, frameworks, etc…

Espero que tenham gostado,  até a próxima!

Olá pessoal,

Hoje vou falar sobre um pattern comportamental que, na minha opinião, está entre os mais interessantes descritos pelo GoF: o Observer Pattern. Vamos descrevê-lo e mostrar alguns cenários onde ele se encaixa como uma luva, além de um pouco de código, utilizando-o na prática.

Definição

A grosso modo, o Observer Pattern provê um relacionamento  um-para-muitos entre objetos com baixíssimo acoplamento, com a condição de que algumas interfaces sejam implementadas. É composto por uma entidade principal, que de acordo com as mudanças de estado notifica outras entidades dependentes. A entidade principal, que pode ser chamada de Observable ou Subject, não conhece nada das classes dependentes (Observers), apenas que elas implementam uma interface específica.

Observer - Diagrama de ClassesObserver – Diagrama de Classes

Uma aplicação prática

Vamos a um exemplo simples, mas que demonstra a funcionalidade do padrão. Temos uma aplicação que realiza, por exemplo, a leitura de um arquivo de texto e insere cada linha desse arquivo em uma tabela do banco de dados. Até uma certa quantidade de linhas, a inserção será relativamente rápida, mas conforme essa quantidade aumenta, o processamento vai ficando cada vez mais lento e demorado. Suponhamos que ao apertar um botão, seja iniciado o processo e a janela fica travada, esperando o fim do método que se encarregou de fazer toda a lógica.

//um monte de código aqui...
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
processoParse.iniciarProcessoParse();
}
});
//mais outro monte aqui...

Bom, podemos criar uma nova thread para que o processo seja executado de maneira independente, pois desse modo,  janela poderia ser utilizada enquanto o processo realizado, já que a mesma não se encontraria mais travada.

//um monte de código aqui...
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
Runnable runn = new Runnable(){
public void run(){
processoParse.iniciarProcessoParse();
}
};

Thread processo = new Thread(runn, "ProcessoParse");
processo.start();
}
});
//mais outro monte aqui...

Obs.: Talvez essa não seja a maneira mais OO de resolver esse problema, mas para fins de exemplo deve servir.

E onde entra o Observer nessa história?

Em lugar nenhum. O problema do travamento foi resolvido. Mas esse não era um post sobre o Observer Pattern?

Imagine que seu cliente ao ver o comportamento do sistema, deseje que, a cada insert no banco de dados, seja mostrada uma mensagem na tela, para fins de logging, pois se houver algum tipo de erro, seria exibida a mensagem informando qual foi o erro que ocorreu. Pode parecer simples, mas existe um ponto complexo nessa história: no objeto Janela temos uma referência para um objeto ProcessoParse, portanto conseguimos enviar mensagens (invocar métodos) para esse processo. O problema está em como fazer o contrário, isto é, notificar o objeto Janela das mudanças no estado do processo. O padrão Observer provê uma solução elegante para esse problema, que consiste em fazer com que a janela (ou algum outro objeto que possa tratar a notificação) se registre em uma lista de observadores (ou ouvintes) e a cada mudança de estado do processo, conseguimos enviar uma mensagem para todos os observadores, informando que ocorreu uma mudança.

//interface que define como serão os observadores
public interface ParseListener{
void notify(String msg);
}

//classe abstrata com as operações básicas de inserir,
//remover e disparar uma notificação em cada objeto
//da lista de observadores, definindo um "Observável"
public abstract class Subject{
private List<ParseListener> listeners;

public Subject(){
listeners = new ArrayList<ParseListener>();
}

public void addParseListener(ParseListener listener){
listeners.add(listener);
}

public void removeParseListener(ParseListener listener){
listeners.remove(listener);
}

protected void update(String msg){
for(ParseListener listener : this.listeners){
listener.notify(msg);
}
}
}

Com esse código, temos a estrutura básica do pattern, ao qual podemos utilizar em qualquer ocasião que se faça necessária a aplicação desse padrão. Agora vamos mostrar como podemos usufruir dessa estrutura no nosso exemplo inicial.

//aqui temos a classe processo parse estendendo a
//nossa classe Subject
//agora ela herda toda a funcionalidade de um
//Observable
public class ProcessoParse extends Subject{
public void iniciarProcessoParse(){
//um monte de código aqui...
while(linhas.hasNext()){
linha = linhas.next();
//a cada chamada do método update, os observers
//são notificados aqui dizendo que determinada
//linha foi lida do arquivo
this.update("Leu: " + linha);
this.inserirBancoDeDados(linha);
//aqui dizendo que a linha foi "parseada" e inserida no
//BD com sucesso
this.update("Inseriu com sucesso.");
}
}
}

public class Janela extends JFrame implements ParseListener{
//um monte de código aqui...
private ProcessoParse processo;

public Janela(){
//um monte de código aqui também...
processo = new ProcessoParse();
//Aqui estamos de fato registrando nossa classe na lista
//de observadore da classe ProcessoParse
processo.addParseListener(this);
}

//Como estamos implementando a interface ParseListener, somos
//obrigados a implementar também o método notify, definido na
//própria interface
//Esse método será invocado a cada atualização do estado do 
//Subject, no caso o ProcessoParse. Com ele virá uma String 
//contendo uma mensagem indicando qual registro foi 
//inserido no banco de dados
public void notify(String msg){
txtLog.append(msg);
}
}

Usos comuns

Podemos conferir o uso desse pattern em várias partes do JDK (no tratamento de eventos do Swing, por exemplo), tendo até uma estrutura pronta para ess efim, além de estar em muitos frameworks de mercado,  pois esse pattern é muito flexível a eventuais mudanças que possam ocorrer no decorrer do desenvolvimento. Por fim, lembre-se sempre de utilizar os patterns com cautela, apenas quando seu uso for imprescindível, já que eles acabam adicionando complexidade a sua estratégia.

Espero que tenham gostado, até mais!