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

28 Nov 08 JUG Day em Porto Alegre/RS – dia 13 de dezembro de 2008

jugday

Jug Day – Um dia inteiro de Java

O Grupo de Usuários Java do Rio Grande do Sul (RSJUG), promove no dia 13 de dezembro o evento JUG Day, um dia inteiro dedicado à tecnologia Java.

O JUG Day é um evento semestral do RSJUG e conta com o apoio da SUCESU/RS. Esta edição ocorrerá nas instalações do Campus Tecnológico DC Shopping, do IPA Metodista, contando com uma grade de programação que envolve temas atuais no cenário Java, além de tutoriais de nível iniciante e intermediário, com o objetivo de promover a integração entre os participantes e difusão do conhecimento.

As inscrições estão abertas no site oficial (http://jugday.rsjug.org) com valor promocional de R$ 20,00 entre os dias 12 e 27 de novembro. Estudantes e associados SUCESU-RS têm desconto de R$5,00.

Tags: , ,

27 Nov 08 Certificação di Gratis: Prova beta para Sun Certified Developer for Java Web Services 5

Yeap, exatamente isto, a dica ta meio atrasada, mas só me registrei para fazer a prova hoje.
Para quem já tem a certificação SCJP (Sun Certified Java Programmer), pode fazer até o próximo dia 10/12/2008 “di gratis” a prova beta da nova certificação da SUN.
Não acredito que certificação prove alguma coisa, mas sempre ajuda colocar mais uma sigla no currículo, já que as empresas gostam delas por algum motivo :D

Quem quiser se inscrever, basta ligar para qualquer centro prometric ou acessar a página da prometric diretamente, não é necessário um voucher paraesta prova.

O conteúdo que estão pedindo não é nada demais para quem já trabalha com web services, segue o outline:

Exam Testing Objectives

  1. XML Web Service Standards
    1. Given XML documents, schemas, and fragments determine whether their syntax and form are correct (according to W3C schema) and whether they conform to the WS-I Basic Profile 1.1.
    2. Describe the use of XML schema in Java EE Web services
  2. SOAP 1.2 Web Service Standards
    1. List and describe the encoding types used in a SOAP message.
    2. Describe the SOAP Processing and Extensibility Model.
    3. Describe SOAP Message Construct and create a SOAP message that contains an attachment.
  3. Describing and Publishing (WSDL and UDDI)
    1. Explain the use of WSDL in Web services, including a description of WSDL’s basic elements, binding mechanisms and the basic WSDL operation types as limited by the WS-I Basic Profile 1.1.
    2. Describe how WSDL enables one to separate the description of the abstract functionality offered by a service from concrete details of a service description such as “how” and “where” that functionality is offered.
    3. Describe the Component Model of WSDL including Descriptions, Interfaces, Bindings, Services and Endpoints.
    4. Describe the basic functions provided by the UDDI Publish and Inquiry APIs to interact with a UDDI business registry.
  4. JAX-WS
    1. Explain JAX-WS technology for building web services and client that communicate using XML
    2. Given a set of requirements for a Web service, such as transactional needs, and security requirements, design and develop Web service applications that use JAX-WS technology
    3. Describe the Integrated Stack (I-Stack) which consists of JAX-WS, JAXB, StAX, SAAJ
    4. Describe and compare JAX-WS development approaches.
    5. Describe the features of JAX-WS including the usage of Java Annotations.
    6. Describe the architecture of JAX_WS including the Tools SPI that define the contract between JAX-WS tools and Java EE.
    7. Describe creating a Web Service using JAX-WS.
    8. Describe JAX-WS Client Communications Models.
    9. Given an set of requirements, design and develop a Web service client, such as a Java EE client and a stand-alone client, using JAX-WS.
    10. Given a set of requirements, create and configure a Web service client that accesses a stateful Web service.
  5. REST, JSON, SOAP and XML Processing APIs (JAXP, JAXB and SAAJ)
    1. Describe the characteristics of REST Web Services.
    2. Describe the characteristics of JSON Web Services.
    3. Compare SAOP web services to REST Web Services.
    4. Compare SAOP web services to JSON Web Services.
    5. Describe the functions and capabilities of the APIs included within JAXP.
    6. Describe the functions and capabilities of JAXB, including the JAXB process flow, such as XML-to-Java and Java-to-XML, and the binding and validation mechanisms provided by JAXB.
    7. Create and use a SOAP message with attachments using the SAAJ APIs.
  6. JAXR
    1. Describe the function of JAXR in Web service architectural model, the two basic levels of business registry functionality supported by JAXR, and the function of the basic JAXR business objects and how they map to the UDDI data structures.
    2. Create JAXR client to connect to a UDDI business registry, execute queries to locate services that meet specific requirements, and publish or update information about a business service.
  7. Java EE Web Services
    1. Identify the characteristics of and the services and APIs included in the Java EE platform.
    2. Explain the benefits of using the Java EE platform for creating and deploying Web service applications.
    3. Describe the functions and capabilities of the JAXP, DOM, SAX, StAX, JAXR, JAXB, JAX-WS and SAAJ in the Java EE platform.
    4. Describe the role of the WS-I Basic Profile when designing Java EE Web services.
  8. Security
    1. Explain basic security mechanisms including: transport level security, such as basic and mutual authentication and SSL, message level security, XML encryption, XML Digital Signature, and federated identity and trust.
    2. Identify the purpose and benefits of Web services security oriented initiatives and standards such as Username Token Profile, SAML, XACML, XKMS, WS-Security, and the Liberty Project.
    3. Given a scenario, implement Java EE based web service web-tier and/or EJB-tier basic security mechanisms, such as mutual authentication, SSL, and access control.
    4. Describe factors that impact the security requirements of a Web service, such as the relationship between the client and service provider, the type of data being exchanged, the message format, and the transport mechanism.
    5. Describe WS-Policy that defines a base set of constructs that can be used and extended by other Web specifications to describe a broad range of service requirements and capabilities.
  9. Developing Web Services
    1. Describe the steps required to configure, package, and deploy Java EE Web services and service clients, including a description of the packaging formats, such as .ear, .war, .jar, annotations and deployment descriptor settings.
    2. Given a set of requirements, develop code to process XML files using the SAX, StAX, DOM, XSLT, and JAXB APIs.
    3. Given an XML schema for a document style Web service create a WSDL file that describes the service and generate a service implementation.
    4. Given a set of requirements, create code to create an XML-based, document style, Web service using the JAX-WS APIs.
    5. Implement a SOAP logging mechanism for testing and debugging a Web service application using Java EE Web Service APIs.
    6. Given a set of requirements, create code to handle system and service exceptions and faults received by a Web services client.
  10. Web Services Interoperability Technologies
    1. Describe WSIT, the features of each WSIT technology and the standards that WSIT Implements for each technology and how it works.
    2. . Describe how to create a WSIT client from a Web Service Description Language (WSDL) file.
    3. Describe how to configure web service providers and clients to use message optimization.
    4. Create a Microsoft Windows Communication Foundation (WCF) client that accesses a Java web service.
    5. Describes the best practices for production and consumption of data interoperability between WCF web services and Java web service clients or between Java web services and WCF web service clients.
  11. General Design and Architecture
    1. Describe the characteristics of a Service Oriented Architecture (SOA) and how Web services fit to this model.
    2. Given a scenario, design a Java EE web service using Web Services Design Patterns (Asynchronous Interaction, JMS Bridge, Web Service Cache, Web Service Broker), and Best Practices.
    3. Describe how to handle the various types of return values, faults, errors, and exceptions that can occur during a Web service interaction.
    4. Describe the role that Web services play when integrating data, application functions, or business processes in a Java EE application.
    1. Endpoint Design and Architecture
    1. Given a scenario, design Web Service applications using information models that are either procedure-style or document-style.
    2. Describe the function of the service interaction and processing layers in a Web service.
    3. Design a Web service for an asynchronous, document-style process and describe how to refactor a Web Service from a synchronous to an asynchronous model.
    4. Describe how the characteristics, such as resource utilization, conversational capabilities, and operational modes, of the various types of Web service clients impact the design of a Web service or determine the type of client that might interact with a particular service.

Mais informações na página da certificação.
Depois da prova (vou fazer dia 10) eu posto o que achei das questões por aqui.

Tags: , ,

26 Nov 08 Nova cara para o blog

Acabei de atualizar o WP e aproveitei para mudar o tema do blog também.
Acho que este é mais clean que o anterior.

O que vocês acham?

Sei que a maior parte lê só pelo feed mesmo, mas agradeço comentários.
Vou pensar em tirar uma das barras laterais, mas por enquanto ficam duas mesmo :D

19 Nov 08 Curso básico de refactoring para quem é pobre e preguiçoso

Continuando com a seqüência de posts com títulos polêmicos que comecei dizendo que “Comentário no código é para os fracos“, segue um curso básico de refactoring para quem é pobre (por que vou utilizar o eclipse que é uma excelente IDE e alem de tudo é “di grátis”), e preguiçoso, por que o eclipse vai fazer quase todo o trabalho para nós.
O ponto de partida vai ser o “exercício” que deixei no final do post sobre comentários no código.
Par quem não quiser ler todo o outro post, o código inicial vai ser este abaixo:

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);
	}
}

