Blog do Urubatan
msgbartop
Desenvolvedor, Palestrante, Escritor, Nerd Assumido e Pai do Marcus :D
msgbarbottom

20 Oct 09 Palestras da Semana

JugDay Faculdade de Tecnologia SENAC/RS


Pelo titulo parece que tenho feito palestras todas as semanas :D
Bom, mas esta semana tem duas:
Na quarta feira vou falar de Ruby on Rails, de produtividade, de metodologias ágeis e conversar um pouco com os alunos da Faculdade de Tecnologia do Senac/RS
e no sábado tem o RSJUG Jug Day onde eu vou apresentar um tutorial sobre desenvolvimento de aplicações Ruby on Rails, para mudar um pouquinho vou fazer um sistema de gerenciamento de projetos bem simples, mas já foge bastante do blog e da loja virtual que todo mundo faz o tempo todo, e pra deixar mais divertido vou usar um pouco de jQuery para tornar a aplicação mais interativa.

Bom era isto, ando escrevendo pouco por aqui por que a correria anda grande, tento responder todos os emails :D

Estou com um projeto que pode se tornar mais um livro, mas com certeza não vai ser publicado este ano, o trabalho ta corrido, o filho ta grande e cada dia mais parecido comigo, mas o importante é que tem saúde :D Daqui a 3 dias faz 5 meses.

Nos vemos dia 21 a noite no Senac e dia 24 na faculdade Dom Bosco no Jug Day!

Tags: , , , , , ,

30 Sep 09 Seja comunicativo, diga por que escreveu este código

Bom, no último post eu disse para você não ser repetitivo, e não escrever nos comentários o que o seu código faz. Se você precisa comentar o que o seu código faz, você realmente precisa refatorar o seu código e torna-lo mais legível
Mas comentários no código não são sempre ruins, o ruim é você escrever em português o que o seu código faz em java, mas existem diversas situações que veremos a seguir onde os comentários são ótimos, ou pelo menso são úteis …

Por exemplo, na interface pública de um serviço, um JavaDoc informando para que serve aquele serviço e com exemplos de utilização são sempre muito bem vindos, principalmente se este comentário informar quais são as validações que serão feitas nos parâmetros e quais são as restrições ao uso daquele serviço …
Eu não posso pegar exemplos de projetos em que estou trabalhando por que isto seria motivo para demissão por justa causa por quebra de sigilo :D
Então vamos ficar com alguns exemplos públicos e alguns exemplos mais simples que eu conseguir pensar na hora …

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * This is the only interface you need to create and manage system users, but if you need to manage user privileges take a look at the @link{PrivilegesService} interface
 */
public interface UsersService {
   /**
    * This method should be used only if you are already authenticated in the system, do no forget to send the session id header when calling methods that are not public like this one.
    * To create a user you need to provide all the needed information, this method will create  user in the database and then will try to create the user in the backend system, if the creation works the two accouns will be linked otherwise the database reccord will be erased. 
    * @param userName the user name must be unique within the LDAP domain, this means that there can
    * @param password
    * @param email
    */ 
   public User createUser(String userName, String password, String email);
}

Neste exemplo, não há necessidade alguma de colocar um comentário dizendo que o método createUser cria um usuário, mas o javadoc do exemplo informa de algumas pré condições para a execução do método e também diz qual o fluxo de execução e possíveis falhas. Como neste exemplo o UsersService é a interface publica de um serviço, esta documentação é bastante bem vinda, pois vai ajudar os usuários que vão acessar o serviço a saber o que fazer antes de criar um usuário e a saber possíveis motivos para as falhas.

Bom, acho que todos os outros exemplos que eu procurar vão ser parecidos com isto, resumindo este post e o anterior:
Se um comentário diz o que o método faz, o código é um lixo ou o comentário é redundante, o que o método faz tem que ser óbvio pelo nome do método
Se o comentário diz quando o método deve ser utilizado, algumas pré condições, o fluxo de execução, possíveis erros, e principalmente se ele esta em uma interface publica do sistema, que vai ser entregue a outra equipe/programador/empresa. o comentário é útil
Se o comentário esta em algum método ou variável privada, provavelmente tem algum problema por ai.

Acho que com isto eu encerro este assunto de comentários, eu posso ter me expressado errado, ou o mais provável, muitas pessoas leram o título do post e saíram berrando antes de ler o resto, mas a idéia básica é, o seu código tem que ser muito fácil de ler, os nomes das classes, métodos, variáveis, pacotes e quaisquer arquivos envolvidos no sistema devem dizer o que são, para que servem e por que estão ali. Se você esta colocando um comentário que diz que o método “create” cria um usuário, você deveria chamar o método de “createUser”, mas se o comentário esta informando o usuário do método de que o nome de usuário utilizado não precisa ser único mas o email sim, pois é este o campo utilizado como chave, ai você tem um comentário útil (e um sistema extranho :D ).

Não é por que o seu código tem comentários que ele é um lixo, mas tome cuidado por que é muito fácil utilizar comentários como desculpa para código ruim. E neste caso, talvez você precise estudar um pouco de rafactoring.

Tags: , , , ,

24 Sep 09 Software Auto Identificável – Self Identifying Software

2identify_yourself_logo3333
esta imagem foi encontrada na web usando o images.google.com e eu achei que tinha a ver com o post

Eu não conhecia o conceito até ver este twit do CV falando deste post sobre Self Identifying Software. E lendo o post percebi que já passei e algumas vezes ainda passo pelo mesmo problema: Identificar qual versão do software esta instalada em um servidor, ou em que versão do sofware algum bug apareceu ou aconteceu ou acontece …

Bom, eu curti a idéia e fiquei pensando em como implementar isto, pelo menos em projetos Java, disto sairam estes “code snippets” abaixo …
Bom, normalmente trabalho com o ANT para fazer o build de projetos Java, e tenho utilizado o Subversion (sim, eu conheço o GIT e gosto dele, mas no momento não vai rolar no trampo, mas uso para projetos pessoais :D )
Então, fui a página do subversion e baixei o SVNANT, desenvolvido pelo pessoal do subclipse, e integrei ele no meu build assim:

1
2
3
4
5
6
7
8
9
10
        <path id="svn_tasks">
		<fileset dir="${directory_you_unzipped_the_svnant_package}" includes="svn*.jar">
		</fileset>
	</path>
	<taskdef classpathref="svn_tasks" resource="org/tigris/subversion/svnant/svnantlib.xml" />
	<target name="_setup_svn_info">
		<svn failonerror="false" javahl="true" svnkit="false">
			<info target="${basedir}" verbose="true"/>
		</svn>
	</target>

Depois disto, em qualquer parte do build em que você for criar um .jar, .war ou qualquer tipo de pacote java, basta fazer algo parecido com isto:

1
2
3
4
5
6
7
8
9
        <target name="build_jar" depends="_setup_svn_info,compile">
		<jar destfile="${dist.dir}/${jar.name}">
			<fileset dir="${basedir}/bin" includes="*.*" />
			<manifest>
				<attribute name="SVN-URL" value="${svn.info.url}" />
				<attribute name="SVN-REV" value="${svn.info.rev}" />
			</manifest>
		</jar>
        </target>

Claro que o importante é o depends e o manifest, o resto vai depender do seu build, isto não é nem um exemplo real, escrevi direto aqui no blog para dar a idéia, então se tiver algum problema com o código me avisem nos comentários :D

Mas isto não é útil se você não conseguir ler o MANIFEST.MF do .jar onde a sua classe se encontra, então estou colocando aqui também um exemplo de código para isto, mas lembre-se de alterar o nome da classe para cada pacote, caso contrário você nunca saberá de qual pacote a classe esta sendo carregada :D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package blog.urubatan;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.jar.Manifest;
 
public class ExemploDoUrubatan {
	private Manifest manifest;
 
	private void initManifest() throws URISyntaxException,
			FileNotFoundException, IOException {
		Class<?> clazz = getClass();
		URL classContainer = clazz.getProtectionDomain().getCodeSource()
				.getLocation();
		File manifestContainer = new File(classContainer.toURI());
		File metaInf = new File(manifestContainer, "META-INF");
		File manifestFile = new File(metaInf, "MANIFEST.MF");
		manifest = new Manifest(new FileInputStream(manifestFile));
 
	}
 
	public ExemploDoUrubatan() throws URISyntaxException,
			FileNotFoundException, IOException {
		initManifest();
	}
 
	public String getSvnUrl() {
		return manifest.getMainAttributes().getValue("SVN-URL");
	}
 
	public String getSvnRevision() {
		return manifest.getMainAttributes().getValue("SVN-REV");
	}
 
