Creating a WebServer

Hello, how are you?

Today’s post will be a little different. I will post about how to load a Servlet “Hello World” using forward. This post purpose it’s to let us have some base of web services, so in the future, I can post here some web service with Hibernate, Struts, Ajax, Log4J, RB and others things. It’s already a base to those who does not know how to load a web service, might follow the “advanced” posts, and even learn how can make a simple one web service. And, in the end, I will show some topics about SCWCD that we saw here (SCWCD it’s the Java certification for Web).

You will need to have JDK installed at you pc. I will make this tutorial using an IDE just to make it easier, but if you want to make without an IDE, you just have to use all created files here (XML, Java, JSP, and HTML). At the end of this post I will show how to do it without an IDE.

Two downloads are needed:

First, we shall install the Tomcat.
01) I chose the Full configuration and did “Microsoft installation pattern: Next, Next, Finish”.
Instal Tomcat 01

02) Tomcats icon will be at your system bar, if it’s not green just click on it with the right button and select “Start Service”.
Instal Tomcat 02

03) Open your browser and type http://localhost:8080, it will show you that our server is installed and ready to use.
Instal Tomcat 03

04) We shall stop Tomcat service for now. We will execute it through Eclipse, so there is no reason to leave it active.
Instal Tomcat 04

Uncompress the Eclipse file, and execute it (eclipse.exe). Eclipse will ask you to select a workspace, it’s a place where Eclipse will store the project and the configurations that we do. The directory that you chose won’t affect the final purpose of this post, so select the directory that you feel more comfortable with.
Config Eclipse 01

A Welcome Screen will be displayed, let’s change to Java perspective.
Config Eclipse 02

Let’s go to the View Servers.
Config Eclipse 03

Type Servers and choice the View.
Config Eclipse 04

Now, let’s add Tomcat. Right button on: “Servers -> New -> Server”.
Config Eclipse 05

Select Tomcat 7.
Config Eclipse 06

Point the Tomcat installation folder. Then click on Finish button.
Config Eclipse 07

Almost done with those configurations we got just one last. Double click on the Tomcat server that is on the Servers Views. A configuration screen will be displayed.
Let’s change the configuration “Server Locations” to “Use Tomcat installation (takes control of Tomcat installation)”. This configuration allow that Eclipse might have the control over Tomcat, by doing this, every time we need to change anything at the server, we can make in here. Now, just close and save it.
Config Eclipse 08

Finally, let’s do some code! o Uhull!
Create a new project at Eclipse. We will name this project of Servlet. File > New > Other.
Project 01

Type “Dynamic Web Project” and select a Web project.
Project 02

Type “Servlet” as our project name and press Finish button.
Project 03

Eclipse will ask if you want change perspective. Check no. Let’s get used to one perspective, after you can test the others at your will.
Project 04

Let’s create a first page, a welcome home page. Right click on “WebContent” > New > File.
Project 05

Name the file as index.html and click on “Finish”.
Project 06

Let’s edit index.html file, double click on it. I’ll put the code in here:

<html>
    <body>
        <h1>Olá</h1>
    </body>
</html>

We will create now a “web.xml” file, to access our welcome page. To do it, right click on “WEB-INF > New > File”. Remember, this file must stay on WEB-INF folder!
Project 07

All web.xml files have its first lines with some default configurations. You might find it easily at internet that is why I will just type it here without explains.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>hello</servlet-name>
    <jsp-file>/index.html</jsp-file>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

In another day, I might explain better about web.xml tags. For now:

  • For each servlet (< servlet >) we need a mapping (< servlet-mapping >). The mapping it’s the one that will show a direction to each URL typed at the browser. The Servlet does not need to be a Java class. Realize that we are mapping the typed URL to a HTML page. In other words, mapping is used to capture the typed URL and send it to a servlet.

To run our little application right click on our project Servlet > Run as > Run on Server.
Project 08

Just click on “Finish”.
Project 09

Eclipse will open a web browser and will show the welcome page. If your Eclipse does not open the browser, after Tomcat be active, just type the follow address at your web browser: http://localhost:8080/Servlet/hello . After the first page, push the red button to stop the server, we have a lot of work ahead.

Let’s do some refactor at the index.html so it might be able to send values, and our servlet will handle those values and send it to another page. Our field names will be name, value1 and value2. Realize that we got 3 tags: “form”, “action” and method. Form put all values inside its body, it is like a bag. Everything inside the form body will go inside the request. Method will define wich kind of request will be done, there are several types and for now we are going to use the “post”. Action defines the destination our request will be delivered.

