Vivendo e Aprendendo

Experiência prática na administração de Banco de Dados

Indo um pouco além ...

by Gilberto C. Andrade on 23 março 2009

Tagged as: Java,

Estou aprendendo um pouco sobre programação orientada a objeto em java e com o pouco que li resolvi implementar uma pequena api que abstrai as regras de acesso e recuperação de dados - acesso a banco de dados. Gosto muito dessa (OrBroker) api de persistência com isso elaborei um contrato que acho o mínimo necessário para o acesso a dados, o qual poderá utilizar a api OrBroker - espero não somente essa api, mas outras (desacoplamento).

IService: Interface (contrato) geral para uso com o mescanimo de persistência OrBroker. Estabelece assinaturas de métodos essenciais para operações de acesso a banco de dados.

Assinaturas:

public interface IService<T, PK extends Serializable> {
    /**
     * Expõe o mecanismo de persistência. .
     */
    public Broker getBroker();

    public Class<T> getClassEntity();

    /**
     * Método genérico usado para obter todas as entidades de uma classe
     * particular. Essa classe particular é definida no construtor da
     * implementação desta interface.
     *
     * @return Collection de entidades preenchidas
     */
    public Collection<T> getAll();

    /**
     * Método genérico para obter uma entidade.
     *
     * @param entity
     *                objeto ao qual se aplica o retorno da pesquisa.
     * @return true e o preenchimento da entidade passada como parâmetro. false
     *         caso contrário.
     */
    public boolean find(T entity);

    /**
     * Método genérico para inserção de uma nova entidade.
     *
     * @param entity
     *                entidade a ser inserida.
     * @throws InsertException
     */
    public void insert(T entity) throws InsertException;

    /**
     * Método genérico para atualização de uma entidade.
     *
     * @param entity
     *                entidade a ser alterada.
     */
    public void update(T entity);

    /**
     * Método genérico para deleção de uma entidade.
     *
     * @param entity
     *                entidade a ser deletada.
     */
    public void delete(T entity);

    /**
     * Método genérico para consulta nomeada preexistente.
     *
     * @param queryName
     *                nome da consulta.
     */
    public Collection<T> findByNamedQuery(String queryName);

    /**
     * Método genérico para personalizada com a cláusula SQL LIKE.
     *
     * @param likeColumn
     *                campo a ser usado na cláusula SQL.
     * @param likeValue
     *                valor para pesquisa.
     */
    public Collection<T> findLike(String likeColumn, String likeValue);
}

Vocês podem notar o uso do inglês para nomear classes, metodos e até atributos. Acho isso um vício ou uma maneira de reduzir os nomes, pois em português ficam enormes. Outra coisa, alguns podem comentar que o nome certo seria sufixar ou prefixar tal interface com o termo DAO, para expressar um padrão de projeto muito conhecido e utilizado para, também, abstrair essas atividades de banco de dados. Acontece que essa minha pequena implementação não exigirá tamanha desacoplagem e acho também que um programa que grava e ler dados, não faz somente isso, faz isso e um pouco mais - regras de negócio.

Assim, optei por, inicialmente, colocar as assinaturas necessárias ao acesso a dados e deixar para uma outra interface acrescentar as assinaturas de contrato específicas:

public interface ICategoriaService extends IService<Categoria, Integer> {
    /**
     * Busca por chave primária.
     * @param primaryKey
     * @return a instância da entidade encontrada ou null se a entidade não existe
     * @throws IllegalArgumentException se o primeiro argumento é nulo
     */
    public Categoria find(Integer primaryKey);
}

Na implementação ocorre um fato interessante quando a entidade sendo trabalhada não exigir contratos além dos já fornecidos. Notei essa característica quando da implementação dos métodos por uma classe a ser utilizada como base de implementação, ou seja, as classes mais específicas - a exemplo da ICategoriaService - herdarão dessa classe base e implementarão seus contratos específicos.

Um exemplo de uso dessa classe base:

public class CategoriaBaseServiceTest {
    private BaseService<Categoria, Integer> cS = new BaseService<Categoria, Integer>(
	    Categoria.class, Constants.ORBROKER_INVENTARIO);

    @Test
    public void testGetAll() {
	Collection<Categoria> result = cS.getAll();
	System.out.println(result);
	assertFalse(result.isEmpty());
    }
}

Então ficou da seguinte maneira essa pequena api:

Interface	     Implementação
IService ----------> BaseService
|                        |
|                        |
ICategoriaService -> CategoriaService
comments powered by Disqus