	public static void main(String[] args) throws FileNotFoundException,
			URISyntaxException, IOException {
		ExemploDoUrubatan ex = new ExemploDoUrubatan();
		System.out.println(ex.getSvnUrl());
		System.out.println(ex.getSvnRevision());
	}
}

Se for a versão de um arquivo .war o código pode ser colocado em um servlet com uma URL conhecida, ou em um listener que vai guardar esta informação no servlet context para ser impresso depois por uma URL conhecida …
Se o servlet for a opção selecionada, o código ficaria parecido com isto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package blog.urubatan;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class ServletExample extends HttpServlet {
	private static final long serialVersionUID = 1L;
 
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		super.doPost(req, resp);
	}
 
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String warRoot = getServletContext().getRealPath(".");
		File manifestContainer = new File(warRoot);
		File metaInf = new File(manifestContainer, "META-INF");
		File manifestFile = new File(metaInf, "MANIFEST.MF");
		Manifest manifest = new Manifest(new FileInputStream(manifestFile));
		PrintWriter writer = resp.getWriter();
		Attributes mainAttributes = manifest.getMainAttributes();
		String svnUrl = mainAttributes.getValue("SVN-URL");
		String svnRev = mainAttributes.getValue("SVN-REV");
		writer.format("URL: %s\nRev:%s\n", svnUrl, svnRev);
	}
 
}

Com isto, pelo menos para projetos java, já cobrimos duas das situações mais comuns, que são saber a versão de uma API e saber a versão de uma aplicação WEB.
Com isto já é possível verificar o deploy de aplicações durante o build se o script for um pouco mais inteligente, o pessoal de testes tem condições de dizer exatamente qual foi a build que gerou o problema, é possível construir um “dashboard” com a versão de tudo que é utilizado no sistema, facilitando bastante a identificação de onde o problema ocorre, e principalmente, no caso de clusters, permitindo que seja verificada a versão em cada um dos nós de uma forma fácil …

Agora no caso do Rails, eu ainda não consegui decidir qual a melhor abordagem para isto …
criar um arquivo com estes meta dados dentro do diretório config, atualizar este arquivo por uma task rake toda vez que for executar um deploy via capistrano e criar um controller para informar a versão?
As gems já tem um mecanismo de versionamento, seria só atualizar a versão da gem a cada build, coisa que pode ser feita até com keywork expansion, ou utilizando o mesmo esquema do rake mencionado antes.
Bom, vou pensar mais nisto, derepente rola até criar um plugin para aplicações rails pra facilitar a vida :D
O que vocês acham?

Tags: , , , ,

16 Sep 09 Não seja repetitivo, nunca comente o que o seu código faz

Eu sei que já falei sobre comentários antes, mas acho que a abordagem não agradou muito, a maior parte das pessoas leu só o título do post e não prestou atenção no texto, então vamos tentar uma abordagem diferente.
Este post é o primeiro de uma série de 2, o próximo post vai dizer que é necessário comentar o código, mas com comentários decentes, então, sem gritaria por aqui por enquanto, ok?
Mas vamos ao que interessa …
Na minha opinião, qualquer programador Java, ou até mesmo, qualquer programador, que colocar os olhos no código abaixo, vai entender quase que instantaneamente o que ele faz, se alguem não concordar com isto, avise por favor …

1
2
3
4
5
6
new EmailMessage()
    .from("exemplo@urubatan.com.br")
    .to("gerente@empresa.com")
    .withSubject("Aprovação de processo")
    .withBody("Descrição bastante detalhada do que precisa ser aprovado")
    .send();

(sim, copiei o exemplo do blog do GC :D )
Então, eu acredito que se alguem quiser colocar um comentário neste código dizendo algo do tipo:

  • Envia email
  • Cria uma mensagem de email, configura propriedades e depois envia

Vai estar simplesmente sendo repetitivo, e poluindo o código com comentários inúteis, isto seria dizer o que o código faz, e se você comenta o que o seu código faz você é sim um perdedor que gosta de jogar trabalho no lixo!
Ahh, mas e se meu código não é assim tão claro? E se meu código é parecido com isto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// create some properties and get the default Session
Properties props = new Properties();
props.put("mail.smtp.host", _smtpHost);
Session session = Session.getDefaultInstance(props, null);
 
// create a message
Address replyToList[] = { new InternetAddress(replyTo) };
Message newMessage = new MimeMessage(session);
if (_fromName != null)
    newMessage.setFrom(new InternetAddress(from,
        _fromName + " on behalf of " + replyTo));
else
    newMessage.setFrom(new InternetAddress(from));
    newMessage.setReplyTo(replyToList);
    newMessage.setRecipients(Message.RecipientType.BCC, _toList);
    newMessage.setSubject(subject);
    newMessage.setSentDate(sentDate);
 
// send newMessage
Transport transport = session.getTransport(SMTP_MAIL);
transport.connect(_smtpHost, _user, _password);
transport.sendMessage(newMessage, _toList);

Bom, se o seu código é assim, então você precisa estudar um pouco de refactoring :D
Ahh, mas estou alterando uma parte da aplicação com muito código legado …
Bom, você deveria utilizar pelo menos alguns “extract method” para facilitar um pouco a leitura, e não comentar o que o código faz.

Imaginem a seguinte cena:
Você esta caminhando na rua e entra em uma loja, no momento em que você entra na loja, vê uma placa escrito: Roupas masculinas
Dois passos adiante, um vendedor chega e diz: Senhor, aqui o senhor vai encontrar roupas masculinas
Mais alguns passos e outro vendedor: Vendemos roupas masculinas aqui senhor.
E mais outra placa dizendo: Aqui roupas masculinas

Se você ainda estiver na loja e não bater no próximo que lhe visar que ali são vendidas roupas masculinas, no mínimo acabou de ocorrer um desperdício absurdo de esforço para informar exatamente a mesma coisa.
E este caso do email não é um dos mais comuns, o motivo deste post é que em muitos lugares eu vejo código parecido com:

1
2
3
4
5
6
/**
 * Set's the active property
 */
public void setActive(boolean active) {
   this.active = active;
}

(Isto não é uma critica a ninguém especifico e a todos os que já escreveram código assim, não foi uma nem duas vezes que vi isto por ai …)
um método de nome “setActive” com o comentário “Set’s the active property” é no mínimo redundância, e desperdício de tempo.
Então, eu não estou dizendo, nunca comentem o seu código, mas estou dizendo, se você precisa dizer o que o seu código faz, o seu código tem problemas, mas comentários são úteis, principalmente em interfaces públicas se você estiver informando por que ou como o código faz o que faz …
Mas tenha como regra, é proibido um comentário dizendo o que o código faz, pois ele é um sinal de que o código esta muito ruim!!

Ahh, e só para terminar, a biblioteca que permite aquele código de envio de emails bonitinho é a “Fluent Mail API” e o nome desta “técnica” é “Fluent Interfaces”, uma “técnica” bastante utilizada por quem trabalha com “Domain Driven Design”, e DDD faz Orientação a Objetos realmente mais divertida e mais útil, vou falar mais sobre isto em breve :D .

Tags: , , , , ,

31 Aug 09 Rs On Rails 2009 – Ótimo evento, espero que aconteça novamente em 2010

RS On Rails

O Rs On Rails que aconteceu no fim de semana passado estava excelente, palestras muito boas, a organização estava show debola também.
Tinha mais gente no evento do que eu achei que teria …
Acho que só temos a agradecer ao pessoal da Softa pela realização deste evento …
Infelizmente eu pude ficar pouco tempo por lá, meu filho esta com 3 meses agora e eu só tenho os fins de semana pra babar um pouco com ele acordado, e pra poder ajudar a Aline a cuidar dele (Não basta ser pai, tem que participar) :D
Mas este post tem 5 objetivos:

  1. Agradecer ao pessoal da organização pelo ótimo evento, que ja fiz
  2. Avisar que os slides da minha palestra já estão no SlideShare (embedded abaixo), e que o código esta no GitHub (clique aqui)
  3. Perguntar aos leitores do blog o que acharam da minha palestra, o que preciso melhorar para a próxima :D
  4. Tirar um pouco da poeira do blog, já que não tenho tido muito tempo de escrever por aqui
  5. Lembrar vocês que quem quiser comprar o meu livro com 30% desconto, pode utilizar o código URUBATAN no site da Novatec

Bom, acho que era isto, seguem os slides …

Quaisquer dúvidas é só deixar um comentário por aqui …

PS.: fiz o upload errado como um usuário guest no slideshare também, mas o oficial é o acima que esta na minha conta do slideshare :D

Tags: , , , , , , ,

25 Jun 09 Um especialista precisa saber um pouco de cada coisa