<html>
    <body>
        <form action="/Servlet/mathit" method="post">
            <h1>Hello</h1>
            Type your name: <input type="text" name="name"/> <br/><br/>
            Lets do some math?<br/>
            Type the first value to be added: <input type="text" name="value1"/> <br/>
            Type the second value to be added: <input type="text" name="value2"/> <br/><br/>
            <input type="submit" value="Do some math"/>
        </form>
    </body>
</html>

Now, we are going to create a Servlet (Java class that will handle the request). Inside the fold src we will create a package and a Java class that will extend HttpServlet. This class will receive the values from our index.html, to sum the values and forward it to a jsp.
Project 11a

Project 11b

Project 12

Project 13

package com;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Servlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse res)    throws ServletException, IOException {
        int value1;
        int value2;
        int total = 0;
        String name = (String) req.getParameter("name");
        String warning = "";
        try {
            // I know this is ugly, but in a future we can do some refactor and apply some OO and Design principles
            value1 = Integer.parseInt((String) req.getParameter("value1"));
        } catch (NumberFormatException e) {
            // Catching this execption in case some invalid value was sent
            value1 = 0;
            warning = "We got some bad value(like in blank or non numerics values, we set 0 instead";
        }
        
        try {
            // I know this is ugly, but in a future we can do some refactor and apply some OO and Design principles
            value2 = Integer.parseInt((String) req.getParameter("value2"));
        } catch (NumberFormatException e) {
            // Catching this execption in case some invalid value was sent
            value2 = 0;
            warning = "We got some bad value(like in blank or non numerics values, we set 0 instead";
        }
        // Setting the name inte the request
        req.setAttribute("name", name);
        
        // Sending the warning to the customer
        req.setAttribute("warning", warning);

        total = value1 + value2;
        
        // Setting the total value ate the request
        req.setAttribute("total", total);
        
        // The Request Dispatcher sets the next direction to the webservice.
        // Lets redirect to the JSP that we will create.
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/show.jsp");
        
        // Sends the process forward with the request and the response
        requestDispatcher.forward(req, res);
    }
}

We will show the sum value and the sent name from our first page. Our JSP will be inside WEB-INF folder. Pay attention, inside WEB-INF folder!
Project 14

Project 15

<%@page isELIgnored="false" %>
<html>
    <body>
        Thanks ${name} for passing by. <br/>
        The total is: ${total}. <br/>
        
        <br/>${warning}
    </body>
</html>

Almost done, we will change our web.xml so it might be able to handle our new request. Do you remember our tag “action=mathit” at index.html? It is now that we are going to map it so Tomcat knows how to work with.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>  
    </welcome-file-list>
  
    <servlet>
        <servlet-name>hello</servlet-name>
        <jsp-file>/index.html</jsp-file>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>final</servlet-name>
        <servlet-class>com.Servlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>final</servlet-name>
        <url-pattern>/mathit</url-pattern>
    </servlet-mapping> 
</web-app>

Now just starts Tomcat just like when we did the first time to access our first page, our servlet will work fine.
PS.: If your Tomcat shows an error message and does not work, go to: Servers > Tomcat (folder) > server.xml. Open it and then push F5. Execute Tomcat again.
Project 16

And to run the web service without the Eclipse it’s easier. We will use all files created here (those might be created even using a computer notepad). First, inside Tomcats installation folder, go to wtpwebapps and create the folders tree bellow (inside WEB-INF folder, it must have the same files):
Project 17

Project 18

Inside Servlet folder put the index.html file. And inside “/classes/com” will be our Servlet.class. Our file .class you can find it inside the workspace you have set up when we started the Eclipse.

Now, just start Tomcat service (like we did when we installed the Tomcat) and type http://localhost:8080/Servlet/hello in your browser.

About SCWCD:

  • All files inside WEB-INF folder are protected. Try to access our jsp: http://localhost:8080/Servlet/show.jsp . Now if we talk about index.html we can access it directly because this file is not inside of the WEB-INF folder http://localhost:8080/Servlet/index.html . All files inside WEB-INF folder are protected from direct access. Always remember this! ;)
  • Its worth memorize a sample of web.xml (with all other tags), because those tags and mappings will be found at the test.

I hope this post might be useful to you.
See you soon.

OBS.: Sorry about the double posts. I got some erros about names!

Criando um WebServer

Boa tarde, tudo bem?

Hoje o post vai ser um pouco diferente. Vou postar como levantar um Servlet “Hello World” utilizando forward. O propósito do post é para que mais para frente, eu possa postar aqui WebService com integração de Hibernate, Struts, Ajax, Log4J, RB e mais outras coisas. Já é uma base para quem não sabe como levantar um WebService, para depois poder acompanhar os exemplos mais complexos e até mesmo aprender como se faz o simples. E ao final, assuntos vistos sobre SCWCD (certificação Java para Web). É necessário ter o Java JDK instalado.

