Aplicando desenvolvimento orientado a interfaces com Java

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (2)  (0)

Veja neste artigo como utilizar o modelo de desenvolvimento orientado a interfaces em Java, reduzindo o acoplamento entre os componentes e provendo um maior desempenho na aplicação.

INTRODUÇÃO

Neste artigo será apresentado um modelo de desenvolvimento de software mais utilizado pelas Fábricas de Software. O modelo consiste em desenvolver aplicações Java com menor acoplamento entre os componentes, provendo assim um maior desempenho na aplicação. Por Java ser uma linguagem OO (Orientada a Objetos) é preciso obedecer todas as restrições desse paradigma na hora de desenvolver uma aplicação, são eles:

  1. Encapsulamento
  2. Polimorfismo
  3. Herança

Em muitos casos é comum ler citações onde desenvolvedores mais experientes preferem o desenvolvimento de software voltado à interfaces ao invés de usar herança.

Ao modelar um software é preferível escolher Composição ao invés de herança.” (Aristofânio Garcia, (2013))

O encapsulamento aplica-se à forma de acesso aos atributos de um objeto. No caso da linguagem Java, encapsulamento pode ser definido através dos seguintes modificadores de acesso: private, protected, public ou default, cada um desses tipos de acessos acarretam em formas deferentes de encapsulamento do código, onde pode se ter:

  • Private: Membros marcados por esse modificador de acesso não podem ser acessados por outras classes da aplicação, porém a classe que contém a declaração do membro private tem acesso total aos mesmos.
  • Public: Membros marcados por esse modificador são acessíveis em qualquer lugar do código, por qualquer classe e de qualquer pacote.
  • Protectede Default: Apesar de serem bastante semelhantes, cada um tem sua particularidade. O modificador protected é utilizado para permitir acesso somente a classes do que estão no mesmo pacote, classes de pacotes diferentes não conseguem acessar diretamente os membros declarados com esse modificador de acesso. Já o modificador default permite acesso somente a classes do mesmo pacote, sendo assim, classes de pacotes diferentes não conseguem visualizar membros default.

Já o polimorfismo baseia-se na capacidade de ter várias formas de instanciar um objeto, pode-se dizer que ao ter sobrecarga do construtor de uma determinada classe já se faz possível trabalhar de forma polimórfica.

Interligando os conceitos de encapsulamento e polimorfismo, podemos encontrar o conceito de abstração, onde em linguagens orientada a objetos podemos utilizá-la a partir de um contrato, em outras palavras utilizando interfaces para prover comunicação entre diferentes partes da aplicação. Dessa forma é possível diminuir o acoplamento, aumentar a coesão e tornar o código mais legível e extensível.

PONDO EM PRÁTICA:

Após identificar e separar os módulos que farão parte do domínio da aplicação ficará mais fácil identificar os pontos onde farão conexão com o a visão da aplicação, domínio e o banco de dados.

Para melhorar a coesão do código, é uma ótima prática dividir classes em pacotes, de forma que se possa separar as responsabilidades.

Estruturando o projeto

Figura 1: Estruturando o projeto

No pacote br.com.example.domain serão colocadas as classes java beans, para trabalhar com banco de dados objeto relacional(ORM). Como no caso do JPA, é preciso que os objetos sejam serializados.

Listagem 1: Classes Bean

package br.com.example.domain;

import java.io.Serializable;

public class Person implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer code;
	private String name;
	private String cpf;
	private String rg;

	public Integer getCode() {
		return code;
	}

	public String getName() {
		return name;
	}

	public String getCpf() {
		return cpf;
	}

	public String getRg() {
		return rg;
	}

	public void setCode(Integer code) {
		this.code = code;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setCpf(String cpf) {
		this.cpf = cpf;
	}

	public void setRg(String rg) {
		this.rg = rg;
	}
	/*É importante adicionar os hashCode e Equals para melhorar
	a performance na hora de efetuar buscas no banco de dados*/
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((code == null) ? 0 : code.hashCode());
		result = prime * result + ((cpf == null) ? 0 : cpf.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((rg == null) ? 0 : rg.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (code == null) {
			if (other.code != null)
				return false;
		} else if (!code.equals(other.code))
			return false;
		if (cpf == null) {
			if (other.cpf != null)
				return false;
		} else if (!cpf.equals(other.cpf))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (rg == null) {
			if (other.rg != null)
				return false;
		} else if (!rg.equals(other.rg))
			return false;
		return true;
	}

}

Já no pacote br.com.example.application serão representadas as interfaces que representarão o domínio da aplicação, dessa forma é possível implementar códigos inerentes ao domínio do negócio, tornando-o independente de tipo de banco de dados, separando assim domínio da aplicação do banco de dados.

Listagem 2: Pacote Application

package br.com.example.application;

import br.com.example.domain.Person;

public interface PersonApplication {

	public void persist(Person person);
	public void update (Person person);
	public void delete(Person person);
	public Person findByCode(Integer code);
}

O pacote br.com.example.application.impl contém as classes que implementam as interfaces inerentes ao domínio da aplicação, sua função basicamente é realizar a conexão entre o banco de dados e a aplicação.

Listagem 3: Classes do application fazendo chamadas ao repositório através da interface

package br.com.example.application.impl;

import br.com.example.application.PersonApplication;
import br.com.example.domain.Person;
import br.com.example.repository.PersonRepository;

public class PersonApplicationImpl implements PersonApplication {

	private PersonRepository personInf;

	@Override
	public void persist(Person person) {
		personInf.persist(person);
	}

	@Override
	public void update(Person person) {
		personInf.update(person);
	}

	@Override
	public void delete(Person person) {
		personInf.delete(person);
	}

	@Override
	public Person findByCode(Integer code) {
		return personInf.findByCode(code);
	}

}

Seguindo essa mesma ideia, os pacotes br.com.example.repository e br.com.example.repository.impl contém as interfaces e as classes que as implementam formando a camada que estabelece a conexão com o banco de dados e efetua a lógica de acesso aos dados do banco.

Listagem 4: Interface Repository

package br.com.example.repository.impl;

import br.com.example.domain.Person;
import br.com.example.repository.PersonRepository;

public class PersonRepositoryImpl implements PersonRepository {

	@Override
	public void persist(Person person) {
		/*
		 * Aqui toda a lógica para salvar a entidade Person, independente de
		 * qual for o banco de dados!
		 */
	}

	@Override
	public void update(Person person) {
		// TODO Auto-generated method stub

	}

	@Override
	public void delete(Person person) {
		// TODO Auto-generated method stub

	}

	@Override
	public Person findByCode(Integer code) {
		// TODO Auto-generated method stub
		return null;
	}

}

CONCLUSÃO

Seguindo esse padrão, as aplicações tornam-se mais independentes e é possível alterar o banco de dados sem que haja necessidades de alterar o domínio de negócios. Em alguns casos podem ser necessárias alterações em toda a tecnologia aplicada à camada de, entretanto seguindo este padrão é possível alterar também a visão sem a necessidade de alterar o domínio do negócio, deixando o código expansível, coeso e menos acoplado.

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?