Para quem acha que o título deste post esta contraditório, lamento informar, mas você esta completamente equivocado.
Você conhece algum especialista? De preferência algum que esteja ai pertinho de você.
Se conhece por exemplo um especialista em Java ou .NET, chega pra ele e pergunta se ele conhece algum dos seguintes assuntos:

  • XML
  • Expressões Regulares
  • HTML
  • XHTML
  • Javascript
  • Modelos de Threading
  • Como funciona uma CPU
  • Para que serve um sistema operacional
  • O que é e para que serve uma “Maquina Virtual”
  • Flash
  • XSD
  • XPath
  • SQL
  • Estrutura de bancos de dados
  • TCP/IP
  • Sockets

Acredito que a resposta vai ser sim para todos, ou pelo menos a grande maior parte destes itens. E isto são só coisas genéricas, imagina se começarmos a detalhar a sopa de letrinhas existente no mundo Java EE ou no .NET.
Pois é mais ou menos isto que estou querendo dizer, um especialista precisa saber um monte de coisas para se tornar um especialista em uma delas.
A forma mais fácil que eu conheço para melhorar muito e muito rápido a qualidade do código que você escreve em uma linguagem é aprendendo outra linguagem de programação.
Tem gente que diz que o ideal é aprender uma linguagem nova por ano, e com certeza, o período da minha vida profissional que eu mais melhorei foi quando aprendi várias linguagens em um período curto de tempo.
Quando eu era mais novo (coisa de velho escrever isto :D ) o meu chefe na época disse que um especialista é alguem que sabe cada vez mais sobre cada vez menos, e que um super especialista é alguem que sabe absolutamente tudo sobre absolutamente nada …
Ach oque este conceito esta um pouco desatualizado, até por que por este conceito, um super especialista é o cara que sabe absolutamente tudo sobre absolutamente nada.

Pelo menos na minha opinião, eu espero que um especialista em Java por exemplo, consiga criar um pacote EAR padrão Java EE para uma aplicação composta por dois módulos web e três módulos EJB além de algumas bibliotecas utilizadas por todos os módulos.
Para fazer isto, o cara vai ter que conhecer no mínimo muito XML, vai ter que saber o que são meta dados, vai ter que saber quais meta dados foram definidos via anotações no código e quais ele vai querer sobre escrever com XML. Vai ter que conhecer a estrutura de um arquivo EAR, a estrutura de um arquivo WAR e qual a diferença entre um arquivo jar de uma biblioteca e de um módulo EJB.
Para entender direito o que ele ta fazendo, ele vai ter que conhecer o protocolo HTTP, por conseqüência o protocolo TCP e o IP. Além de precisar entender de RMI que é utilizado para chamada dos EJBs, RMI também funciona sobre TCP.
Se o servidor for rodar em cluster, é necessário saber como este cluster esta configurado, a maior parte dos servidores Java EE utiliza o protocolo IIOP/IP, o mesmo do corba, já que pela especificação Java EE todo EJB pode ser chamado utilizando CORBA também, e que o IIOP/IP permite roteamento muito mais fácil do que o RMI direto.
E isto tudo só para começar.
Se o especialista em java precisar também configurar o servidor de aplicações também ai aumenta bastante a quantidade de coisas que ele vai ter que saber só para poder ser chamado de especialista em Java e nem chegamos na parte de desenvolvimento ainda …
Claro que isto ainda é só a minha opinião, mas para ser um especialista em java, o cara tem que saber muito bem Orientação a Objetos, Reflexão, Refactoring e mais Refactoring, AOP, a diferença entre excessões checadas e não checadas, para que serve cada tipo de collection, todas as classes no mínimo dos pacotes java.lang e java.util e mais um monte de outras coisas.

Só para finalizar.
Vocês não vão conseguir se tornar especialistas em nada da noite para o dia. Isto vai demorar bastante, e mesmo que você queira ser especialista em .NET por exemplo, você vai ter que estudar muitas outras coisas.
A pior coisa que tem é programador bitolado que acha que a única linguagem/ferramenta/time/religião que presta é a que ele conhece agora …
(isto foi um misto de dicas com desabafo :D )

Tags: , ,

13 May 09 Java tem espelhos, e o mago deve saber jogar com eles (Básico da Reflexão)

Ok, o título deste post ficou meio estranho, mas como muita gente diz que isto é magia negra mesmo, então até que o título não esta tão ruim :D
Uma coisa que eu vejo bastante por ai, e não é de hoje, é que grande parte dos programadores Java não faz idéia do que seja Reflection, e normalmente tem medo de escrever, ou até mesmo de ler código “complicado”.
Não vou dizer que reflection é simples, mas é um recurso extremamente poderoso do Java que todo programador Java deveria conhecer.

O que é Reflection

Reflection em java, é como o nome diz, a possibilidade de programaticamente, visualizar um reflexo de um objeto ou uma classe, e como em um espelho, é possível também distorcer um pouco esta imagem quando necessário.
Como no reflexo em um espelho, o que você visualiza, não é o objeto real, apenas um reflexo deste, mas como na física, você pode deduzir como interagir com o objeto real, utilizando o seu reflexo.

Quando eu escrevi isto, lembrei de uma cena de um filme muito velho, acho que era “fúria de titâs” ou algo assim, onde alguem utilizava o reflexo da medusa em um escudo para lutar com ela sem se transformar em pedra.

Mas voltando ao assunto, reflection, é a possibilidade, de em tempo de execução, diversas informações sobre um objeto qualquer, incluindo mas não se limitando a seguinte lista:

  • Qual é a classe de um objeto
  • Quais métodos públicos a classe possui
  • Quais métodos foram declarados na classe (incluindo os privados)
  • Quais interfaces a classe implementa
  • Qual classe a classe do objeto estende
  • Quais anotações foram colocadas em uma classe
  • Quais anotações foram colocadas em um método
  • Quais anotações foram colocadas em um atributo
  • Quais anotações foram colocadas em um parâmetro de um método
  • Quais os tipos dos parâmetros de um método
  • Qual o tipo dos atributos de uma classe
  • Qual o tipo de retorno de um método

Via reflexão também é possível por exemplo, executar as seguintes ações em um objeto de uma classe que não existia no momento em que o código foi desenvolvido (um plugin por exemplo):

  • Instanciar um objeto
  • Chamar um método passando parâmetros ou não
  • Ler o valor de atributos privados de um objeto
  • Criar um clone de um objeto copiando o estado do mesmo
  • Chamar diretamente métodos privados de um objeto
  • Chamar métodos estáticos de uma classe
  • Ler atributos estáticos de uma classe

Claro que estes são só exemplos, a API de reflection adiciona muito mais flexibilidade do que isto, principalmente quando combinada com algum framework de AOP ou com a API de criação de Proxies disponível no próprio Java.
Mas para fazer tudo isto, é necessário conhecer algumas classes que a maior parte dos programadores Java não se preocupam em conhecer.
Só um detalhe antes de apresentar as novas classes, apenas combinando a API de reflection com a API de Proxies e o suporte a annotations do Java 5 é possível implementar todos os recursos do EJB3 por exemplo.
Agora vamos aprender a usar espelhos para fazer mágica :D

  • java.lang.Class – Esta é a classe que representa uma classe, todos os objetos tem um método “getClass” que retorna um objeto do tipo java.lang.Class, a partir de um objeto deste tipo, é possível obter diversas informações sobre uma classe, este é o ponto de entrada para o mundo dos espelhos, exatamente como aquele espelho do Alice no pais das maravilhas, mas sem o perigo de ficar preso por la como aconteceu com ela
  • java.lang.reflect.Field – Esta é a classe que representa um atributo de uma classe, objetos deste tipo nos permitem saber por exemplo, o nome dos campos de uma classe, e até mesmo ler o valor destes atributos
  • java.lang.reflect.Method – Objetos deste tipo representam métodos de uma classe, é possível utilizar estes objetos para chamar métodos passando ou não parâmetros para eles, mesmo que estes métodos sejam privados
  • java.lang.reflect.Modifier – Esta classe permite saber se um método ou atributo é privado ou publico, se ele é estático, ou seja, quais os modificadores de acesso foram utilizados na declaração do método, atributo ou classe
  • java.lang.reflect.Array – Esta classe representa um array, com objetos deste tipo é possível acessar todos os elementos de um array por exemplo
  • java.lang.reflect.Constructor – Esta classe representa um construtor de uma classe qualquer, uma classe pode ter diversos contrutores, e com referências para estes contrutores podemos saber quais os parâmetros necessários para instanciar uma objeto, ou até mesmo instanciar o objeto realmente
  • java.lang.reflect.AnnotatedElement – esta interface permite saber quais as anotações presentes em uma declaração, ela é implementada por Class, Method e Field por exemplo
  • Package java.lang.reflect – Antes de continuar lendo, por favor de uma olhada em quais as outras classes disponíveis no pacote responsável pela criação de espelhos e também pela distorção dos reflexos nestes espelhos no Java