Vou fazer utilizando uma IDE, pois fica mais fácil, mas caso queira fazer todo o processo sem IDE, basta utilizar todos os arquivos criados aqui (XML, Java, JSP, HTML). Ao final do artigo vou mostrar como se faz sem IDE.

Dois downloads são necessários:

Primeiro, vamos instalar o Tomcat.
01) Utilizei a configuração Full e “padrão Microsoft: Next, Next, Finish”.
Instal Tomcat 01

02) O ícone do Tomcat vai aparecer na barra do sistema, caso não esteja verde, bastar clicar com o botão direito e selecionar “Start Service”.
Instal Tomcat 02

03) Depois abra seu browser e digite http://localhost:8080, será exibido que o servidor está instalado e pronto para usar.
Instal Tomcat 03

04) Vamos parar o serviço do Tomcat. Nós iremos executá-lo através do eclipse, então não existe a necessidade de deixarmos ele ativo.
Instal Tomcat 04

Após descompactar o Eclipse, vamos abri-lo e começar a configurar o Tomcat. O Eclipse irá solicitar que você escolha um “workspace”, um espaço de trabalho onde o eclipse irá guardar os projetos assim como as configurações que fizermos. A escolha desse diretório, não afetará o resultado final desse artigo, então fique a vontade para escolher o diretório que mais lhe agradar.
Config Eclipse 01

Vai aparecer a tela de “Seja Bem Vindo”. Vamos então mudar para a perspectiva Java.
Config Eclipse 02

Vamos agora escolher a View de servidores.
Config Eclipse 03

Digite Servers e selecione a View.
Config Eclipse 04

Agora, vamos adicionar o Tomcat. Botão direito em Servers -> New -> Server.
Config Eclipse 05

Vamos selecionar o Tomcat 7
Config Eclipse 06

E temos agora que apontar o diretório onde foi instalado o Tomcat. E depois clicar em Finish.
Config Eclipse 07

Estamos acabando. Falta agora uma última configuração. Vamos dar duplo clique sobre o servidor Tomcat que acabou de aparecer na View Servers. Uma tela de configuração irá aparecer.
Vamos alterar a configuração o “Server Locations” para “Use Tomcat installation (takes control of Tomcat installation)”. Essa configuração faz com que o Eclipse tenha o controle sobre o Tomcat, com isso, toda vez que precisarmos alterar alguma coisa no servidor, iremos fazer daqui mesmo. Depois de alterar, basta fechar e salvar.
Config Eclipse 08

E finalmente, vamos aos códigos!!! Uhull! o
Criemos um novo projeto no Eclipse. Vamos chamar esse projeto de Servlet. File > New > Other (Ctrl+N).
Projeto 01

Digite “Dynamic Web Project” para selecionar um projeto Web. (Lembro que ainda vou mostrar como fazer tudo isso sem precisar do Eclipse).
Projeto 02

Digite Servlet como nome do projeto e clique em Finish.
Projeto 03

O Eclipse vai perguntar se deseja mudar de perspectiva. Marque em não. Vamos nos acostumar com uma perspectiva, depois, podem tentar as outras à vontade.
Projeto 04

Vamos criar a página inicial. Um HTML mesmo de boas vindas. Botão direito sobre “WebContent > New > File”.
Projeto 05

Coloque o nome do arquivo de index.html e clique em “Finish”.
Projeto 06

Vamos editar o arquivo index.html, para isso, dê um duplo clique nele. Vou colocar apenas o código aqui.

<html>
    <body>
        <h1>Olá</h1>
    </body>
</html>

Criaremos agora um arquivo “web.xml” para acessarmos nossa página inicial. Para isso, com o botão direito, vamos clicar na pasta “WEB-INF > New > File” e vamos criar o arquivo. Se lembrem, esse arquivo fica na pasta “WEB-INF”!
Projeto 07

O arquivo web.xml tem como suas linhas iniciais várias configurações que são padronizadas. Você pode encontrar facilmente na internet, por isso vou apenas colocar aqui sem explicar o que significam.

<web-app id="WebApp_ID" version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>hello</servlet-name>
    <jsp-file>/index.html</jsp-file>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

Depois em um futuro artigo explicarei melhor sobre as tags do arquivo web.xml, por hora:

  • Para cada servlet (< servlet >) precisamos de um Mapeamento (< servlet-mapping >). O mapeamento é quem define o destino das urls digitadas no browser. O Servlet não precisa ser necessariamente uma classe Java. Note que estamos mapeando a url digitada e destinando para uma página HTML. Ou seja, mapping é para capturar o que é digitado na url e passar para o servlet.