Antes de começar o refactoring, vamos definir o que é refactoring de uma forma bem simples:
Refactoring = Alterar partes do código de uma aplicação sem quebrar outras partes da aplicação que dependam daquele código.
Refactoring é uma forma de melhorar o design de um código existente enquanto ele continua funcionando.
Gosto muito de uma frase espetacular do Fowler, um dos papas do desenvolvimento ágil, que coloco abaixo:

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999

Nos vamos utilizar os recursos de refactoring do Eclipse para transformar este lixo acima em alguma coisa legível, mantendo exatamente o mesmo comportamento, ou seja, sem quebrar o código que já funciona.
Para facilitar o trabalho, este tutorial (se é que pode ser chamado de tutorial), vai ser um simples “passo a passo” que eu utilizei para alterar este código no Eclipse, que é a minha segunda IDE preferida (a melhor de todas na minha opinião é o IntelliJ IDEA, mas se eu utilizasse este, não seria um tutorial para quem é pobre :D )
Siga os passos abaixo:

  1. Primeiro vamos renomear a classe, com o arquivo aberto, o cursos sobre o nome da classe (VeryBaclyNamedFile) pressione ALT+SHIFT+R e substitua o nome da classe por “TextFileToScreenPrinter” depois pressione “Enter”
  2. Agora esta na hora de alterar os nomes de alguns métodos. Repetindo exatamente o mesmo procedimento (ALT+SHIFT+R, altera nome, Enter), faça as seguintes alterações nos nomes de métodos e variáveis:
    • asdfg -> standardContentForNewFiles
    • an -> fileName (neste caso no parâmetro do construtor e na variável de instância)
    • ctfiidne -> ensureFileAlreadyExists
    • canIDoAnyThing -> abortIfCanNotReadOrWriteFile
    • startDoing -> createFileReader
    • temp -> rawFileReader (neste caso no parâmetro do construtor e na variável de instância)
    • rfsdw -> fileLineReader (neste caso no parâmetro do construtor e na variável de instância)
    • nowReallyDoIt -> printEachLineFromFileToConsole
    • yicdet -> e
    • firstDoTheOtherThing -> createLineReaderFromFileReader
    • reallyDoItInternal -> forEachLineInTheFilePrintItOnTheScreen
    • imDoingIt -> printNextLineOfFileToStdOutButFailIfThereAreNoMoreLines
  3. Agora com nomes menos ruins para os métodos vamos começar a organizar um pouco as coisas, dentro do método “abortIfCanNotReadOrWriteFile” selecione o trecho “new File(fileName).exists()”, pressione as teclas ALT+SHIFT+L e de o nome “fileExists” para a variável, agora repita a operação para o bloco “new File(fileName).canRead()” e de o nome “canReadTheFile” para a variável, e por último repita a operação com o bloco “new File(fileName).canWrite()” e nomeie a variável “canWriteToTheFile”.
  4. Agora podemos ler facilmente que a lógica deste método esta invertida, então precisamos negar as variáveis no “if” dentro do método “abortIfCanNotReadOrWriteFile”.
  5. Agora dentro do método “doIt”, podemos remover o try/catch.
  6. Editando o método “createLineReaderFromFileReader”, vamos mudar o tipo sendo utilizado para inicializar a variável “fileLineReader” para um java.util.Scanner, para isto basta substituir o bloco “new BufferedReader(rawFileReader);” por “new Scanner(rawFileReader);”. No momento em que isto for feito, o eclipse vai reclamar que não sabe o que é “Scanner”, então precione CTRL+1 com o cursor sobre a palavra “Scanner” e selecione “import java.util.Scanner”. Agora a reclamação é um “type mismatch”, simplesmente precione CTRL+F1 novamente e selecione a opção “Change the type of fileLineReader to Scanner”. E por último, vamos adicionar a seguinte linha neste método:
    1
    
    fileLineReader.useDelimiter("\n");
  7. Para melhorar um pouco o código, vamos remover os dois parâmetros extras do construtor da clase, o único parâmetro que deve ficar no construtor é o primeiro, que aponta para o arquivo que deve ser lido. Para fazer isto, coloque o cursor sobre o construtor e pressione ALT+SHIFT+C, remova os dois parâmetros extras no dialogo e clique em finish, como esta alteração vai causar um erro no código, será necessário clicar em continue no próximo dialogo. Para corrigir o erro, remova as linhas 19 e 21, o eclipse deve ter sublinhado estas linhas em amarelo.
  8. O código esta começando a parecer um pouco melhor, mas ainda precisa de alterações (no momento ele não deve estar nem compilando se você seguiu todos os passos até agora). Vamos então remover o método “printNextLineOfFileToStdOutButFailIfThereAreNoMoreLines”, e alterar o código do método “forEachLineInTheFilePrintItOnTheScreen” para algo parecido com o bloco abaixo:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    Iterable<String> lineIterator = new Iterable<String>(){
      @Override
      public Iterator<String> iterator() {
        return fileLineReader;
      }
    };
    for(String line : lineIterator){
      System.out.println(line);
    }
  9. Para melhorar o código do método, selecione a criação do iterator toda (deve ser da linha 40 a 45 no arquivo), pressione as teclas ALT+SHIFT+M e digite o nome “initializeLineIteratorFromLineReader” para o novo método.
  10. Agora utilizando o refactoring de rename (ALT+SHIFT+R) altere o nome da variável “lineIterator” para “linesInTheFile”, desta forma o último bloco do método pode ser lido exatamente igual ao nome do método.
  11. Agora no método “ensureFileAlreadyExists” vamos alterar o conteúdo para o seguinte bloco:
    1
    2
    3
    4
    5
    6
    7
    
    File file = new File(fileName);
    boolean fileExists = file.exists();
    if (!fileExists) {
      FileWriter fileWriter = new FileWriter(file);
      fileWriter.write(conteudoPadraoParaNovoArquivo);
      fileWriter.close();
    }
  12. Se você já esta se acostumando com os refactorings, vai perceber que o que foi feito foi um “extract variable” na condição do IF, e dois renames, um na variável que aponta para o arquivo e outro na variável que aponta para o FileWriter.
  13. Agora que quase todas as variáveis e métodos tem nomes decentes, podemos fazer algumas alterações na lógica, para limpar um pouco o código desta classe, como por exemplo, remover o método “createFileReader” e a variável “rawFileReader”, alterar o método “createLineReaderFromFileReader” para passar “new File(fileName)” como parâmetro na criação do Scanner.
  14. Isto vai gerar um erro de compilação, com o CTRL+1 poderemos adicionar a exception que falta no throws do método e tudo vai ficar OK.
  15. Podemos renomear o método “createLineReaderFromFileReader” para apenas “createLineReader”.