Agora um exemplo básico, por que acredito que vocês não conseguiram entender muita coisa até aqui, mas eu prometo que depois de um exemplo as coisas vão ficar um pouco mais claras.

Este exemplo, razoavelmente simples, vai listar todos os métodos e atributos públicos em uma classe.
Para o exemplo se tornar um pouco mais divertido, o nome da classe deve ser passado como parâmetro, isto também faz você poder listar uma classe que não existia quando o programa foi compilado.

test/List.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
package test;
 
import java.lang.reflect.*;
 
public class List {
        public static void main(String[] args) throws Exception{
                if(args.length!=1)
                        throw new Exception("Voce precisa informar o nome da classe como unico parametro");
                Class<?> clazz = Class.forName(args[0]);
                printClassInformation(clazz);
                printClassAttributes(clazz);
                printClassMethods(clazz);
        }
        public static void printClassInformation(Class<?> clazz) throws Exception {
                System.out.println("Class Name: " + clazz.getName());
        }
        public static void printClassAttributes(Class<?> clazz) throws Exception {
                for(Field f : clazz.getDeclaredFields()){
                        System.out.format("\t--Private Attribute Name: %s, Attribute Type: %s\n",f.getName(),f.getType().getName());
                }
        }
        public static void printClassMethods(Class<?> clazz) throws Exception {
                for(Method m : clazz.getMethods()){
                        System.out.format("\tMethod Name: %s, Return Type: %s, Parameter Types: %s\n",m.getName(),m.getReturnType().getName(),m.getParameterTypes().toString());
                }
        }
}

Compile este exemplo, e execute passando por exemplo “java.lang.Class” como parâmetro e você vai ter um exemplo básico do funcionamento da API de Reflection.
Você pode também criar outra classe, empacotar ela em um arquivo .jar, adicionar este jar no classpath e executar este exemplo passando o nome da sua nova classe como parâmetro.

Claro que este é um exemplo extremamente básico, com um código que se não fosse pelo parâmetro passado para algumas classes, poderia ser executado até no Java 1.2, ou seja, a API de reflexão não é nova, é apenas sub utilizada pelo programador de nível médio.
Ahh, mas saber isto vai fazer com que eu seja um expert em java?
Claro que não! Mas não saber isto, com certeza te impede de ser um :D

test/Call.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
package test;
 
import java.lang.reflect.*;
 
public class Call {
        public static void main(String[] args) throws Exception {
                Class<?> clazz = Class.forName(args[0]);
                Method m = clazz.getMethod(args[1]);
                Object instance = clazz.newInstance();
                Object result = m.invoke(instance);
                System.out.println(result);
        }
}

Este é outro exemplo bastante simples, apenas para demonstrar algumas possibilidades, este exemplo bastante simples, chama um método sem parâmetros em uma classe qualquer que tenha um construtor padrão.
Para chamar métodos estáticos, seria necessária uma pequena alteração, o parâmetro passado para o método “invoke” da classe Method, é a instancia do objeto onde o método deve ser chamado, para métodos estáticos, esta instância é substituida pela classe que possui o método estático.
E o construtor padrão é necessário, por que precisamos de uma instância da classe para invocar o método, se a classe não possuir um construtor padrão, precisaremos passar parâmetros para o construtor, o que iria complicar bastante o exemplo, e a idéia aqui é só mostrar algumas possibilidades, e não complicar mais ainda a vida de vocês.
Mas como funciona o exemplo?
Tente compilar o exemplo, e executar ele passando os parâmetros:
java.lang.Object hashCode
ou
java.lang.Object toString
ou
QualquerNomeDeClasse nomeDeUmMétodoSemParâmetrosDestaClasse
e pronto, método executado.

Ai você vai pensar agora: Mas é muito mais fácil eu escrever direto “System.out.println(new Object().hashCode())” no meu código.
Claro que é, mas para isto você precisaria saber que o método que seria executado era o hashCode de uma nova instância de Object.
A idéia da API de reflection é obter informações em tempo de execução, é possibilitar um pouco de méta programação no Java.

Imagine só, criar um proxy para uma interface que garante que todos os métodos executados, caso tenham a anotação @Transactional, serão executados dentro do contexto de uma transação.
Isto é meta programação, isto é manter a mente um pouco mais aberta do que o programador médio.

Outra possível pergunta: Tu não vai ser expulso do clubinho por que esta revelando os segredos, como aconteceu com o Mister M?
Resposta: Claro que não, isto não é segredo nenhum, tu só não tinha aprendido antes por que não parou para estudar. Se você fosse um pouco mais preguiçoso, como eu, você já teria parado para estudar uma forma de trabalhar menos com as ferramentas que você tem na mão, e se você é um programador, meta programação, é uma forma de fazer mais trabalhando menos.

Mais uma pergunta: Por que ninguem me contou isto antes? explicando assim até parece fácil!
Resposta: Provavelmente achavam que tu é burro demais para entender, agora tu pode provar que isto não é verdade. E não se engane, não é tão simples assim, código usando reflexão pode ficar bastante complicado, eu só mostrei uns exemplos bem básicos.

A API de Proxies eu vou deixar como assunto para um próximo post, minha imagina imaginação esta meio fraca hoje, estou de saco cheio de assistir esta aula maluca que eu não to nem prestando atenção, acho que vou pra casa já :D

Se vocês tiverem idéias de mais exemplos que vocês querem ver como pode ser feito com reflexão, ou se tiverem perguntas sobre reflexão em java, por favor sintam-se a vontade de registrar as perguntas, dúvidas e sugestões aqui nos comentários do blog, vou tentar responder todas as perguntas :D
E como sempre, se você gostou deste post, indique para seus amigos, e coloque um link no seu blog :D

Acho que daqui a uns dias eu escrevo mais sobre reflection, mas vou tentar utilizar uns exemplos mais complexos, se tiverem sugestões para o próximo post, é só deixar nos comentários.

Tags: , , ,

11 May 09 Em time que esta ganhando se mexe sim (Refactoring básico)

Por mais que você seja um excelente programador, que todo o seu código funcione perfeitamente na primeira vez em que é executado (o que eu acho bem pouco provável que aconteça), por mais que você conheça pouco do código do sistema, ou por qualquer outro motivo que você possa lembrar agora ou daqui a 10 anos.
Em código que esta funcionando se mexe sim!
Mas por que estou dizendo isto? Porque se você fizer como eu, e de vez em quando, mas só de vez em quando para não ficar muito decepcionado consigo mesmo, pegar algum código que você escreveu no mês passado, ou a seis meses atrás, ou a um, dois, cinco ou dez anos, você vai achar este código muito mal escrito, mal organizado, feio, escrito por alguém que ainda precisava aprender tudo o que você aprendeu neste intervalo.
Se isto não acontecer com você, com certeza você está se tornando um programador medíocre que não aprendeu absolutamente nada neste intervalo, que não está melhor hoje do que era na semana passada, ou no mês passado ou no ano passado.
Esta sensação de que o código velho é ruim, não quer dizer que você era um programador ruim, é apenas o sinal de que você se esforçou e que hoje você é muito melhor do que era quando escreveu aquele código.

Ok, e o que isto tem a ver com este post? Tudo!
Se este código velho faz parte de algum sistema, biblioteca, projeto ou qualquer coisa do gênero que você não trabalha mais, deixe da forma como está, as pessoas que estão trabalhando nele agora que se preocupem com ele. Mas se ao contrário ele ainda faz parte de um código que você evolui dia a dia, então é sua responsabilidade fazer com que este código velho e maltrapilho, escrito por você ou não, evolua também, pelo menos o suficiente para não atrapalhar o código novo, escrito por este programador muito melhor do que aquele que escreveu o lixo que está sob seus olhos, mesmo que este tenha sido você ontem.
E este ato de piedade, generosidade e auto compaixão, é chamado de refactoring.
Ou seja, você vai fazer com que o código legado, melhore, seja mais testável, mais estável, mais bonito, sem quebrar todo o resto do sistema que já depende daquele pedaço de lixo que você escreveu no passado :D
E por que isto é também um ato de “auto compaixão”? Porque como eu ouvi um amigo comentar várias vezes, assim você esta diminuindo a quantidade de problemas legados que você vai ter que lidar no futuro próximo.

O que é rafactoring

Segundo a wikipedia: Refatoração (do inglês Refactoring) é o processo de modificar um sistema de software para melhorar a estrutura interna do código sem alterar seu comportamento externo.

Segundo o papa: Refatoração é uma técnica disciplinada para reestruturar um corpo de código existente, alterando a sua estrutura interna sem alterar o seu comportamento externo. O coração da técnica é uma série de pequenas transformações preservando o comportamento. Cada transformação (chamada de refactoring) faz um pouco, mas uma série de transformações podem produzir um resultado significante para a qualidade do sistema. Já que cada refatoração é pequena, é menos provável que ela cause algum problema. O sistema é mantido 100% funcional depois de cada refactoring. Reduzindo as chances de algum problema grave no sistema no final da reestruturação.