Para executarmos nossa pequena aplicação basta clicar com botão direito no nosso projeto Servlet > Run As > Run on Server.
Projeto 08

Basta clicar em “Finish”.
Projeto 09

O Eclipse irá abrir um browser e irá mostrar a tela inicial. Caso seu Eclipse não abra esse browser, após o Tomcat estar ativo, basta digitar o seguinte endereço no seu browser predileto: http://localhost:8080/Servlet/hello . Após a tela inicial, clique no botão vermelho para parar o servidor, pois temos mais trabalho pela frente.
Projeto 10

Vamos alterar o index.html para que ele possa enviar valores, nosso servlet irá tratar esses valores, e enviar para uma próxima página. Os campos serão nome, valor1 e valor2. A pessoa irá digitar seu nome e dois valores a serem somados. Note que existem três tags: “form”, “action” e “method”. Form coloca todos os valores dentro do seu corpo, é como uma sacola ou uma mochila. Tudo que estiver dentro dele irá dentro da requisição. Method define qual o tipo de requisição vamos fazer, existem vários e por hora vamos usar o “post”. A Action define o destino, para onde iremos enviar a requisição.

<html>
    <body>
        <form action="/Servlet/calculemos" method="post">
            <h1>Olá</h1>
            Digite seu nome: <input type="text" name="nome"/> <br/><br/>
            Vamos as somas?<br/>
            Digite o primeiro valor a ser somado: <input type="text" name="valor1"/> <br/>
            Digite o segundo valor a ser somado: <input type="text" name="valor2"/> <br/><br/>
            <input type="submit" value="Calcule"/>
        </form>
    </body>
</html>

Vamos agora criar um Servlet (classe Java que irá tratar a requisição). No eclipse dentro da pasta src vamos criar um package e uma classe Java que “extenda” a classe HttpServlet. Essa classe irá receber os valores da nossa index.html, irá somar os números e encaminhar para uma jsp.
Projeto 11a

Projeto 11b

Projeto 12

Projeto 13

package com;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Servlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse res)    throws ServletException, IOException {
        int valor1;
        int valor2;
        int total = 0;
        String nome = (String) req.getParameter("nome");
        String aviso = "";
        try {
            // Eu sei que está feio, em um futuro poderemos refatorar e aplicar princípios de OO e Design 
            valor1 = Integer.parseInt((String) req.getParameter("valor1"));
        } catch (NumberFormatException e) {
            // Tratando para caso seja digitado um valor inválido 
            valor1 = 0;
            aviso = "Algum valor foi digitado incorretamente (em branco ou caractercs não numérimos), atribuímos 0";
        }
        
        try {
            // Eu sei que está feio, em um futuro poderemos refatorar e aplicar princípios de OO e Design 
            valor2 = Integer.parseInt((String) req.getParameter("valor2"));
        } catch (NumberFormatException e) {
            // Tratando para caso seja digitado um valor inválido
            valor2 = 0;
            aviso = "Algum valor foi digitado incorretamente (em branco ou caracters não numérimos), atribuímos 0";
        }
        // Colocando o nome digitado no request que será enviado ao cliente
        req.setAttribute("nome", nome);
        
        // Enviado o aviso ao cliente
        req.setAttribute("aviso", aviso);

        total = valor1 + valor2;
        
        // Atribuindo o valor da soma ao rquest que será enviado ao cliente
        req.setAttribute("total", total);
        
        // O Request Dispatcher determina o próximo caminho a seguir.
        // Vamos direcioná-lo para a JSP que iremos criar.
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/show.jsp");
        
        // Enviamos o processo para frente passando request e o response
        requestDispatcher.forward(req, res);
    }
}

Em nossa jsp iremos exibir o valor da soma e o nome enviado da página inicial. Nossa jsp irá ficar dentro da pasta WEB-INF. Atenção, dentro da pasta WEB-INF!
Projeto 14

Projeto 15

<%@page isELIgnored="false" %>
<html>
    <body>
        Obrigado pela visita ${nome}. <br/>
        O valor da some é: ${total}. <br/>
        
        <br/>${aviso}
    </body>
</html>

Quase acabando. Vamos alterar o arquivo web.xml para que ele possa receber a nova requisição. Lembra da tag “action=calculemos.do” no index.html? É agora que vamos mapeá-lo para que o Tomcat saiba direcioná-lo.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>  
    </welcome-file-list>
  
    <servlet>
        <servlet-name>hello</servlet-name>
        <jsp-file>/index.html</jsp-file>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>final</servlet-name>
        <servlet-class>com.Servlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>final</servlet-name>
        <url-pattern>/calculemos</url-pattern>
    </servlet-mapping> 