Pronto, o Eclipse acabou de nos ajudar a ter um código menos porco na classe do post sobre comentários de código.
Claro que o código ainda não esta nenhum primor, mas a idéia deste post era mostrar que é possível utilizar recursos da IDE para facilitar o refactoring de código porco quando este for encontrado.
E não se iluda, se você estuda para melhorar o seu conhecimento sobre desenvolvimento e ser um profissional cada vez melhor, provavelmente o código que você escreveu a dois meses atrás você ache muito ruim hoje.

Só para finalizar o post, o seu código deve ter ficado parecido com este:

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
package blog;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Scanner;
 
public class TextFileToScreenPrinter {
	private static final char[] standardContentForNewFiles = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'};
	private String fileName;
	private Scanner fileLineReader;
 
	public TextFileToScreenPrinter(String fileName) {
		super();
		this.fileName = fileName;
	}
 
	public void doIt() throws IOException {
		ensureFileAlreadyExists();
		abortIfCanNotReadOrWriteFile();
		printEachLineFromFileToConsole();
	}
 
	private void printEachLineFromFileToConsole() throws FileNotFoundException {
		createLineReader();
		forEachLineInTheFilePrintItOnTheScreen();
	}
 
	private void createLineReader() throws FileNotFoundException {
		fileLineReader = new Scanner(new File(fileName));
		fileLineReader.useDelimiter("\n");
	}
 