O que indica que um código precisa ser refatorado?

Basicamente se você acha que pode melhorar o código, isto já vale o rafactoring. Você achar que pode melhorar o código quer dizer que você esta sentindo que tem alguma coisa errada com ele, mesmo que você não tenha muita certeza de o que esta errado. Isto só quer dizer que você já aprendeu mais coisas depois que escreveu o código que esta lendo agora.
Mas podemos também formalizar isto um pouco, ou seja, definir alguns pontos nos quais todos concordam haver problemas no código, estes servem como argumento inclusive para você dizer que o código dos outros não esta muito bom, ou para você ter certeza de que o seu esta um lixo logo depois que escreve-lo.

  • Código duplicado (duplicated code)
  • Método longo (long method)
  • Classe grande (large class)
  • Lista de parâmetros longa (long parameter list)
  • Má indentação (Bad Indentation)

Os nomes em inglês estão ali por que eu não inventei isto, eu retirei esta pequena lista do livro do Fowler sobre rafactoring, também referenciado como “a biblia” pelo menos por mim :D

Alguns exemplos de refactoring

Ok, agora que você já sabe como identificar alguns problemas (é fácil, é só você achar que hoje sabe mais do que ontem :D ), vamos ver algumas soluções engarrafadas, prontinhas para beber, ou utilizar na sua IDE preferida (todas as IDEs Java hoje em dia possuem um suporte muito bom para refactorings).

  • Adicionar parâmetro – Add Parameter
     Muitas vezes é necessário adicionar mais um parâmetro em um método já existente, quando fizer isto, sera necessário alterar todos os lugares que já chamam o método existente, ou pelo menos deixar o método original como um delegate passando um valor padrão para o novo método, tudo depende de por que você esta utilizando este refactoring
  • Converter inicialização dinâmica por estática – Convert Dynamic to Static Construction
     Algumas vezes a utilização de reflection pode criar fraquezas para o sistema, se isto não for necessário, então prefira inicializar estaticamente os objetos
  • Converter inicialização estática por dinâmica – Convert Static to Dynamic Construction
     Algumas vezes o sistema tem bastante a ganhar com a utilização de reflection para reduzir código duplicado ou pelo menos para adicionar flexibilidade
  • Encapsular atributo – Encapsulate Field
     Nunca, e eu disse nunca mesmo, exponha um atributo diretamente em java, isto simplesmente não esta certo, prefica utilizar métodos de leitura e escrita
  • Extrair classe – Extract Class
     Várias vezes é possível encapsular parte do comportamento de uma classe maior em outra classe
  • Extrair interface – Extract Interface
     Algumas vezes acessar diretamente uma classe de outras partes do sistema aumenta muito o acoplamento do sistema, nestes casos, prefira criar uma interface com os métodos públicos e esconder um pouco a implementação, ou até mesmo criar mais de uma implementação
  • Extrair metodo – Extract Method
     Diversas vezes, quando o código de um método esta muito grande, é possível extrair parte dele para um outro método, preservando o comportamento e reduzindo a duplicação de código
  • Extrair sub classe – Extract Subclass
     Quando parte do comportamento de uma classe é utilizado apenas em situações especificas, criar uma sub classe pode ser uma boa idéia
  • Introduzir “objeto parâmetro” – Introduce Parameter Object
     Quando um método tem muitos parâmetros, algumas vezes é útil encapsular estes parâmetros em um objeto, e faer com que o método receba apenas aquele objeto como parâmetro
  • Mover classe – Move Class
     Quando um package tem muitas classes, algumas vezes é útil mover uma ou mais classes para outro package, também pode ser utilizado quando uma classe simplesmente esta no lugar errado.
  • Subir método – Pull Up Method
     Quando um método é implementado em mais de uma classe e estas classes compartilham uma super classe, pode ser útil mover a implementação deste método para esta super classe
  • Remover parâmetro – Remove Parameter
     Algumas vezes um dos parâmetros de um método simplesmente não é mais utilizado
  • Remover método de escrita – Remove Setting Method
     Quando um atributo deve ser somente leitura, não é interessante que exista um método de escrita para este atributo
  • Renomear método – Rename Method
     Algumas vezes o nome de um método simplesmente não parece certo, ou então não diz o que aquele método faz.


Claro que estes não são os únicos refactorings existentes, esta é apenas parte da lista que pode ser encontrada no site do livro de refactorings do Martin Fowler. Apenas as descrições foram escritas por mim, e mesmo no site, ou no livro do Fowler você não vai encontrar uma lista completa, por que é bem possível que outro refactoring seja criado hoje ou amanha, o importante é entender a idéia.

E eu tenho que decorar tudo isto? Tenho que fazer na mão e garantir que funciona?

Uma das coisas boas de ótimas idéias é que muita gente gosta delas, e acaba copiando.
Em algum momento do passado remoto do desenvolvimento java, quando as boas IDEs eram todas pagas, o pessoal da JetBrains, leu “a biblia” e disse: Que o IntelliJ IDEA ajude os desenvolvedores a fazerem os rafactorings para que o código se torne bonito e legível. E assim fez o IntelliJ IDEA.
Algum tempo depois, o eclipse copiou a idéia e passou a suportar muitos refactorings também, e hoje em dia o NetBeans também suporta muitos refactorings, e assim o desenvolvedor vive feliz podendo ser produtivo com a sua IDE favorita.
Eu adoro o IntelliJ IDEA, mas utilizo muito mais o eclipse, e algumas vezes até o NetBeans.
Todas as 3 IDEs suportam refactorings, e até o VIM e o Emacs suportam refactorings, mas não se iludam desenvolvedores Java, o pessoal da microsoft viu que isto era bom, e também adicionou suporte a diversos refactorings no visual studio, por tanto vocês não são mais os únicos com boas ferramentas.
Então respondendo a pergunta do título, não precisa decorar tudo, e não precisa fazer tudo na unha não, mas por favor, decore pelo menos os atalhos para os refactorings suportados pela sua IDE, o seu código agradece.
Outro dia eu coloco uma lista de atalhos de cada IDE para alguns refactorings por aqui (se der tempo :D )

Mas só isto basta? Meu código não vai parar de funcionar mesmo?

Um dos valores do Extreme Programming é a coragem, e este valor é necessário para se refatorar o código por exemplo, a probabilidade de o seu código parar de funcionar depois de um refactoring com a ajuda da sua IDE é bem pequena, um refactoring manual é mais arriscado, mas o código limpo bonito e funcional vale o risco.
Outra coisa, para diminuir o risco, escreva testes para o seu código sempre, com os testes, você tem algo para garantir que você não quebrou nada enquanto estava refatorando.
Mas se o mariquinhas ai não tem coragem de mexer no próprio código, pode continuar escrevendo código mediocre por ai, deve ter alguem com coragem o suficiente para fazer um trabalho decente e entregar código de qualidade na sua empresa, só espero que o seu chefe não se preocupe muito com qualidade, se não o teu medinho vai custar o teu emprego, por que com certeza, esta tua frescura já ta custando a qualidade do teu trabalho sua franguinha!

Sem brincadeiras agora, nem toda hora é hora de refatorar, nem todo refactoring vale a pena, nem sempre se tem tempo para melhorar o que já esta pronto, mas ler o código e saber o que pode ser melhorado, e como melhora-lo vai garantir que você faça menos porcaria no futuro, pelo menos comigo isto funciona :D

Tags: , ,

13 Nov 08 Comentário no código é para os fracos

Provavelmente serei crucificado por causa deste post, mas se você se der ao trabalho de ler até o final, provavelmente vai concordar comigo que comentários no código são para os fracos, programador hardcore de verdade escreve código legível!
É exatamente isto que eu estou dizendo, por exemplo, o que faz o código abaixo?

1
2
3
4
5
6
7
8
9
10
public String write(StringBuilder fle, StringBuffer con) {
  File f = new File(fle.toString());
  FileReader fr = new FileReader(f);
  BufferedReader br = new BufferedReader(fr);
  String lin;
  while((lin=br.readLine())!=null){
    con.append(lin).append("\n");
  }
  return con.toString();
}

Difícil? E este ainda é um código simples, mas vamos dar uma melhorada nele …

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public String read(StringBuilder fle, StringBuffer con) {
  //Opens the file with the name container in the fle parameter
  File f = new File(fle.toString());
  //Create a file reader, then a buffered reader to make our work easier
  FileReader fr = new FileReader(f);
  BufferedReader br = new BufferedReader(fr);
  String lin;
  //Read each line of the file until it is null
  while((lin=br.readLine())!=null){
    //Put the content read into the buffer pointed by the parameter "con"
    con.append(lin).append("\n");
  }
  //The caller already have the content, because he created the buffer, but I'll return the string anyway
  return con.toString();
}