</web-app>

Agora basta iniciarmos o Tomcat e pronto (como fizemos da primeira vez para ver nossa primeira página), nosso servlet vai funcionar.

OBS.: Caso seu Tomcat mostre uma telinha com erro e acabe por não funcionar, vá em: Servers > Tomcat (pasta) > Server.xml. Após abrir o arquivo aperte F5. Execute o Tomcat novamente.
Projeto 16

Agora, para executar sem o Eclipse, é mais simples ainda. Vamos utilizar todos os arquivos criados aqui (que podem ser criados inclusive com um notepad). Primeiro, dentro da instalação do seu Tomcat, basta criar dentro da pasta wtpwebapps, a árvore de arquivos e pastas a serguir (dentro da pasta WEB-INF deve ficar igual na foto):
Projeto 17

Projeto 18

Dentro da pasta Servlet coloque o arquivo index.html. E dentro da pasta “/classes/com” ficará nossa classe Servlet.class. Nosso arquivo .class você poderá encontrar dentro do workspace que você configurou.

Agora, basta executar o Tomcat (como feito no início após instalarmos o Tomcat) e digitar no browser http://localhost:8080/Servlet/hello e boa navegação.

Sobre o SCWCD:

  • Todos os arquivos dentro da pasta WEB-INF estão protegidos. Tentem acessar nossa jsp: http://localhost:8080/Servlet/show.jsp Já no caso do index.html conseguimos este acesso pois o arquivo não encontra dentro da pasta WEB-INF http://localhost:8080/Servlet/index.html . Todos os arquivos que se encontram dentro da pasta WEB-INF estão protegidos de acesso direto. Grave isso! ;)
  • Vale a pena, sempre decorar um web.xml de exemplo (com todas as outras tags existentes), pois esse mapeamento cai na prova.

Espero que esse post possa lhe ser muito útil
Até a próxima.

Código Limpo – Parte 01

Já pensou no que as pessoas dizem sobre você após lerem seu código? Não me refiro apenas às pessoas das quais hoje você convive, imagine sobre a primeira empresa que você trabalhou, será que seu código é elogiado? Se seu companheiro de trabalho for ler e entender seu ultimo código, será que ele poderá ter um surto psicótico? O que você pensa, hoje, sobre a qualidade do código que deixaram para você alterar? Qual o nível de habilidade você daria para essa pessoa?

A pergunta que vai ecoar é: “Após analisarem nosso código, eles poderão nos indicar como referência para desenvolvimento?” (ouch!).

Para que isso aconteça, devemos adotar certas boas práticas e costumes enquanto estivermos fazendo nosso “if de cada dia”. Como esse conteúdo é extenso, vou dividi-lo em várias partes.

Como exemplo, iremos utilizar um sistema de consulta à informações das partidas de futebol. Eis um breve resumo: “O sistema Futebol Show tem por objetivo informar dados das partidas. O sistema deve conter: data/horário das partidas agendadas, local da partida, times que estarão jogando (e seus jogadores), trio de arbitragem. Ao final de cada jogo, o sistema retornará a quantidade de gols (total, e gol marcado por cada jogador), o resultado, soma dos cartões aplicados pelo juiz”.

1 – Classes

  • É aconselhável que as classes tenham nomes de substantivos. No nosso exemplo, poderíamos identificar: Partida, Estádio (local da partida), Time, Arbitragem, Jogadores. Isso lhe ajudará a pensar e entender o que está sendo feito, e para onde o sistema está caminhando. Dar-te-á uma melhor visão do contexto. Imagine se colocássemos Estádio como String na classe Partida. Se pedissem para adicionar mais tarde capacidade de pessoas, teríamos que criar mais um atributo em Partida, a classe partida começaria a perder sua Coesão, pois quem deve saber a capacidade de pessoa no estádio é o Estádio, não a Partida.
  • Nome das classes no singular. Se você acabasse de ler uma classe nomeada como Jogadores. O que vem a sua cabeça? Provavelmente, um conjunto de Jogadores. Bem óbvio, mas acreditem, já vi acontecer de encontrar nome de classes no plural. E ao questionar o porquê, não me disseram (ninguém sabia), sendo que a função da classe era de ser um objeto único mesmo. Nomeando corretamente sua classe, irá trazer mais clareza ao propósito da classe.

