jump to navigation

Demonstrando o uso de encapsulamento ao facilitar o uso do componente rich:tree do Richfaces 02/08/2009

Posted by fredericobenevides in JSF, Seam.
7 comments

Quando começamos a programar em java, muitas pessoas ensinam que para criar uma classe encapsulada é apenas colocar os seus atributos como private e criar getters/setters para cada um deles. Geralmente, essas pessoas no início não aprendem que encapsulamento é aquele objeto que provê operações públicas ocultando suas implementações internas, que não precisam ser conhecidas por quem usa. Um exemplo real disso, é uma pessoa utilizar um carro conhecendo apenas as suas “operações” externas (volante, acelerador, marcha, etc…) sem ter necessidade de conhecer o seu funcionamento interno.

Então, eu resolvi criar um post pra demonstrar o uso de encapsulamento ao criar uma classe que facilitará na criação de árvores.

Como criar uma árvore usando RichFaces

Para quem não conhece o funcionamento do componente rich:tree, darei breves explicações de como utilizá-lo. Essas implementações foram feitas usando o framework Seam.

Os códigos abaixo terão sempre o mesmo resultado na geração da seguinte árvore:
rich_tree

Para criar uma árvore, utilizamos o TreeNodeImpl. Cada nó da árvore devemos setar a descrição utilizando o método setData do TreeNodeImpl. É simples, porém ao adicionar cada filho de um nó, devemos preocupar com o seu identificador.

public TreeNode getArvore() {

	/* Raiz */
	TreeNode rootNode = new TreeNodeImpl();

	/* adicionando o pai1 na raiz */
	TreeNodeImpl pai1 = new TreeNodeImpl();
	pai1.setData("Pai_1");
	rootNode.addChild(0, pai1);

	/* adicionando filho1 ao pai1 */
	TreeNodeImpl filhoPai1 = new TreeNodeImpl();
	filhoPai1.setData("Filho_1");
	pai1.addChild(0, filhoPai1);

	/* adicionando filho2 ao pai1 */
	filhoPai1 = new TreeNodeImpl();
	filhoPai1.setData("Filho_2");
	pai1.addChild(1, filhoPai1);

	/* adicionando o pai2 na raiz */
	TreeNodeImpl pai2 = new TreeNodeImpl();
	pai2.setData("Pai_2");
	rootNode.addChild(1, pai2);

	/* adicionando filho1 ao pai2 */
	TreeNodeImpl filhoPai2 = new TreeNodeImpl();
	filhoPai2.setData("Filho_1");
	pai2.addChild(0, filhoPai2);

	/* adicionando filho2 ao pai2 */
	filhoPai2 = new TreeNodeImpl();
	filhoPai2.setData("Filho_2");
	pai2.addChild(1, filhoPai2);

	/* adicionando filho3 ao pai2 */
	filhoPai2 = new TreeNodeImpl();
	filhoPai2.setData("Filho_3");
	pai2.addChild(2, filhoPai2);

	return rootNode;
}

A página contendo o componente rich:tree que chama a árvore.

<rich:tree style="width:300px" value="#{tree.arvore}" var="item">
 <h:outputText value="#{item}"/>
</rich:tree>

Agora que já temos um conhecimento de como trabalhar com o componente, podemos ver que é até simples o uso, apesar de termos um pequeno trabalho ao adicionar cada filho. Logo, resolvi criar uma classe para auxiliar na construção do objeto que representa a árvore, e também para que o desenvolvedor não perdesse tempo em estudar como implementar essa construção. Afinal, quanto menor o trabalho do desenvolvedor em se preocupar com cada detalhe, mais ele agiliza o desenvolvimento.

A seguir a nova implementação usando a classe Tree para auxiliar na criação da árvore.

public class Tree<T> {

	private boolean root;
	private String description;
	private T object;

	private TreeNode<Tree<T>> treeNode;
	private List<Tree<T>> childs = new ArrayList<Tree<T>>();