Mais fácil certo? Bastou ler os comentários, mas o código continua um lixo.
Ou seja, esta é uma gambiarra utilizada por péssimos programadores para contornar a própria limitação de não conseguir escrever um código decente.

Então qual a solução que eu recomendo?
Vamos tentar reescrever este método então:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public String readFileContents(File fileToRead) {
  boolean canReadFile = fileToRead.exists();
  if(!canReadFile)
    return "";
  StringBuilder buffer = new StringBuilder();
  BufferedReader readerForFile = openBufferedReaderForFile(fileToRead);
  readFileContetIntoBuffer(buffer,readerForFile);
  closeFileReader(readerForFile);
  return buffer.toString();
}
private  BufferedReader openBufferedReaderForFile(File fileToRead){
  return new BufferedReader(new FileReader(fileToRead));
}
private void readFileContetIntoBuffer(buffer,readerForFile){
  String line;
  while((line=readerForFile.readLine())!=null){
    buffer.append(line).append("\n");
  }
}
private void closeFileReader(readerForFile){
  readerForFile.close();
}

Agora se você prestar atenção no nome do método “readFileContents” já vai saber o que o método faz, Além disto, o código do método é quase legível em inglês. A leitura dele ficaria mais ou menos assim:

if not can read file, return null
open Buffered Reader For File: fileToRead
read File Contet Into Buffer: buffer, readerForFile
close File Reader: readerForFile
return buffer.toString();

Ou seja, qualquer um que entenda inglês, como qualquer desenvolvedor tem a obrigação de entender, vai ler o método como se fosse um comentário.

E eu já vi gente fazendo pior do que isto, o código tinha comentários, mas parecia com esta coisa ai em baixo:

1
2
3
4
5
public String write(StringBuilder fle, StringBuffer con) {
  File f = new File(fle.toString()); FileReader fr = new FileReader(f);  BufferedReader br = new BufferedReader(fr);
String lin; while((lin=br.readLine())!=null){  con.append(lin).append("\n");  }
  return con.toString();
}

Com certeza tinha muito menos linhas de código do que a minha versão :D
Mas não é uma tarefa fácil entender o código que uma criatura destas escreve :D

Claro que o exemplo que eu apresentei foi um exemplo bem simples, e que escrever código legível requer uma certa prática …
Então, vou fazer uma proposta:
Vou deixar um exemplo de código abaixo, e vocês tentam torna-lo mais legível. Em um ou dois dias eu posto a minha resposta aqui.
Quem quiser pode postar nos comentários o código que escreveu.
Para que o código fique colorido no blog, basta colocar dentro de uma tag <pre lang=”java” line=”1″> … </pre>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package blog;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class VeryBadlyNamedFile {
	private static final char[] asdfg = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'};
	private String an;
	private BufferedReader rfsdw;
	private FileReader temp;
 
	public VeryBadlyNamedFile(String an, BufferedReader rfsdw, FileReader temp) {
		super();
		this.an = an;
		this.rfsdw = rfsdw;
		this.temp = temp;
	}
 
	public void doIt() throws IOException {
		ctfiidne();
		startDoing();
		try {
			canIDoAnyThing();
		} catch (RuntimeException yicdet) {
			nowReallyDoIt();
		}
	}
 
	private void nowReallyDoIt() {
		firstDoTheOtherThing();
		reallyDoItInternal();
	}
 
	private void firstDoTheOtherThing() {
		rfsdw = new BufferedReader(temp);
	}
 
	private void reallyDoItInternal() {
		while (true) {
			try {
				imDoingIt();
			} catch (Exception e) {
				break;
			}
		}
	}
 
	private void imDoingIt() throws Exception {
		String s = rfsdw.readLine();
		if (s == null)
			throw new Exception("hahaha, I bet you did not understood the code");
		System.out.println(s);
	}
 
	private void ctfiidne() throws IOException {
		File a = new File(an);
		if (!a.exists()) {
			FileWriter wrfedsd = new FileWriter(a);
			wrfedsd.write(asdfg);
			wrfedsd.close();
		}
	}
 
	private void canIDoAnyThing() {
		if (new File(an).exists() && new File(an).canRead() && new File(an).canWrite())
			throw new RuntimeException();
	}
 
	private void startDoing() throws FileNotFoundException {
		File f = new File(an);
		temp = new FileReader(f);
	}
}

E agora um “main” só para executar o lixão acima.

1
2
3
4
5
6
7
8
9
package blog;
 
import java.io.IOException;
 
public class Main {
	public static void main(String[] args) throws IOException {
		new VeryBadlyNamedFile("c:\\anyFile.any",null,null).doIt();
	}
}

Os exemplos estão em java, mas em qualquer linguagem os comentários para explicar o código servem para mascarar a incapacidade dos programadores escreverem código decente.

PS.: Só para constar, eu não acho de verdade que vocês não devem comentar o código, mas se vocês não escrevem código legível, ou escrevem código que realmente precisa de um comentário para outro programador entender, então vocês não aprenderam a programar ainda!

PS2.: só para constar, o código deste post foi inventado na hora, inspirado em coisas que ja vi em diversos lugares por ai, masescrevi ele direto no blog, então existe uma grande possibilidade de não compilar.

PS3.: acho que preciso de exemplos melhores, mas vocês devem ter entendido a idéia deste post

Tags: , , ,

17 Oct 07 Integração contínua sincrona com Rails/Rake

English version here

Bom, integração contínua acho que todos concordam que é uma necessidade em qualquer projeto de software, mas a integração contínua assíncrona utilizada normalmente tem alguns problemas, como por exemplo:

  • O código mesmo não passando nos testes é comitado
  • Os testes só serão executados algum tempo depois pelo servidor de integração, e só no final disto é que o desenvolvedor ficara sabendo se ocorreu algum problema de integração com o código que ele ja não esta mais trabalhando
  • O desenvolvedor provavelmente ja esta no meio de outra tarefa quando receber o e-mail dizendo que ocorreu algum problema com a tarefa anterior

Eu não estou dizendo que não é interessante existir um servidor de integração, é interessante para que todos os envolvidos no projeto tenham sempre acesso aos relatórios e a última versão do sistema compilado, mas não acho que deva ser dele a tarefa de integrar o sistema.

Ou seja, o que antigamente era o servidor de integração, agora passa a ser apenas um servidor de builds, e gerador de relatórios sobre o código fonte e progresso do projeto.

O ideal é que o desenvolvedor, durante o processo de commit, seja obrigado a executar todos os testes, e este commit só ser realmente executado se todos os testes passarem.

Claro que isto pode ser melhorado, adicionando ainda algumas restrições, por exemplo, exigir uma cobertura de testes mínima, mas no meu caso, eu desenvolvi esta task do Rake para um projeto em que estou trabalhando sozinho, e estou utilizando o GIT para controle de versões (escreverei um post sobre o GIT ainda esta semana se der tempo), e estou utilizando integração sincrona também em alguns projetos com Java, em outra oportunidade escrevo sobre o processo com Java.

Estou adotando esta prática de integração sincrona para todos os novos projetos da minha empresa e dos clientes que aceitam a idéia.

Mas voltando ao assunto, é bastante fácil implementar isto em um projeto Rails, basta seguir estes passos:

1 – criar um arquivo de nome ‘git.rake’ dentro do diretório lib/tasks com o seguinte conteúdo:

namespace :git do
  desc "Update every thing before the tests"
  task :update do
    puts "Lets update it all, but we are using GIT so we already have the latest source for this repo"
  end
  desc "Run all tests, if all are OK, then commit every thing to the git local repository"
  task :commit => [:update, :test] do
    puts "No test failures, now we can commit it all"
    exec 'git commit -a'
  end
end

Como podem ver esta task do Rake é bem simples, e com certeza isto vai aumentar muito a qualidade do projeto!

2 – sempre ao final de uma tarefa, em vez de executar o comando “git commit -a”, executar o comando: “rake git:update”

Só isto, a partir de agora você esta utilizando integração continua sincrona :D

Claro que esta task do Rake pode ser melhorada ainda, pode ser configurado por exemplo um pull de um repositório central, ou um update de um subversion ou qualquer coisa do gênero, mas acho que ja serve como exemplo para quem quiser começar a utilizar integração sincrona.

Se todos os testes passarem, o GIT vai abrir o VIM para que o desenvolvedor edite a mensagem de commit, depois da mensagem editada o código alterado é comitado sem problemas e sem medo de quebrar o próximo build com tudo integrado.