2 – Métodos

  • O nome dos métodos devem indicar um verbo. Após ler a ação no nome, já temos uma boa idéia do que ele irá realizar. Por exemplo:
    match.goal(value);

    O que esse código faz? O que ele retorna? Lá se vai um tempo para ter que entrar na classe, analisar o método… Imaginem se fosse escrito assim:

    match.getGoalsByPlayer(player);

    Ao ler o nome do método (com o verbo), já dá para ter uma noção do retorno, e inclusive, um provável comportamento do método.

  • É indicado que cada método mantenha um único objetivo. Imagine se você for chamar o método para buscar o total de pessoas presentes na partida:
    List presentAudience = match.getTotalPresentAudience();

    Mas ao executar o método, a seguinte mensagem é retornada:

    Exception in thread "main" main.DaoPublicException
      at main.DaoPublic.updateTotalProfitMatch(DaoPublic.java:6)
      at main.PresentAudience.getPresentAudience(PresentAudience.java:7)
      at main.match.getPresentAudience(match.java:7)
      at main.Principal.main(Principal.java:13)

    Espere, porque um método de atualizar renda da partida está sendo executado onde uma simples consulta deveria ser feita? Seu método tem que ser “Coeso”. Caso não haja outra opção, como última escolha, altere o nome do método para que o desenvolvedor que usar o método esteja ciente do que vai ocorrer. (Sei que o nome ficou feio, mas…).

    match.getPresentAudienceAndUpdateProfit();
  • Identação: “Deve ser a primeira regra do desenvolvedor”. O problema é que cada pessoa tem seu modo predileto, e às vezes não condiz com o padrão da empresa. Uma coisa é certa, não sei qual o padrão que você irá adotar, mas, por favor, sempre adote um. Abaixo dois códigos onde que, em sua leitura, fica clara a diferença de leitura:
            public int calculateScoredGoals()
        {int total = visitorTeam.getScoredTeam() +
    houseTeam.getScoredTeam();
                return total
            ;}
      public int calculateScoredGoals(){
        int total = visitorTeam.getScoredTeam() +
        houseTeam.getScoredTeam();
        return total;
      }

    Não importa qual a sua identação, apenas adote uma que facilite a leitura não só sua, mas de toda empresa.

  • Não devemos preservar referências retornadas por métodos que não terão utilizade depois. Vamos imaginar um método de atualização, que retorna a lista com os objetos que foram atualizados para caso queira utilizar:
      public void updateMatchDate() {
        //... Some code
        List expelledPlayers = DaoFactory.getDaoMatch().updatePlayers(expelledPlayers);
        //... More code, but none of them accessing expelledPlayers
      }

    Qual o motivo de ter criado a referência para a lista? Para que? Bastaria chamar o método e pronto. A lista será atualizada e você terá uma referência a um objeto alocado na memória que não será utilizado.

Esse foi o primeiro post sobre esse assunto, ainda falta muito pela frente!

Caso queria debater sobre essas idéias, podem postar que eu responderei. Gosto de aprender com a experiência de todos.

Clean Code – Part 01

Have you thought about what people think after they read your software code? I’m not only talking about people that you hang with in these days. Remeber the first company where you worked, will your code be praised? Whould the guy who works with you get a psychotic freak-out if he tries to read and understand the last code you wrote? What do you think, about the quality of the code that you are refactoring today? Which skills levels would you give to the creator of that code?

The question that remain: “After people read our code, would they have us as a reference for development?” (ouch!).

For this to happen, we should do some good practices and costumes while writing our “Daily If”. This subject is huge, so I have to split it.

As a start point, we will use a system that summarizes soccer matches. A little brief about it: “Soccer Show is a system whose objective is to summarize soccer matches. The system must have: date/hour of the scheduled matches, matches place of teams that will be playing (and the players), the result, the sum of the cards applied by the officials”.

1 – Classes

  • It’s a good choice to name the classes as nouns. At our sample system, we could identify: Match, Stadium (match place), Team, Officials and Players. This will help you to think and understand what’s going on. It will give you a better vision of the application context. Imagine if we had declared Stadium as a String at Match class. If later we were asked to add the Stadium capacity, we would create another attribute in Match, the class would start losing its “Cohesion”, who else should know the capacity of the people in the Stadium, but the Match.
  • Classes not in plural. Tell me what will pass through your mind after reading this class name: “Players”. A collective of players is a probably answer. It’s pretty obvious, but, I have seen this happening at some applications. When I asked why, no one told me the reason of that name (they did not know it). Naming your class correctly will bring more clearness to your class purpose.