	private void forEachLineInTheFilePrintItOnTheScreen() {
		Iterable<String> linesInTheFile = initializeLineIteratorFromLineReader();
		for(String line : linesInTheFile){
			System.out.println(line);
		}
	}
 
	private Iterable<String> initializeLineIteratorFromLineReader() {
	  Iterable<String> lineIterator = new Iterable<String>(){
			@Override
      public Iterator<String> iterator() {
	      return fileLineReader;
      }
		};
	  return lineIterator;
  }
 
	private void ensureFileAlreadyExists() throws IOException {
		File file = new File(fileName);
		boolean fileExists = file.exists();
		if (!fileExists) {
			FileWriter fileWriter = new FileWriter(file);
			fileWriter.write(standardContentForNewFiles);
			fileWriter.close();
		}
	}
 
	private void abortIfCanNotReadOrWriteFile() {
		boolean fileExists = new File(fileName).exists();
		boolean canReadTheFile = new File(fileName).canRead();
		boolean canWriteToTheFile = new File(fileName).canWrite();
		if (!fileExists && !canReadTheFile && !canWriteToTheFile)
			throw new RuntimeException();
	}
 
}

Atalhos do Eclipse Ganimede que todo preguiçoso inteligente deveria decorar

  • ALT+SHIFT+M -> Extract method
  • ALT+SHIFT+L -> Extract Local Variable
  • ALT+SHIFT+R -> Rename
  • CTRL+1 -> Quick Fix
  • ALT+SHIFT+X,J -> Executa aplicação Java
  • ALT+SHIFT+X,T -> Executa Unit Test
  • ALT+SHIFT+X -> Executar, se o tipo não for especificado, um menu será aberto em 5 segundos no canto inferior direito
  • CTRL+SPACE -> Code completion
  • CTRL+SHIFT+SPACE -> Parameter completion
  • CTRL+3 -> Atalho super mega mágico para qualquer tarefa dentro do eclipse,digite o nome do que quer fazer no dialogo que vai aparecer
  • ALT+SHIFT+S -> menu “source” onde ficam comandos como “Generate getters and setters” e “Override/Implement methods”
  • ALT+SHIFT+T -> Menu de refactoring