E vocês, o qu acham deste processo de integração continua? preferem sincrona ou assincrona? por que?

Só para lembrar: Estão abertas as incrições para o curso de Java Server Faces da Tech Office

Tags: , , ,

01 Oct 07 Review: ZK Framework – O modo mais simples de fazer uma Aplicação Web Rica

Este ótimo review foi escrito pelo Marcos de Sousa. Muito obrigado pela colaboração!


Parte I – ReviewIntroduçãoZK é uma framework web ajax open source, que pemite o desenvolvimento de interfaces ricas para aplicações web com pouca programação e um custo de desenvolvimento reduzido, tal como as antigas aplicações desktop.

ZK foi o primeiro projecto ajax no SourceForge.net, acumulou 450.000 downloads e 800.000 visitantes, e foi referenciado por mais de 4.000 websites desde o lançamento da primeira versão em 2005.

Simplesmente Rico

Basicamente o ZK possui quase tudo feito de bandeja, ora vejamos a versão ZK 3.0.0-FL-2007-09-28:

  • Componentes:
  • 79 XUL e 83 HTML componentes prontos: Tabbox, grid, listbox, tree, menu, combobox, bandbox, datebox, chart, hbox, vbox, window, slider, paging, audio, image, timer, include, iframe, etc
  • Drag-and-drop suportado por todos componentes
  • Menu de Contexto e Tooltips customizaveis suportado por todos componentes
  • Ordenação Customizada de listbox, grid etc
  • Auto-preenchimento para combobox
  • “Load on demand” sem escrever nenhuma linha de código, desde a versão 2.4.0
  • “Live data” ou “Load on demand” para listbox
  • Todos componentes são clonáveis e serializáveis
  • Validação e formatação para componentes de entrada de dados, com suporte completo a uso de expressões regulares e $#,##0
  • 100% Java API para os componentes Google Maps, FCKeditor, DOJO e Timeline
  • Componente Tree com paginação
  • Server push, chamado de reverse-ajax, permite o servidor enviar dados para clientes activos, ou seja, facilmente desenvolvemos um CHAT.
  • Em adição componentes TreeModel, Timebox e Flash
  • Modelo server centrico e baseado em eventos:
  • Mais de 20 eventos suportados; onChange, onChanging, onScroll, onSelect, on Show, onZIndex, etc
  • Todos eventos são processados no servidor
  • Todos eventos estão sincronizados. Não possui problema “Racing Condition”
  • Scripting usando expressões EL. Inclui mas não limitado a Java, Javascript, Ruby and Groovy. A escolha é sua :D .
  • Mudanças no User-interface sem necessidade de restarting da aplicação
  • Anotações que permite uma página acessar base de dados sem escrever código java
  • Macro componentes
  • Facilidade em encapsular componentes puramente clientes como componentes do ZK usando 100% Java API
  • Dialogos Modais verdadeiramente server-side
  • Internacionalização
  • MVEL plug-in

Facilidade de utilização

Simplicidade é um dos valores de base do ZK. Outra das facilidades que se encontra nessa framework, é a disponibilidade com que a sua equipa de desenvolvedores está disposta a ajudar.

A criação de novos/customizados componentes é bastante simples.

A documentação é muito boa e bem detalhada.

Plataforma Independente

  • ZK Mobile foi lançado e está na versão 0.8.6 com 10 MIL (Mobile Interactive Language) componentes já de bandeja: listbox, listitem, textbox, image, label, command, datebox, decimalbox, intbox, frame
  • A ideia por trás do ZK Base está mantida no desenvolvimento do ZK Mobile, ou seja, todos as características acimas mantém-se
  • ZK suporta os seguintes browsers: Internet Explorer 6+/7, Firefox 1+, Safari 2+, Mozilla 1+, Opera 9+ and Camino 1+.
  • Corre em qualquer web server que suporta Servlet 2.3+ e JVM 1.4+

Mega Componentes, Colaboração da Comunidade e Integração com outras frameworks e bibliotecas Javascript

ZK é uma das framework com um mais componentes e diversificados. E em cada versão novos componentes têm vindo a serem lançados. Está em andamento o desenvolvimento de componentes de larga escala como folha de cálculo “spreadsheets” e forums. Alias, já está disponível para download o primeiro SIP de spreadsheet. Comunidade open source é tudo sobre colaboração. ZK insentiva a comunidade na criação de novos componentes e ideias. A comunidade participa activamente e é citada pela contribuição que faz.

Todo o trabalho complicado é feito pela equipe de ZK. Se quiser algum novo componente ou sugerir melhorias/integração pode submeter na lista de “Feature Requests”.

Google Maps, FCKeditor, DOJO e Timeline já estão integrados desde as versões mais antigas.