2 – Methods

  • Methods name should indicate a verb. After we read the method name, we already can have an idea of what this method will do. By Sample:
    match.goal(value);

    What does this piece of code? What does it returns? Then you take some time getting in the class, opening the method to read the code… Imagine if the code was like this:

    match.getGoalsByPlayer(player);

    After reading the method name (with the verb), you already have an idea of its return object, even more, a possible method behavior.

  • It’s a good idea that each method contains only one behavior. Imagine if you invoke a method to get the total of present audience at the match:
    List presentAudience = match.getTotalPresentAudience();

    After you invoke the method you get this message:

    Exception in thread "main" main.DaoPublicException
      at main.DaoPublic.updateTotalProfitMatch(DaoPublic.java:6)
      at main.PresentAudience.getPresentAudience(PresentAudience.java:7)
      at main.match.getPresentAudience(match.java:7)
      at main.Principal.main(Principal.java:13)

    But, why a method that updates the matches profit is doing at this simple GET method? Your method must be “Cohesive”. Even, if there is no option, as last choice, change the methods name so the developer that will use the method will be aware of what might happen. (I know, its ugly, but…)

    match.getPresentAudienceAndUpdateProfit();
  • Indent: This is like “The First Developer Rule”. The problem is that each developer has its own preference, and sometimes it does not fit at the company indent pattern. One thing is for sure, I do not know which indent pattern you will adopt, but, please, take one. Right below we get two codes where it’s easy to see which one is easier to read:
            public int calculateScoredGoals()
        {int total = visitorTeam.getScoredTeam() +
    houseTeam.getScoredTeam();
                return total
            ;}
      public int calculateScoredGoals() {
        int total = visitorTeam.getScoredTeam() + houseTeam.getScoredTeam();
        return total;
      }

    It does not matter what kind of indent you will adopt, just chose one that makes the code reading easier not only for you, but for your entire company.

  • We should not keep returned attributes from methods if it will not be accessed later. Let’s imagine an update method which returns a list with the objects that were updated:
      public void updateMatchDate() {
        //... Some code
        List expelledPlayers = DaoFactory.getDaoMatch().updatePlayers(expelledPlayers);
        //... More code, but none of them accessing expelledPlayers
      }

    What’s the motive of creating the list? What for? Just invoke the method and it’s done. The list will be updated and you will not have an allocated object without reference.

This was the first post about this subject, much more are coming! Leave your opinions bellow so we might chat about it. I love to learn with other people experiences.

 

Diga, não pergunte!

Às vezes ao programar OO nos deparamos com situações das quais nos sentimos tentados sempre em colocar um valor em um atributo de modo mais rápido. Talvez o prazo para entrega do projeto esteja curto, ou então a alteração em questão é grande e não nos preocupanos com pequenos detalhes… Com isso é mais fácil deixar ser levado pelas circunstâncias do que analisar o que estamos fazendo.

Suponhamos que nós temos uma classe Porta e queremos saber se a ela está aberta ou não, e queremos mais, queremos mudar o estado dela de aberta para fechado e vice-versa. Um modo bem simples seria criar a classe e nela colocarmos um atributo booleano:

 public class Door {
     private boolean doorIsOpen = false;
}

Até aí tudo tranquilo, mas agora começa o perigo. Como iremos fazer com que essa variável tenha seu valor alterado? Devemos optar que essa alteração fosse realizada pela classe Porta? Ou pelo objeto que está chamando o objeto Porta? A solução mais comum que vemos por aí é fazer um get/set muito encontrado em códigos legados:

public void setDoorIsOpen(boolean doorIsOpen) {  
	this.doorIsOpen = doorIsOpen;  
}

public boolean getDoorIsOpen() {  
	return doorIsOpen;  
}  
// To close the Door  
if (door.getDoorIsOpen() == true)  
	door.setDoorIsOpen(false);  

// To open the Door
if (door.getDoorIsOpen() == false)  
	porta.setDoorIsOpen(true);

Pense comigo, e se, essa condição de pergunta (if + get) e o método set estivesse em 30 pontos do sistema e o cliente pedir uma nova regra de negócio. Imaginemos que, para ser fechada, a Porta tem que estar com o alarme ligado:

  public class Door {  
       private boolean doorIsOpen = false;  
       private boolean alarmIsActive = true;  
       public boolean getAlarmIsActive() {  
            return alarmIsActive;  
       }  
  }
  // To close the Door  
  if (door.doorIsOpen() && door.getAlarmIsActive ())  
       door.setDoorIsOpen(false);

Utilizando esse tipo de código, seria necessário ter que alterar todo os método do projeto que utilizassem esse código. Imagine todo o trabalho que teríamos para realizar essa alteração por todo o código…

Para não ter todo esse trabalho, basta dizer ao objeto Porta o que fazer, e não perguntar o estado do seu atributo para depois alterá-lo.