	public Tree() {
		treeNode = new TreeNodeImpl<Tree<T>>();
		root = true;
	}

	public Tree(String description, T object) {
		treeNode = new TreeNodeImpl<Tree<T>>();
		this.object = object;
		this.description = description;
		treeNode.setData(this);
	}

	public void addChild(Tree<T> tree) {
		childs.add(tree);
	}

	public TreeNode<Tree<T>> toTreeNode() {
		int i = 0;
		for (Tree<T> tree : childs) {
			TreeNodeImpl<Tree<T>> nodeChild = (TreeNodeImpl<Tree<T>>) tree.toTreeNode();
			treeNode.addChild(i, nodeChild);
			i++;
		}
		return treeNode;
	}

	public boolean isRoot() {
		return root;
	}

	public T getObject() {
		return object;
	}

	public String getDescription() {
		return description;
	}

	@Override
	public String toString() {
		return description;
	}
}

public TreeNode<Tree<String>> getArvore() {

	/* criando a raiz */
	Tree<String> parentRoot = new Tree<String>();

	/* adicionando o pai1 na raiz */
	Tree<String> pai1 = new Tree<String>("Pai_1", null);
	parentRoot.addChild(pai1);

	/* adicionando filho1 ao pai1 */
	Tree<String> filhoPai1 = new Tree<String>("Filho_1", null);
	pai1.addChild(filhoPai1);

	/* adicionando filho2 ao pai1 */
	filhoPai1 = new Tree<String>("Filho_2", null);
	pai1.addChild(filhoPai1);

	/* adicionando o pai2 na raiz */
	Tree<String> pai2 = new Tree<String>("Pai_2", null);
	parentRoot.addChild(pai2);

	/* adicionando filho1 ao pai1 */
	Tree<String> filhoPai2 = new Tree<String>("Filho_1", null);
	pai2.addChild(filhoPai2);

	/* adicionando filho2 ao pai1 */
	filhoPai2 = new Tree<String>("Filho_2", null);
	pai2.addChild(filhoPai2);

	/* adicionando filho3 ao pai1 */
	filhoPai2 = new Tree<String>("Filho_3", null);
	pai2.addChild(filhoPai2);

	return parentRoot.toTreeNode();
}

Como podemos ver, o código ficou mais simples e mais limpo para a criação da árvore. Para adicionar cada filho não houve necessidade de preocupar com o identificar numérico. A codificaçao ficou mais simples, porém produtivo.

Os getters foram criado apenas onde houve necessidade. Caso também fosse permitido o acesso ao treeNode, quebraria o encapsulamento, pois o desenvolvedor poderia modificar seus dados, sendo que apenas a classe Tree é o responsável para modificar.

Por fim, a classe está bem encapsulada, já que o desenvolvedor não tem necessidade de conhecer o funcionamento interno, ele tem apenas que conhecer as suas operações públicas.

Falando em Java 2009. Eu vou! 20/05/2009

Posted by fredericobenevides in Palestras.
add a comment

Falando em Java 3 edição

Domingo agora, dia 24, estarei indo assistir as palestras do Falando em Java, uma das melhores palestras do ano. Felizmente poderei estar em SP para participar dessas palestras já que as outras que teve eu não pude ir. Infelizmente em Brasília tá devendo palestras dos níveis que já teve em SP.

Falando em Java terá duas palestras internacionais. Uma com o Bill Burke, lider do desenvolvimento do Jboss RESTEasy e outra com o Dr. Jim Webber, diretor dos serviços profissionais da ThoughtWorks. Não vejo a hora de assistí-las, principalmente sobre REST que curto muito.

Quero saber sobre as novidades do VRaptor 3, pois curto muito este framework.

Bem, o resto da programação se encontra no site: http://www.caelum.com.br/falando-em-java/programacao.html

É isso aí… Quem for participar, nos vemos lá!