Integração com Spring, Hibernate, bem como com Seasar (http://www.seasar.org/en/index.html, é a framework open source de Dependency-Injection mais popular no Japão).

A integração com Jboss Seam, bem como com tags JSP já está pronta.

A integração com Yui-Ext (http://www.extjs.com/, uma das mais famosas bibliotecas javascript), simplesmente é uma das melhores novidades. É mesmo para ficar de boca aberta. E mais ainda, todos os componentes do Yui-Ext serão integrados com ZK.

O desenho de layouts é sempre complicado para desenvolvedores. Logo, Ext Layout de Yui-Ext foi integrado. Mas, como se sabe usando plug-in externos acabamos pagando um preço (performance), logo a equipe do ZK lançou o ZK Layout de modo a trazer simplicidade, flexibilidade e poder no desenho de layout, isso aumenta a performance pois reduziram do Ext Layout 500 KB para o ZK Layout 20KB. Até parece que pagamos os caras de ZK para trabalharem para nós .

Para os amantes de JSF (JavaServer Faces), estavam todos tristes, pois, até agora nada foi dito de JSF. Em voz alta, já está integrado ZK em forma de componentes.

Confira nas referências os links com os artigos de integração com as frameworks passo a passo.

Histórico de Lançamento de versões do ZK

Dá para perceber o quanto a equipa do ZK está trabalhando nele com bastante dedicação.

Desvantagens

A licença de ZK é bastante crtiticada. No entanto, vale a pena dizer que segue a mesma licença do famoso MySQL.

Conclusão

Muito ficou por analisar (por exemplo as desvantagens do ZK). No entanto isso pode ser considerado lendo o artigo do Cameron Smith – ZK Rich Client Framework and Agile Development em Inglês http://www.theserverside.com/tt/articles/article.tss?l=ZKandAgile. No artigo ele faz uma discussão e depois apresenta um tutorial. Faz a comparação entre as frameworks RIA: Echo2, ZK, OpenLaszlo, Flex, GWT.

Devido a variedade de componentes de fabrica já prontos para serem usados, ajax de raíz (sem esforço), integração com frameworks populares como Spring, Hibernate, JSF, etc, devido ao suporte da comunidade, devido a ser open source, etc torna o ZK uma escolha privilegiada, principalmente no desenvolvimento de aplicações web para Intranet.

Referências

Sobre Marcos de Sousa

Marcos de Sousa actua na área de desenvolvimento há mais de cinco anos. É desenvolvedor no Banco BCI Fomento (www.bcifomento.co.mz). Setembro 2007, Maputo – Moçambique.


01/10/2007 – Alguns dados sobre o projeto atualizados no post

Tags: , ,

29 Sep 07 Coletânea de Links

Bom, acho que era isto, desculpem pelo tempo sem postar, é que a semana foi corrida com o Curso de Rails, mas agora vou voltar a postar com mais frequência!

Amanha ou segunda devo escrever alguma coisa sobre o Curso, que na minha opinião foi bem legal, acho que todos os alunos aproveitaram bastante! (Hoje não vou escrever mais por que é meu aniversário de casamento e tenho que dar mais atenção para a esposa se eu quiser chegar no segundo aniversário :D )

Outra coisa, vocês acham úteis estas coletâneas de links que posto de vez em quando?

Tags: , , , , , ,

10 Sep 07 Rails Rumble e as lições aprendidas (Urubatan)

O título foi “roubado” do blog do Nando Vieira que também estava participando do Rails Rumble, que como eu comentei aqui, e aqui, foi o motivo de eu praticamente não sair de casa neste fim de semana lindo) :D
A idéia da competição eram equipes de 1 a 4 pessoas passando 48h desenvolvendo algum sistema que depois vai ser avaliado …
Bom, eu tive algumas interrupções no caminho:

  • Só comecei a desenvolver a aplicação no sábado as 9h da manha (ja tinha gente trabalhando des das 2h da manha BRT que foi quando a competição começou)
  • Sai sábado a noite para tomar umas cervejas e comer um cachorro quente na casa de alguns amigos
  • Parei um bom tempo para fazer o Almoço para a esposa no sábado
  • Fui voltei a programar apenas no domingo la pelas 8h a manha
  • Parei novamente as 12h para ir no almoço de aniversário de um primo meu
  • A tarde fomos visitar meu cunhado
  • Voltei a programar domingo as 17h e parei hoje as 2h da manha quando encerrou a competição

Por tanto utilizei muito menos do que as 48h disponíveis :D

Mas acho que consegui atingir meu objetivo!
Tudo bem, algumas coisas que eu queria fazer, não consegui completar, mas em sua maior parte eram “perfumarias”, o que não consegui completar:

  • O Layout da aplicação (fala sério, o leyout que eu fiz só pra não ficarem só os campos jogados na tela ta uma porcaria)
  • Validação de campos client-side, a validação dos inputs esta apenas server-side
  • Utilização do validation-reflection para gerar validações client-side automagicamente
  • Suporte a pesquisas privadas
  • Melhor utilização de Ajax, tem muito pouca coisa usando AJAX na app que eu fiz
  • Melhor autenticação e autorização

O que eu aprendi participando desta competição?

  • Testes unitários são importantes (tive problemas por ter abandonado a idéia de escreve-los quando o tempo começou a apertar)
  • 1 pessoa só não é um bom tamanho para uma equipe, eu poderia ter utilizado muito bem a ajuda de outro programador, e melhor ainda de um designer, ou seja, como diz o pessoal do 39signals, 3 pessoas é um tamanho excelente para uma equipe de desenvolvimento, 2 programadores e 1 designer :D
  • AJAX sem uma linha de Javascript é o máximo
  • CGI não é uma boa forma de deploy de uma aplicação Rails, mas FastCGI funciona que é uma beleza e é bem rápido
  • Não curto muito trabalhar sobre pressão (que novidade)
  • Não é pecado utilizar SQL diretamente em aplicações RoR, principalmente para relatórios

No geral foi bem divertido, acho que não vou ganhar nada por causa do layout podre da minha aplicação, mas ela funciona bem e a principio sem bugs conhecidos por mim :D

Diferente do Nando Vieira

  • eu não tive problemas com a instalação do rubygems via apt-get (uso desta forma em casa já)
  • Não tive problemas com a configuração do servidor, ja que trabalhei com isto por algum tempo, e já havia realizado esta tarefa algumas vezes
  • Aparentemente defini um escopo aceitável para a quantidade de esforço disponível, se fosse um pouco menor talvez houvesse tempo para mais testes unitários

Bom, acho que era isto, a aplicação esta rodando, ja dormi um pouco e estou atrazado para o trabalho :D
Se quiserem dar uma olhada no que eu fiz (ja disse que o layout esta uma porcaria), a aplicação esta rodando neste endereço:
http://kyourclient.railsrumble.com/

As avaliações das aplicações começam na Quarta Feira, basicamente elas serão feitas assim:
Qualquer um que quiser avaliar as aplicações desenvolvidas pode se reigstrar e avalia-las, então, se quiserem ajudar este amigo que vos escreve, o link para avaliação da minha aplicação é este.

Valeus galera, a brincadeira estava divertida, e acho que depois disto ja tenho meu certificado de Nerd garantido :D

Tags: , ,

31 Aug 07 Um pouco de tudo e tudo de nada – correndo atrás da máquina

fields.JPGUma das coisas legais de trabalhar com TI é que todo dia tem novidade, uma das coisas ruins de trabalhar com TI é que precisamos pelo menos ter uma idéia sobre tudo o que esta acontecendo …

Então, segue mais um daqueles posts com poucas opiniões e muitos links …

  • Annotated to the bones:
    Parece que o pessoal não aprende mesmo, em vez de diminuir a quantidade de configurações necessárias eles só mudam elas de lugar, mas mesmo assim ja melhora um pouco, a versão 2.0 da especificação do JMX (Java Managenment Extensions) vai suportar a definição de MBeans via anotações como podemos ver neste post.
  • Parece que o JavaFX esta pegando mesmo, ja existem projetos para criação de bibliotecas de componentes para o JavaFX, alem do projeto do compilador que deve diminuir bastante o startup das aplicações em JFX transformando a aplicação em um .class padrão, mas o que eu quero realmente ver, é quando vai estar disponível o Java FX Mobile! por que quanto mais eu apanho pro Java ME, mais eu me convenço que Java ME só serve pra fazer joguinhos.
  • E depois que eu escreve um post sobre Design By Contract, na verdade em um dos comentários postados, fiquei sabendo do Spring DBC (Spring Design By Contract) que é uma biblioteca que facilita a utilização de Design By Contract em projetos que utilizam o Spring Framework, utilizando o AOP dinâmico do Spring Framework em vez de AOP estático do AspectJ, a única coisa que não gostei é que a especificação do “Contrato” é feita no XML, ou seja, longe da classe.
  • A Vingança dos Nerds! não, eu não estou falando daquele filme, estou falando deste post do BizRevolution, um ótimo post de uma “pessoa normal”, dizendo que mesmo os “humanistas” não gostando da idéia, o mundo é dos Nerds :D
  • A ZDnet finalmente revelou quais são os “7 hábitos dos desenvolvedores eficientes“, e sinceramente eu concordo com eles, com estes 7 hábitos, qualquer desenvolvedor se torna mais eficiente do que seria sem eles, os 7 hábitos são:
    • Entender o problema
    • Usar as ferramentas adequadas
    • Focar a simplicidade (foi a melhor tradução para Strive que eu consegui :( )
    • Mantenha o seu código limpo e claro
    • Aprenda a debugar
    • Use o que ja esta disponível (não re-invente a roda)
    • Continue a aprender
  • Ja começou a aprender a usar o Guice? se não começou ainda, ja esta na hora, tem empresas pedindo experiência com o Guice na hora de contratar, faz um tempinho já, mas eu falei um pouco sobre o Guice aqui no blog :D
  • glassfish.pngUm pouco sobre o Glassfish a implementação de referência do Java EE 5 (e um ótimo servidor de aplicações):
  • Sabe aqueles bug reports maravilhosos que ajudam aresolver problemas? se você gosta deles, não permita que seus usuários leiam isto. O Guia de como criar os piores bugs reports possíveis, e pior, baseado em fatos reais.
  • A equipe de desenvolvimento do Eclipse Web Tools ja esta trabalhando na versão 3.0, por enquanto a única alteração é o suporte ao Jetty :D
  • xplogo.gifXP: Melhor em Java ou em Ruby? é um post sobre um TCC falando de metodologias ágeis (no caso XP) comparando o mesmo projeto desenvolvido em Java e em Ruby, o meu único comentário sobre isto é: Ágil não quer dizer apenas entregar a primeira versão rápido (não estou dizendo que este é o caso), acho que as comparações deles valem tanto quanto dizer que delphi é melhor para desenvolvimento ágil do que java por que cria mais rápido uma aplicação Desktop de frontend para bancos de dados :D
  • Finalmente parece que o mercado esta acordando para as metodologias ágeis (tanto de desenvolvimento como de gerenciamento), todos os dias vejo uma noticia nova de mais uma empresa começando a utilizar XP ou SCRUM ou …
    Só espero que não façam a mesma porcaria que fizeram com o RUP que é muito bom, mas todas as empresas que eu conheço que dizem usar RUP usam Waterfall …
  • Java Server Faces

Tags: , , , , , , ,

30 Aug 07 Extra!Extra! Certificação Sun Certified Enterprise Architect 5 (Java EE 5) – e ainda por cima de grátis!

duke_winter.gifA SUN finalmente esta atualizando as provas da certificação SCEA para Java EE 5 (a versão anterior ainda falava de EJB 1.2, na verdade 1.2 e 2.0).
As inscrições para a prova BETA da certificação vão abrir no dia 20 de setembro de 2007.
A vantagem das provas beta é que são gratuitas, a desvantagem é que normalmente elas tem o dobro de questões que a prova normal :D
Mas passando na prova beta, você ganha o certificado sem desenbolsar R$1 …

Mais detalhes sobre o conteúdo da prova podem ser encontrados nesta thread do JaraRanch, mas basicamente é o seguinte:
javasparrow-med.jpg

  1. Application Design Concepts and Principles
  2. Common Architectures
  3. Integration and Messaging
  4. Business Tier Technologies
  5. Web Tier Technologies
  6. Applicability of Java EE Technology
  7. Patterns
  8. Security

Agora não tenho mais desculpas para não fazer a prova :D
Como na prova atual, a SCEA é dividida em 3 partes, uma prova objetiva, o desenvolvimento de uma arquitetura, e perguntas sobre a arquitetura desenvolvida …
Para se registrar, a partir do dia 20 de setembro, acessar o site http://www.2test.com/ e seguir os passos, ou ligar para o centro prometric mais próximo :D

Tags: ,