Utilizando esse conceito, alteração do código aconteceria apenas em um ponto e os outros 30 pontos do sistema continuariam intactos. O código inicial, antes da alteração solicitada pelo cliente (alarme ligado), ficaria assim:

  public class Door {  
      private boolean doorIsOpen = false;  
      private boolean alarmIsActive = true;  
      public boolean getAlarmIsActive() {  
           return alarmIsActive;  
      }  
      public boolean isOpen() {  
           return doorIsOpen;  
      }  
       public void closeDoor(){  
          doorIsOpen = false;  
       }  
       public void openDoor(){  
            doorIsOpen = true;  
       }  
  }

E o código para fechar/abrir a Porta seria bem mais simples:

  // Closes the Door
  if (door.isOpen())  
       door.closeDoor();  
  // Opens the Door
  if (!door.isOpen())  
       door.openDoor();

Após essa alteração, para aplicarmos o código novo (verificando o alarme), basta apenas colocar a condição do alarme dentro do método de fechar a Porta, e pronto, alteramos uma linha em uma classe todo o resto do sistema fica intocável:

  public void closeDoor(){  
       if (alarmIsActive)  
            doorIsClose = false;
  }

Agora, toda vez que a regra de negócio mudar (ex.: fechar a Porta), basta apenas alterar um método dentro da classe específica que o restante do projeto continuará intacto.

Utilizando esse princípio, diminuímos o acoplamento entre as classes e seu código está apto a ser utilizado em todas as partes do sistema.

Fica a dica.

Inspirado por: “The pragmatic Bookshelf – Alec Sharp”

Edit: Código final, dica do H.Fernandes. [=

Tell, don’t ask.

Sometimes when we are programming OO we are facing some situations when we are tempted to put a value into an attribute in the fastest way. It happens because we have to deliver the code soon, or because we are doing a big change and don’t have a lot of time to expend in little details. So, it’s easier to be dominated by circumstances than analysing what we are doing.

Suppose we have a Door class and we want to know when it’s open or not but we want more, we want to change its state when it’s open we might close it and vice-versa. An easy way it would be to create a class and put a boolean attribute:

 public class Door {  
     private boolean doorIsOpen = false;  
}

So far we are ok, but now we can feel some danger. How are we going to make this attribute change its value? Shall we choose to let this attribute changing be handled by the Door class or by the object that is calling this Door Object? The most usual solution we can see in the market: is to make a get/set as the first programmers did a lot:

public void setDoorIsOpen(boolean doorIsOpen) {  
	this.doorIsOpen = doorIsOpen;  
}

public boolean getDoorIsOpen() {  
	return doorIsOpen;  
}  

// To close the Door  
if (door.getDoorIsOpen() == true)  
	door.setDoorIsOpen(false);  

// To open the Door
if (door.getDoorIsOpen() == false)  
	porta.setDoorIsOpen(true); 

Think with me, what if, this condition of questioning (if + get) and the set attribute value were in more than 30 places of your project, and the customer asks for a new business rule. How should it look? How would it be coded? Let’s supose that, the user wants the door closed. The Doors Alarm must be active:

  public class Door {  
       private boolean doorIsOpen = false;  
       private boolean alarmIsActive = true;  
       public boolean getAlarmIsActive() {  
            return alarmIsActive;  
       }  
  }  
  // To close the Door  
  if (door.doorIsOpen() && door.getAlarmIsActive ())  
       door.setDoorIsOpen(false); 

With this type of code, it would be necessary to change all project method that is using this code. Imagine all the hard work to change this code overall project…

To avoid all this hard work, just tell the object Door what to do, do not ask its attribute state and then changing it.

By applying this concept, this code change would happen only in one part of the project and the other 30 places would remain the same. The start code before the new customer request (activated alarm), would be like this:

  public class Door {  
      private boolean doorIsOpen = false;  
      private boolean alarmIsActive = true;  
      public boolean getAlarmIsActive() {  
           return alarmIsActive;  
      }  
      public boolean isOpen() {  
           return doorIsOpen;  
      }  
       public void closeDoor(){  
          doorIsOpen = false;  
       }  
       public void openDoor(){  
            doorIsOpen = true;  
       }  
  }   

The code to close the Door it would be simpler:

  // Closes the Door
  if (door.isOpen())  
       door.closeDoor();  
  // Opens the Door
  if (!door.isOpen())  
       door.openDoor();   

After this refactoring we just have to put the alarm condition inside the method that closes the Door; changing one line in one class and all the rest of the project will remain the same:

  public void closeDoor(){  
       if (alarmIsActive)  
            doorIsClose = false;
  }   

Now, every time that the business rule changes (like close the Door), we just have to change the method of a specific class and, all the project classes, will be intact.

By this principle, we lose coupling between the classes, and your code is ready to be used by all your project.

It’s a good tip!

Inspired by: “The pragmatic Bookshelf – Alec Sharp”

Edit: Refactor at last code. Tip by H. Fernandes (at porguese post)