Xbox 360. Muito mais que um video game. 09/04/2009

Posted by fredericobenevides in jogos.
1 comment so far

Não poderia deixar de passar um post para falar desse video game. Não irei fazer uma análise, mas apenas comentários do mesmo.

Para quem não sabe, peguei meu xbox na segunda passada. Peguei a versão Xbox 360 Special Edition Resident Evil.  Esse xbox é a versão elite que vem 2 jogos, resident evil e Super Street Fighter II Turbo HD Remix para baixar pela live.

Ele é da cor vermelha como podem ver nas seguintes fotos:

Bem, por que um post sobre esse video game ? Primeiramente, adoro jogos  e, desde criança cresci jogando video games. Apenas, na geração passada (Playstation 2, Game Cube e Xbox ) que não joguei. Por isso, até que sentia um pouco falta de jogar alguns jogos que sai apenas em video games. Infelizmente os que saem para PC, alguns não rodam direito na minha máquina e não estou nem um pouco animado para um upgrade, pois o dinheiro vai ser usado em um notebook.

Nessa geração eu resolvi começar com o wii, sabe, aquela famosa propaganda sobre a jogabilidade. Então no ano passado comprei e até que curti muito alguns jogos, principalmente Resident Evil 4. Ótimo jogo e a jogabilidade nem se fala. Mas sabe, nem tudo era perfeito. Estava sentindo falta de grande produções, jogos que estavam saindo para o Xbox 360/Playstation 3/PC que não saia pro Wii. O Wii estava perdendo muitos jogos pela capacidade dele por não preferirem dar um downgrade, etc. Então resolvi comprar um Xbox, principalmente depois que joguei um pouco no Xbox do meu irmão alguns meses atrás.

Desde semana passada que chegou o meu Xbox, estou curtindo pra caramba! Ele tem mostrado muito mais completo, e a interatividade que ele me oferece não tem igual. E também agora entendo porque muitos falavam da LIVE.

Veja só, to jogando e posso falar com alguém no msn. Posso jogar e ver como está o progresso de download dos jogos que eu pedi pra baixar. Posso desafiar alguma pessoa em algum jogo. Posso baixar demo de jogos antes de resolver comprar algum jogo (Sim, eu uso jogos originais).

Agora no wii, por exemplo, para baixar um jogo eu não tinha idéia quando o download iria acabar, pois ele não demonstra o tempo de download. No wii para eu adicionar uma outra pessoa que eu queira jogar tenho que saber um número gigante, exemplo: 2887 2607 7401 9203 (esse não é o meu número do wii). Agora imagina, para cada jogo você ter um número desse, e toda vez que for jogar um jogo diferente com a mesma pessoa ter que adicionar esse número “gigante”. Sinceramente, isso é coisa da idade da pedra. Agora, vamos para um mundo moderno. No xbox só preciso saber apenas a gamer tag da pessoa e simplesmente adicionar no xbox. Pronto em todos os jogos encontro a pessoa.

Ah eu já falei da live? Ah que isso, a LIVE é uma maravilha. Jogar online, fazer compras online (apesar do wii ofecerer). É até difícil de explicar a sensação de ter um xbox, só sei que nesse pouco tempo to sentindo mais livre e feliz com o Xbox do que na época que eu comprei o Wii pois, hoje o xbox me oferece muito mais do que o Wii possa me oferecer.

Se você tiver em dúvida em comprar o xbox 360, não tenha dúvida, compre e seja feliz!

Rhino: Executando código de javascript na plataforma java ! 27/03/2009

Posted by fredericobenevides in Rhino.
3 comments

Para quem não sabe, a jvm permite executar vários tipos de linguagens além da própria linguagem Java.