Atalhos do Eclipse apra usuáriso de MAC

  • COMMAND+OPTION+M -> Extract method
  • COMMAND+OPTION+L -> Extract Local Variable
  • COMMAND+OPTION+R -> Rename
  • COMMAND+1 -> Quick Fix
  • COMMAND+OPTION+X,J -> Executa aplicação Java
  • COMMAND+OPTION,T -> Executa Unit Test
  • COMMAND+OPTION+X -> Executar, se o tipo não for especificado, um menu será aberto em 5 segundos no canto inferior direito
  • CTRL+SPACE -> Code completion
  • COMMAND+3 -> Atalho super mega mágico para qualquer tarefa dentro do eclipse,digite o nome do que quer fazer no dialogo que vai aparecer
  • COMMAND+OPTION+S -> menu “source” onde ficam comandos como “Generate getters and setters” e “Override/Implement methods”
  • COMMAND+OPTION+T -> Menu de refactoring

E o atalho de teclado mais mágico de todos é:

COMMAND+SHIFT+L (CTRL+SHIFT+L em PCs) -> Lista os atalhos de teclado. :D

Acho que isto já esta bom para começar, se você for realmente um preguiçoso inteligente (o tipo que passa um pouco mais de tempo pensando para ter uma solução melhor agora e trabalhar menos no futuro), provavelmente você vai prestar atenção nos menus do eclipse e vai ir decorando as teclas de atalho com o tempo :D

PS.: Será que alguém vai ficar ofendido com o titulo deste post e vai ficar reclamando que não é pobre ou não é preguiçoso?

Tags: , , ,

17 Nov 08 Espaço, a fronteira final! Dia 8 de maio de 2009! Star Trek the movie!

É isto mesmo, Star Trek “The Movie” dia 8 de maio de 2009 nos cinemas!
Deem uma olhada no site http://www.startrekmovie.com/.
Vai ser espetacular o filme, é o primeiro filme que conta um pouco de antes de construirem a USS Enterprise (fora as viagens para o passado durante os seriados).

Um trailer

Outro trailer

