Convenções de código em Java

Todo bom Desenvolvedor/Programador/Estudante deve saber:

http://www.oracle.com/technetwork/java/codeconvtoc-136057.html

Você sabe a versão do seu software???

Hoje eu li um post que me lembrou algumas duvidas que eu tinha, e que ja tinham sido esclarecidas mas que eu não lembrava como :D . O post é do Bruno Carvalho e fala sobre padronização do versionamento de software, duvida que com certeza já pairou na cabeça de estudantes e mesmo desenvolvedores.
O texto é muito bom é fala da Semantic Versioning, ou Versionamento Semântico em português.
Segue o link do texto.

Boa leitura!!

Blog em java com JSF 2.0, JPA 2.0 e CDI(Weld)

Muito tempo sem postas nada (Nossa lá se vão oito messes :D ), alguns projetos na cabeça, muita coisa na faculdade, emprego novo :P , mas cá estou novamente, e dessa vez vamos definitivamente movimentar esse blog.

Bom nesse artigo eu vou tentar demostrar de forma clara e objetiva a criação de uma aplicação em java. Para isso vamos utilizar alguns frameworks mais utilizados no momento como JSF, JPA, CDI(WELd) e abordando aguns padrões e técnicas.

Desde já vou informando que tudo que apresentarei é fruto de muita pesquisa, estudo e dedicação, mas contudo erros podem ocorrer pois por mais de saibamos determinado assunto, sempre existirá algo a aprender.

Esse artigo não será muito avançado, contudo coisas muito básicas não serão abordadas, porém para que o leitor com menos conhecimento possa acompanhar, darei dicas de artigos e livros ao longo do texto. So let’s go.

O Problema

Nosso objetivo será a criação de uma aplicação web, mas precisamente um blog, “há mais um blog!”, sim pois acredito que seja de facil entendimento para todos. Abaixo temos o diagrama de classes do projeto, é bem simples, serve apenas para visualizarmos o problema:

O que iremos fazer é bem simples, apartir do nosso modelo de classe criaremos nossos objetos, e depois através de uma peculiariedade da JPA (http://www.oracle.com/technetwork/java/javaee/persistence-jsp-136066.html), nossas tabelas serão criadas automaticamente. “Mas eu aprendi na faculdade a criar as tabelas primeiro”, “O que, não criaremos nosso banco de dados primeiro?? E a normalização das tabelas???, “Todas as empresas que trabalhei criavamos o Bd primeiro!!!”. Sim, sim isso são coisas que aconteciam, quer dizer acontecem :D , mas este paradigma esta mudando muito nos ultimos tempos.

O que ocorre é que estamos trabalhando com orientação a objetos, então não faz nenhum sentido eu criar o meu bd primeiro. Graças ao Hibernate (www.hibernate.org) isto é possivel, este framework foi o primeiro a ter a opção da criação das tabelas apartir do modelo, a JPA seguindo o hibernate, tambem dispõe desta opção.

O termo mais proximo disso que estamos fazendo é o que a Microsoft chama de “Model First”! Não existe no mundo Java nenhum nome que remeta a isso!

Notem que nossos objetos Post, Coment e Category possuem um campo “id”, este campo será a identificação única de nossos objetos em sua respectivas tabelas, e é obrigatório que exista, contudo não necessariamente é obrigatório que seja do tipo Integer como foi colocado no exemplo, poderia ser por exemlo um tipo String.

O Ambiente de Desenvolvimento

Eu vou utilizar o Netbeans (www.netbeans.org) nos exemplos, porém o leitor poderá usar a IDE que desejar, inclusive um editor de texto comun :D (Não recomentdado).

Então no Netbeans vamos criar um novo projeto web.



Colocamos o nome do projeto e escolhemos o local para salvar.

Escolhemos o caminho do contexto, que por padrão leva o nome do projeto, mas é possível altera-lo.

Lembrando de escolher o framework “JavaServer Faces” e em Bibliotecas escolhemos JSF 2.0. Mas na aba Configuração, mudaremos o campo “Padrão de Url” de “/faces/*” para “*.jsf”. E deixamos o idioma padrão como facelets.

Mais sobre JSF 2.0:

- http://www.edsongoncalves.com.br/tag/jsf-2-0/
- http://blog.gilliard.eti.br/category/jsf/
- http://www.rponte.com.br/category/jsf/

Nossa classes do Modelo

As classes do Modelo, são as classes representam nosso negócio, ou seja nosso post, comentários e categorias. Essas classes são as classes deverão ser persistidas. Para realizar a persistencia utilizando a JPA deveremos utilizar algumas anotações referentes a JPA.

Segue as classes de nossas entidades já com as anotações do JPA:

Post.java

package com.web.blog.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import static javax.persistence.CascadeType.ALL;
import static javax.persistence.FetchType.LAZY;

@Entity
@Table(name="posts")
public class Post implements Serializable {

private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "title")
    private String title;

    @Column(name = "text")
    private String text;

    @OneToMany(mappedBy = "post", cascade=(ALL), fetch=LAZY)
    private List<Coment> coments = new ArrayList<Coment>();

    @ManyToMany(mappedBy = "posts", cascade=(ALL), fetch=LAZY)
    private List<Category> categories = new ArrayList<Category>();

    public Post() {
    }

    public Post(String title, String text) {
        this.title = title;
        this.text = text;
    }

    //Alguns getters e setters suprimidos

    public void addComent(Coment c){
        coments.add(c);
        c.setPost(this);
    }

    public List<Coment> getComents() {
        return coments;
    }

    public List<Category> getCategories() {
        return categories;
    }

    public void addCategory(Category category){
        categories.add(category);
        category.addPost(this);
    }
}

Coment.java

package com.web.blog.entities;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="coments")
public class Coment implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @ManyToOne
    @JoinColumn(name="post")
    private Post post;

    private String owner;
    private String text;

    public Coment() {
    }

    public Coment(String owner, String text) {
        this.owner = owner;
        this.text = text;
    }

    //Getters e setters suprimidos

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }
}

Category.java

package com.web.blog.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="categories")
public class Category implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    private String name;

    @ManyToMany
    private List<Post> posts = new ArrayList<Post>();

    public List<Post> getPosts() {
        return posts;
    }

    public void addPost(Post post){
        posts.add(post);
    }

    //Getters e setters suprimidos
}

Mais sobre JPA 2.0:

- http://www.edsongoncalves.com.br/category/jpa-2-0/

As Dependências

Precisamos adicionar ao nosso projeto a lib do Postgre, que será o banco de dados que nós usaremos, e no caso voce ter optado em usar o Toncat ou outro servidor no lugar do Glassfish, precisaremos tambem adicionar as lib’s do JPA, nesse caso a biblioteca a ser importada sera a EclipseLink(JPA 2.0) que é a implementação padrão do JPA.

Criando nossa camada de persistencia

Começaremos criando nosso banco de dados no Postgre, assim acesse o Postgre e crie um novo banco de dados chamado blog.

Agora precisamos criar nosso arquivo persistence.xml. No Netbeans isso é muito facil, basta ir em Arquivo>Novo arquivo, e depois na janela que abrir no campos categorias escolher “Persistence” e em tipo de arquivos escolher “Unidade de Persistencia”. Na proxima tela, coloque o nome “blogPU” e lembre-se de escolher EclipseLink(JPA 2.0) como provedor de persistencia, em fonte de dados deixe em branco, deixe marcado o campo “Utilizar apis de transação java”, e escolha “criar” como a estrategia de geração de tabelas.

Ao finalizar o Netbeans abre uma janela contendo a unidade de persistencia criada, então va na aba XML, para podermos fazer algumas modificações.

Nosso arquivo de persistencia devera ficar assim:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
 <persistence-unit name="blogPU" transaction-type="RESOURCE_LOCAL">
 <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
 <exclude-unlisted-classes>false</exclude-unlisted-classes>
 <properties>
 <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/blog"/>
 <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
 <property name="javax.persistence.jdbc.user" value="postgres"/>
 <property name="javax.persistence.jdbc.password" value="senha"/>
 <property name="eclipselink.ddl-generation" value="create-tables"/>
 </properties>
 </persistence-unit>
</persistence>

Precisamos de um objeto para persistir e recuperar nossos Posts e Comentários, esse objeto será nosso repositório de posts e de comentários. O nome Repositório foi inspirado no padrão Repository de Martin Fowler, contudo não é uma implementação fiel do padrão. A questão aqui foi que o leitor venha a ter uma noção do padrão, e como este se encaixa no software :D .

O Repositório é um lugar no seu sistema onde você pode armazenar seus objetos, para depois recuperá-los mediante algum critério. Repositórios são simples, fazem parte do domínio do problema, e servem para abstrair a ideia de persistência. Em um modelo de domínio perfeito, este não deve se preocupar com persistência, na verdade o domínio não conhece o conceito de persistência, para o domínio/sistema, os objetos devem estar disponíveis sempre que solicitados, como se estivessem guardados em algum lugar da memória da máquina. Mas no mundo real, sabemos que isso é impossível, isso é uma inferência tecnológica, a tecnologia que temos hoje não nos deixa fazer isso, por isso precisamos persistir nossos objetos/dados. Como disse, repositórios são simples, contudo  a forma como podem ser implementados é que pode ser complexa, pois podemos querer abstrair os critérios de pesquisa, e o própio mecanismo de persistência.

Mais sobre o padrão Repository:

- http://martinfowler.com/eaaCatalog/repository.html
- http://blog.fragmental.com.br/2007/06/05/dao-e-repository/

PostRepository.java

package com.web.blog.persistence;

import com.web.blog.entities.Post;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;

public class PostRepository {

    EntityManager em;

    public PostRepository(){

    }

    public PostRepository(EntityManager em){
        this.em = em;
    }

    public List<Post> getAll() {
        Query query = em.createQuery("Select p from Post p");
        List<Post> result = (List<Post>) query.getResultList();
        return result;
    }

    public Post getPostByTitle(String title) {
        Query query = em.createQuery("Select p from Post p where p.title = :title");
        query.setParameter("title", title);
        return (Post) query.getResultList().get(0);
    }

    public void addPost(Post post) {
        em.getTransaction().begin();
        em.persist(post);
        em.getTransaction().commit();
    }

    public void updatePost(Post post) {
        em.getTransaction().begin();
        em.merge(post);
        em.flush();
        em.getTransaction().commit();
    }
}

Notem que nosso EntityManager não é instanciado, e que não temos EntityManagerFactory, nem EntityTransaction na nossa classe, isso porque faremos uso de Injeção de Dependencias e Inversão de Controle, o que nos favoreceria muito se estivessemos utilizando TDD por exemplo.

Não vou colocar o codigo do repositorio de categorias pois o mesmo é igual ao do posts, mudando apenas a entidade. Fica como lição de casa :D .

Testando

Para testarmos se isso tudo realmente funciona, usaremos a seguinte classe que é bem simples:

import com.web.blog.persistence.PostRepository;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class testeJPA {

    public static void main(String[] args) {

        Category jsf = new Category();
        jsf.setName("jsf");

        Post post = new Post("Primeiro Post", "Esse é o primeiro post");
        Coment coment = new Coment("Alan", "primeiro comentario");
        post.addComent(coment);
        post.addCategory(jsf);

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("blogPU");
        EntityManager em = emf.createEntityManager();

        PostRepository repository = new PostRepository(em);

        repository.addPost(post);

        for(Post p : repository.getAll()){
            System.out.println("postTitle: " + p.getTitle());
            System.out.println("postText: " + p.getText());

            for(Coment c : p.getComents()){
                System.out.println("...comentOwner: " + c.getOwner());
                System.out.println("...comentText: " + c.getText());
            }
        }
    }
}

Nossa saida do console deverá ser a seguinte:

postTitle: Primeiro Post
postText: Esse é o primeiro post
...comentOwner: Alan
...comentText: primeiro comentario

Continua :D ….


Como matar um Dragão

Se você precisasse criar um programa de computador, daqueles tipo de MATRIZ (Viagem rsss), que matasse dragões, qual linguagem de programação você utilizaria? Aqui vão algumas sugestões:

Java
Chega, encontra o dragão. Desenvolve um framework para aniquilamento de dragões em múltiplas camadas. Escreve vários artigos sobre o framework, mas não mata o dragão.

.NET
Chega, olha a idéia do Javanês e a copia, tenta matar o dragão, mas é comido pelo réptil.

ASP
Os componentes necessários para levantar a espada são proprietários e caros. Outros tantos componentes proprietários para achar a localização do dragão, e mais outros tantos a localização da princesa. Chama então seu amigo programador de PHP.

C
Chega, olha para o dragão com olhar de desprezo, puxa seu canivete, degola o dragão. Encontra a princesa, mas a ignora para ver os últimos checkins no cvs do kernel do linux.

C++
Cria um canivete básico e vai juntando funcionalidades até ter uma espada complexa que apenas ele consegue entender. Mata o dragão, mas trava no meio da ponte por causa dos memory leaks.

COBOL
Chega, olha o dragão, pensa que tá velho demais para conseguir matar um bicho daquele tamanho e pegar a princesa e, então, vai embora de volta ao seu mundinho.

Pascal
Se prepara durante 10 anos para criar um sistema de aniquilamento de dragão. Chegando lá, descobre que o programa só aceita lagartixas como entrada.

VB
Monta uma arma de destruição de dragões a partir de vários componentes, parte pro pau pra cima do dragão e, na hora H, descobre que a espada só funciona durante noites chuvosas.

PL/SQL
Coleta dados de outros matadores de dragão, cria tabelas com N relacionamentos de complexidade ternária, dados em 3 dimensões, OLAP, demora 15 anos para processar a informação. Enquanto isso a princesa virou lésbica.

PHP
Pesquisa bancos de scripts e acha as classes de construção de espada, manuseio da espada, localização da princesa e dragão. Remenda tudo e coloca umas firúlas próprias. Mata o dragão e casa com a princesa. Como tudo foi feito com gambiarras, o dragão um dia vai ressuscitar e comer os dois.

Ruby
Chega com uma puta fama, falando que é o melhor faz tudo, quando vai enfrentar o dragão mostra um videozinho dele matando um dragão. O dragão come ele de tédio.

Assembly
Acha que está fazendo o mais certo e enxuto, porém troca um A por D, mata a princesa e transa com o dragão.

Shell
O cara chega no dragão com um script de 2 linhas que mata, corta, stripa, pica em pedacinhos e empalha o bicho, mas na hora que ele roda, o script aumenta, engorda, enfurece e coloca álcool no fogo do dragão.

Fortran
Chega desenvolve uma solução com 45000 linhas de código, mata o dragão vai ao encontro da princesa, mas esta o chama de tiuzinho e sai correndo atrás do programador java que era elegante e ficou rico.

Fox Pro
Desenvolve um sis tema para matar o dragão, por fora é bonitinho e funciona, mas por dentro está tudo remendado. Quando ele vai executar o aniquilador de dragões lembra que esqueceu de indexar os DBF’s.

Clipper
Monta uma rotina que carrega um array de codeblocks para insultar o dragão, cantar a princesa, carregar a espada para memória, moer o dragão, limpar a sujeira, lascar leite condensado com morangos na princesa gostosa, transar com a princesa, tomar banho, ligar o carro, colocar gasolina e voltar pra casa. Na hora de rodar recebe um “Bound Error: Array Access” e o dragão come ele com farinha.

Analista de Processos
Chega ao dragão com duas toneladas de documentação desenvolvida sobre o processo de se matar um dragão genérico, desenvolve um fluxograma super complexo para libertar a princesa e se casar com ela, convence o dragão que aquilo vai ser bom pra ele e que não será doloroso. Ao executar o processo ele estima o esforço e o tamanho do estrago que isso vai causar, consegue o aval do papa, do Buda e do Raul Seixas para o plano, e então compra 2 bombas nucleares, 45 canhões, 1 porta aviões, contrata 300 homens armados até os dentes, quando na verdade necessitaria apenas da espada que estava na sua mão o tempo todo.

Hello world!

Eu fiz esse blog pra compartilhar com todos minhas experiencias… rsss (Aiai tá mais pra tropeços rss)… com todos, espero que gostem!!!

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.