Alguns exemplos de outras linguagens que rodam na jvm:

  • JRuby (implementação em java da linguagem Ruby)
  • Groovy
  • Scala
  • JavaFX
  • Rhino (implementação Java do Javascript)
  • CajuScript (projeto brasileiro http://code.google.com/p/cajuscript/)

Alguém poderia perguntar o por que de usar outra linguagem na jvm além da própria linguagem java. Bem, um dos itens que eu diria, existem linguagens que oferecem mais agilidade para resolver algum problema do que a própria linguagem java. E pra quem mexe a muito tempo em java, e que conhece outras linguagens, percebe que a linguagem java não é tão bonita assim e nem tão ágil. Pra ser sincero, acredito mais no futuro da plataforma Java do que na linguagem, mas isso não vem ao caso nesse tópico.

Existem linguagens dinâmicas que oferecem mais agilidade para desenvolver e resolver vários problemas, uma delas, o Ruby. Por exemplo, para somar um array no Ruby 1.9 eu poderia simplesmente usar isso =>  %w[1 2 3 4 5].inject(:+)   Claro que pra quem não conhece a linguagem acha estranho, mas o detalhe é que em java teria mais algumas linhas. Então se achar que alguma linguagem te oferece mais produtividade em determinada parte do código, por que não usá-la?

Agora, o melhor de tudo é juntar a interoperabilidade que a jvm ofecere, e ainda ter linguagens mais práticas/ágéis podendo ser executadas em qualquer ambiente. Ótimo, não é mesmo!?

Vamos ao assunto que interessa. Rhino! O que tem de especial executar javascript na plataforma Java?  Já aconteceu de alguns projetos você ter que repetir códigos que são feito em validações de javascript usar no seu programa? Saco, não é mesmo!? Cadê a reutilização de código? Cadê a produtividade? (apesar que alguns casos vai no ctrl+c ctrl+v e mais adaptação do código).

Para resolver alguns destes problemas a gente pode utilizar o Rhino, e com isso termos reutilização de códigos. Desenvolvemos o código em javascript e pronto, fazemos o java chamar determinada função de javascript e voilà, seu código java já está funcionando sem ter necessidade que implementar tudo novamente. Detalhe por padrão no java 6 já vem o Rhino, facilitando a praticidade de não precisar baixar o rhino e colocar no classpath do seu projeto.

O processo para rodar o Rhino dentro do java.

  1. Criar a fábrica ScriptEngineManager para construir ScriptEngine
  2. Criar o objeto que vai manipular determinada linguagem
  3. Avaliar o conteúdo da linguagem e executá-la
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("println('JavaScript Executando')");

Simples não é mesmo?

Agora vamos utilizar um arquivo de javascript, nesse próximo exemplo usando uma função fatorial.

Conteúdo do javascript:

function fatorial(n) {
	if (n == 1) return 1;
	return n * fatorial(n-1);
}
n = 3
println("O fatorial de " + n + " é: " + fatorial(n));

Código

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval(new FileReader("fatorial.js");

Se você reparou bem, quem está chamando a execucação da função está no próprio arquivo do javascript. “Mas não é isso que quero, quero passar o argumento pelo código java, tem jeito?”. Claro que tem, vamos ver:

Arquivo atualizado, sem a chamada para a função:

function fatorial(n) {
	if (n == 1) return 1;
	return n * fatorial(n-1);
}

Código:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval(new FileReader("fatorial2.js");

Invocable invocable = (Invocable) engine;

int fatorial = 3;
Double resultado = (Double) invocable
    .invokeFunction("fatorial", fatorial );
System.out.println("O fatorial de " + fatorial + 
    " é: " + resultado.intValue());

Como podem ver, nesse código passei o meu engine para o tipo invocable. Especifiquei qual o nome da função, e passei o argumento para a função em que o resultado desta chamada me retorna um Object.

Que tal outro exemplo? Vamos fazer agora uma validação de e-mail. Olha, não estou entrando nada em detalhe de hibernate validator, de validação via ajax, mas sim no uso do Rhino dentro do Java, então não há de ter pensamentos: “eu poderia fazer isso usando hibernate validator”, “usando ajax”, etc. Lembre-se sempre disso, isso é para alguns casos que seu código de javascript é o mesmo do seu código java.

function validar_email(email) {
	regex = /^[a-zA-Z0-9][a-zA-Z0-9\._-]+@([a-zA-Z0-9\._-]+\.)[a-zA-Z-0-9]{2}/;
    if(regex.exec(email)) {
    	return true;
    } else {
    	return false;
    }
}

Código:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval(FileLoad.load("email.js"));

Invocable invocable = (Invocable) engine;

String email = "usuario@email.com.br";
Boolean resultado = (Boolean) invocable
    .invokeFunction("validar_email", email);
System.out.println("O email é válido ? " + resultado);

email = "usuario";
resultado = (Boolean) invocable
    .invokeFunction("validar_email", email);
System.out.println("O email é válido ? " + resultado);

Interessante não? Mas você sabia também que é possível utilizar as bibliotecas do java escrevendo com javascript? E que tal implementar um JFrame escrevendo javascript? Ah, e que tal não ter que preocupar em declarar o tipo de objeto, já que javascript é uma linguagem dinâmica? Pois é, o Rhino permite fazer tudo isso!

Vejamos um exemplo como seria criar uma janela:

Arquivo js:

importPackage(javax.swing);
importPackage(java.awt);

var frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.setVisible(true);

Como podem ver para importar usando o javascript preciso digitar, importPackage(nomeDoPacote)  , o resto é normal como se fosse em java, mas claro, sem ter a necessidade de declarar o tipo do objeto, afinal em javascript não precisa.

Código

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval(new FileReader("simples_jframe.js");

Para rodar, simplesmente carrega o arquivo, e pronto, ele mostrará o JFrame.

Achei até interessante isso de desenvolver java usando javascript, que eu fiz um estudo de implementar um JFrame usando Threads. Caso vocês tenham interesse, vocês podem baixar o projeto “blog_rhino” no seguinte endereço do github: git://github.com/fredericobenevides/blog_rhino.git. Dentro desse projeto também terá todos os exemplos citados aqui no blog.

Passos para quem não sabe baixar o projeto e importar para o eclipse:

  1. Digitar o seguinte comando no console: git clone   git://github.com/fredericobenevides/blog_rhino.git
  2. cd blog_rhino
  3. mvn eclipse:eclipse (Fazendo o maven criar os arquivos necessários para importar para o eclipse)
  4. Abrir o eclipse e acessar File -> import -> General -> Existing Projects Into Workspace
  5. “Brincar com o projeto”

Espero que tenham curtido, e se caso um dia achar que possa reutilizar um código javascript… por que não usar Rhino?

Reinventar a Roda 09/03/2009

Posted by fredericobenevides in Desenvolvimento.
3 comments

Desde que eu mudei para Brasília, trabalhei com vários tipos de aplicações. Algumas, ou quem sabe maioria destas aplicações, eu vi o que a maioria é acostumado de ver, funcional por fora, mas internamente, horrível de se trabalhar.

Algumas destas aplicações o que eu nunca consegui entender, é como o pessoal reinventa a roda! E como REINVENTAM! Se fossem boas, tudo bem, mas a maioria não é. Pra ser sincero, não lembro de um destes se teve UM que valeu a pena, mas não vou chegar a ser tão crítico.

Eu nunca gostei disso, pois atrapalham muito o desenvolvimento. Estas implementações geralmente não existem testes, e o pior, na solução existente poderia estar trabalhando no meu negócio e não nos problemas da estrutura de um framework.

Para se ter uma idéia, um dos frameworks mvc que trabalhei, nele encontrava mais outro mvc, o struts. O negócio era uma bomba, que futuramente eles implantaram o struts para algumas partes do sistema. Infelizmente, legado é legado e logo muito da bomba ainda continuava lá, tanto que ele chegou a ter um problema que após uma certa quantidade de usuários, permitia que alguns usuários acessavam com perfil de outros usuários. Imagina o problema disso…

Já vi também criarem sistemas para controle de bugs, sendo que, existem muitos sistemas bons e livres tais como trac e bugzilla. Agora se pudessem parar pra analisar o tempo e o dinheiro que gastou com analistas e desenvolvedores para implementar este software, sairia mais barato pagando licença do Jira. E uma pequena observação, sairia mais barato e teria um sistema bem melhor.

Outra, trabalho com uma aplicação que até inventaram a camada de persistência, e o pior, os que desenvolveram achavam que o design era ótimo. Até já teve uns bugs que por exemplo, se fosse buscar uma pessoa pelo id, o que retornava era apenas um o objeto pessoa com o seu atributo ID sem o restante das informações do usuário. Pois é, era mais fácil fazer new Pessoa(id)…

Nesse tempo, o que eu cheguei a perceber, ou pelo menos parece com o pensamento de certos tipos de desenvolvedores: “Eu sou um bom desenvolvedor e sei fazer a minha própria aplicação, não preciso de soluções existentes”. Claro que eu não sei o que passou na mente de cada um para reinventar a roda, mas será que já perguntaram para si mesmo: “O que a minha aplicação terá o que as outras não tem?”, ou quem sabe pensar: “Vale a pena o tempo que vou gastar para desenvolver do que estudar um outro framework?”.

Lembre-se, reinventar a roda nem sempre é o caminho para uma solução, e sim, apenas o começo de alguns problemas.

Testes… O salvador! 02/03/2009

Posted by fredericobenevides in Desenvolvimento.
6 comments

Este primeiro post vou escrever sobre um assunto que até para muitos já estão cansados de saber, que é sobre o uso de testes no desenvolvimento de software. Neste post não vou explicar como fazer testes unitários na sua aplicação, vou falar um pouco das experiências que eu tive usando testes, mais especificamente com o JUnit.

Desde que eu comecei a “brincar” com testes fiquei meio viciado. O vício aconteceu quando eu comecei a ver que, a segurança que o teste me provê é inverso aos problemas que terei. Pois quanto de nós já deve ter tido problema de ter que arrumar algo que antes funcionava, perder tempo para concertar erros por causa de alguma outra manuntenção que quebrou o seu código. Perder horas, ou dias, por problemas que foram inseridos e não testado corretamente antes de subir para algum ambiente. Pois é, ninguém gosta disso, tanto desenvolvedor, ou até mesmos os responsáveis pela empresa em que trabalha, pois perda de tempo, é dinheiro jogado fora. Então, por mais que leve um tempo maior para implementar com mais segurança, é melhor ter um tempo maior de desenvolvimento, do que em um breve futuro seu código possa ser quebrado por causa de atualizações de outras pessoas, ou até mesmo as suas próprias atualizações.

Um exemplo do que passei aqui no serviço. Tinha um aplicativo, na verdade, uma classe que FAZIA TUDO, que sempre dava problema. Cheio de if, else, e o escambau. Então me passaram o serviço de eu corrigir um bug nessa classe. Eu olhei aquilo novamente, e pensei, desse jeito não dá e resolvi fazer um projeto separado, fiz testes. No final do projeto já tinha 22 classes, e uns 60 testes. O detalhe não é a quantidade de classes ou mesmo testes, mas sim que nesse meio tempo o teste me “salvou”, pois tinha momentos da minha implementação que quebrava algo que eu tinha que corrigir. O projeto demorou um pouco mais por causa dos testes, mas pelo menos , ou por enquanto, esse projeto está livre dos problemas enfrentados aqui no serviço e que já tomou tempo de vários desenvolvedores.

Então pessoal, vamos tentar ser mais profissionais, pois como sabemos, software sempre muda, e o testes ? Bem… este poderá um dia ser o seu Salvador!