E ainda hoje deve sair mais um trailer no site oficial do filme http://www.startrekmovie.com/.

Este eu quero ver :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: , , ,

10 Nov 08 Java Enterprise Edition 6.0 esta ficando bem legal

O Java EE esta cada vez mais simples de se utilizar, então por definição esta cada vez melhor.
O motivo deste post são algumas melhorias vindas da especificação do EJB 3.1 que eu achei espetaculares:
Interface local opcional
Exatamente isto, agora a interface local dos EJBs é Opcional. Isto permite que o seguinte código seja válido:

1
2
3
4
@Stateless
public class HelloBean {
   public String hello() { return "hello"; }
}

E o cliente utiliza isto mais ou menos assim:

1
2
3
@EJB Hello helloRef;
...
helloRef.hello();

Mesmo a classe sendo acessada diretamente, o cliente nunca instância o objeto com um “new”, ele recebe um proxy, exatamente como se estivesse trabalhando com uma interface, mas mesmo assim o modelo fica mais simples e é menos trabalho para o programador :D

Nomes globais JNDI portáveis
Não sei se fui apenas eu, mas é um inferno desenvolver aplicações Java EE que precisem acessar EJBs em mais de um container, exceto se elas puderem fazer isto via anotações o que não cobre 100% dos casos, cada container utiliza um nome global diferente para o EJB, agora no Java EE 6 o nome global dos EJBs faz parte da especificação, então vai ser igual para todos os containers :D
Só quero ver como eles vão fazer para manter a compatibilidade com versões anteriores dos mesmos containers, acho que os EJBs vão ter nome e apelido :D
A sintaxe para os nomes globais dos EJBs vai ser a seguinte:
java:global[/<app-name>]/<module-name>/<bean-name>
E caso o session bean exponha mais de uma interface, o nome vai ser:
java:global[/<app-name>]/<module-name>/<bean-name>/<intf-name>
Isto quer dizer que para o EJB abaixo:

1
2
@Stateless
public class FooBean implements FooRemote { ... }

Publicado em um arquivo de nome foobar.jar, podemos acessa-lo com o seguinte código:

1
FooRemote foo = (FooRemote) =  new InitialContext().lookup("java:global/foobar/FooBean")

E acabou o nome especifico para cada container, ou pior, nome para cada deployment como alguns containers faziam.

Empacotamento de EJBs Simplificado
No Java EE 6 não será mais necessário em uma aplicação criar um .war para a aplicação web, um .jar para os EJBs e empacotar tudo isto em um .ear só para acessar alguns EJBs pela aplicação WEB, vai bastar colocar os EJBs dentro do WEB-INF/classes ou até mesmo em um jar dentro do WEB-INF/lib da aplicação WEB e tudo vai funcionar como mágica :D

Singleton EJBs
Esta última novidade eu não sei se é boa ou ruim …
Singletons são a forma mais podre de programação não orientada a objetos em uma linguagem OO.
Claro que em raros casos um singleton é realmente utilizado como um singleton e neste caso ele é realmente útil, mas eu vi apenas uns dois ou três casos destes até hoje, todas as outras aplicações que tem diversos singletons utilizam os mesmos como um repositório de métodos que não pertencem a objeto nenhum. Ou seja, uma entidade não OO na aplicação …
Mas fora a discussão filosófica, o pior é achar que você tem um singleton e a aplicação possuir duas instâncias do mesmo, por que na implementação clássica de singletons no java, eles são singletons apenas por classloader, o que causa diversos problemas …
Para solucionar este problema, o Java EE 6 possui EJBs Singletons :D
Exatamente isto.
Eles são utilizados como qualquer outro EJB, mas existira apenas uma instância dele no container ou no cluster, ou seja, apenas uma instância na aplicação …
Para criar um EJB Singleton, o código vai ser mais ou menos este:

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.sun.ejb31.test;
 
import javax.ejb.Singleton;
@Singleton
public class CounterBean {
    private int hitCount;
 
    //Perceba a utilização de synchronized aqui
    public synchronized int incrementAndGetHitCount() {
        return hitCount++;
    }
 
}

E era isto, utilize como no primeiro exemplo!

Bom, por enquanto era isto, estou achando que o Java EE 6 vai matar a pau, ainda mais juntando com a especificação de WebBeans que deve sair junto!

Tags: , ,

07 Nov 08 IDE REVIEW: RubyMine – a melhor IDE para Rails até agora

Em todos os meus trabalhos com Ruby On Rails até agora eu não achei necessária uma IDE, pois eu sempre fui mais produtivo com simples editores de texto (tudo bem, não eram editores tão simples assim), As IDEs eram sempre lentas, muito mais lentas que os editores de texto. Mas o pessoal da JetBrains se superou, na verdade não se superou, pois o IntelliJ IDEA ja é expetacular.
Mas o RubyMine é a IDE para Rails [bb]mais rápida até agora, com performance similar ao GEdit e GVim que são os meus editores favoritos (mesmo preferindo o KDE não consigo me acostumar com o Kate).
Eu não sei direito como eles fizeram, mas o code completion para Ruby e Rails esta muito rápido.
A IDE ficou Leve, o que é uma novidade interessante, pois o IntelliJ IDEA é quase tão pesado quanto o Eclipse.
E o melhor de tudo! O RubyMine tem Refactorings para código Ruby, coisa que não encontrei em nenhuma outra IDE (o NetBeans tem algumas tentativas, mas no meu último teste não funcionaram muito bem).
Bom, segue então uma lista do que faz o RubyMine ser uma ótima IDE para desenvolvimento Rails na minha opinião, com alguns screenshots :D


Como o Aptana e o Netbeans o Rubymine tem integração com o “script/generate”, com dialogos bonitinhos para criar cada item, mas isto o Netbeans também tem, e fora os dialogos no GVim com um :Rgen faço a mesma coisa :D


O RubyMine também tem code completion simples, como todas as outras IDEs para Ruby e Rails, o Eclipse tem isto, o Aptana tem, até o GVim tem quando rodando em um Linux (No windows não consegui fazer o Omnicompletion funcionar :D )


Mas aqui a coisa começa a ficar mais divertida, o code completion do RubyMine é inteligente o suficiente para saber quais são os parâmetros possívels para a maioria dos métodos do Rails.
Claro que ele não inferiu isto pelo código, é a integração com o Rails que ja conhece os métodos, mas mesmo assim, este é um recurso que eu não encontrei em nenhuma outra IDE para Ruby ou Rails até agora.


Outra coisa interessante são os refactorings disponíveis.
Este do screenshot é um extract local variable, que substitui uma expressão por uma variável em todo o arquivo.
Alem deste, testei alguns outros refactorings como rename, extract class, …
Só não consegui fazer funcionar o Extract Method que eu realmente queria que funcionasse, seria muito bom ter um Extract Method para código Ruby.

Isto fora os recursos ja conhecidos do IntelliJ IDEA para edição de HTML e Javascript, com refactorings para ambos. E o fato de o RubyMine ser a IDE mais rápida para Ruby que eu encontrei até agora. Fazem ela ser a minha preferida desde ontem também :D

Claro que trabalhei com ela muito pouco tempo, mas mesmo assim, ja gostei bastante do que vi.
Só falta ver como vão ficar os preços, ja que é uma IDE comercial.
Se o preço for bom, por exemplo, próximo ao preço do TextMate, vai valer a pena com certeza!

Tags: , , , , , ,

07 Nov 08 Kubuntu com KDE 4.1 – desktop show de bola e bem rapido :D


Este é o meu desktop em casa rodando o Kubuntu 8.10.
Esta um espetaculo.
Tudo bem que eu sempre gostei mais do KDE do que do Gnome, e que cada um tem um gosto, mas o KDE 4.1 ficou show de bola.
Mas este post não é para mostrar um screenshot do meu desktop, é para dar a dica de como resolver um bug chato no Kubuntu 8.10.
Logo depois que eu instalei o KDE 4.1 a cada 10 segundos aproximadamente a tela fazia um flick ou algo parecido com isto, e eu ja estava quase abandonando o KDE para instalar o Gnome.
Foi quando eu abri as configurações do KDE, em Avançado, serviços e desabilitei o processo KDED.
tudo passou a funcionar perfeitamente!

E só pra constar, ele esta mais rápido do que as versões do KDE3 que eu estava utilizando antes.

Então se estiver com o mesmo problema, é só fazer o mesmo.
PS.: parece que isto faz o KDE não reconhecer monitores conectados ao computador depois dele ligado, mas ai é só ativar e desativar o serviço quando necessário, eu vou testar ligando o note na televisão em casa no findi e atualizo o post dizendo o que aconteceu.