Service e ServiceImpl, pra que e por que programar assim?[RESOLVIDO]

vejo os projetos são feitos dessa forma, por exemplo, clienteService e ClienteService Impl, e o ClienteService Impl usa um outro serviço que também tem sua implementação, por exemplo o DAO, por que programar assim?

1 curtida

Boa tarde xxmayconxx, (Service) seria uma (Interface) que nada mais é do que um contrato, ou seja uma regra que obriga a classe que irá implementar essa interface a usar os metodos definidos nela, ou seja (Service) tem um conjunto de metodos definidos, mais não implementados e a (ServiceImpl) implementa a interface (Service) ou seja a (ServiceImpl) é obrigatória a implementar todos os metodos definidos na interface (Service), mais ae vem outra questão, qual a finalidade disso? a principal finalidade na minha opnião é desacoplar as camadas ou seja, no sistema em si você usará a Interface sem se preocupar como a mesma é implementada, isso fica mais claro quando tratamos da DAO, por exemplo, podemos ter varias implementações da Interface DAO, uma usando JDBC puro e outra usando JPA ou Hibernate, como elas seriam implementadas para a Interface não interessa, desde de que a Interface receba a implementação da mesma, podendo assim trocar facilmente a forma de como a persistencia ocorra sem realizar alterações na própria (Service) pois a mesma estará usando s Interface DAO, segue um exemplo abaixo:

Interface

package financeiro.lancamento;

import java.util.Date;
import java.util.List;

import financeiro.conta.Conta;

public interface ILancamentoDAO {

	public void salvar(Lancamento lancamento);
	public void excluir(Lancamento lancamento);
	public Lancamento carregar(Integer lancamento);
	public List<Lancamento> listar(Conta conta, Date dataInicio, Date dataFim);
	public float saldo(Conta conta, Date data);
}

Implementação Interface

package financeiro.lancamento;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import financeiro.conta.Conta;

public class LancamentoDAOHibernate implements ILancamentoDAO{

	private Session session;
	
	public void setSession(Session session) {
		this.session = session;
	}

	@Override
	public void salvar(Lancamento lancamento) {
		this.session.saveOrUpdate(lancamento);
	}

	@Override
	public void excluir(Lancamento lancamento) {
		this.session.delete(lancamento);
	}

	@Override
	public Lancamento carregar(Integer lancamento) {
		return (Lancamento) this.session.get(Lancamento.class, lancamento);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Lancamento> listar(Conta conta, Date dataInicio, Date dataFim) {
		Criteria criteria = this.session.createCriteria(Lancamento.class);
		
		if(dataInicio != null && dataFim != null){
			criteria.add(Restrictions.between("data", dataInicio, dataFim));
		}else if(dataInicio != null){
			criteria.add(Restrictions.ge("data", dataInicio));
		}else if(dataFim != null){
			criteria.add(Restrictions.le("data", dataFim));
		}
		
		criteria.add(Restrictions.eq("conta", conta));
		criteria.addOrder(Order.asc("data"));
		return criteria.list();
	}

	@Override
	public float saldo(Conta conta, Date data) {
		StringBuffer sql = new StringBuffer();
		sql.append("select sum(l.valor * c.fator)");
		sql.append("from LANCAMENTO l,");
		sql.append(" CATEGORIA c");
		sql.append("where l.categoria = c.codigo");
		sql.append(" and l.conta = :conta");
		sql.append(" and l.data <= :data");
		SQLQuery query = this.session.createSQLQuery(sql.toString());
		query.setParameter("conta", conta.getCodigoConta());
		query.setParameter("data", data);
		BigDecimal saldo = (BigDecimal) query.uniqueResult();
		if(saldo != null){
			return saldo.floatValue();
		}
		return 0f;
	}
}

uso na camada de regra de negocio

package financeiro.lancamento;

import java.util.Date;
import java.util.List;

import financeiro.conta.Conta;
import financeiro.util.DAOFactory;

public class LancamentoRN {

         /* Aqui está a flexibilidade pois não declaro a classe LancamentoDAOHibernate e sim a interface ILancamentoDAO, usando    todos os metodos dela sem se preocupar como os mesmos são implementados*/
	private ILancamentoDAO iLancamentoDAO;
	
        // e no construtor da classe retorno uma implementação da interface ILancamentoDAO, não importando qual seja ela Hibernate, JDBC ou JPA
	public LancamentoRN(){
		this.iLancamentoDAO = DAOFactory.criarLancamentoDAO(); 
	}
	
	public void salvar(Lancamento lancamento){
		this.iLancamentoDAO.salvar(lancamento);
	}
	
	public void excluir(Lancamento lancamento){
		this.iLancamentoDAO.excluir(lancamento);
	}
	
	public Lancamento carregar(Integer lancamento){
		return this.iLancamentoDAO.carregar(lancamento);
	}
	
	public float saldo(Conta conta, Date data){
		float saldoInicial = conta.getSaldoInicial();
		float saldoNaData = this.iLancamentoDAO.saldo(conta, data);
		return saldoInicial + saldoNaData;
	}
	
	public List<Lancamento> listar(Conta conta, Date dataInicio, Date dataFim){
		return this.iLancamentoDAO.listar(conta, dataInicio, dataFim);
	}
}

espero ter ajudado t+

[quote=RafaelCassau]Boa tarde xxmayconxx, (Service) seria uma (Interface) que nada mais é do que um contrato, ou seja uma regra que obriga a classe que irá implementar essa interface a usar os metodos definidos nela, ou seja (Service) tem um conjunto de metodos definidos, mais não implementados e a (ServiceImpl) implementa a interface (Service) ou seja a (ServiceImpl) é obrigatória a implementar todos os metodos definidos na interface (Service), mais ae vem outra questão, qual a finalidade disso? a principal finalidade na minha opnião é desacoplar as camadas ou seja, no sistema em si você usará a Interface sem se preocupar como a mesma é implementada, isso fica mais claro quando tratamos da DAO, por exemplo, podemos ter varias implementações da Interface DAO, uma usando JDBC puro e outra usando JPA ou Hibernate, como elas seriam implementadas para a Interface não interessa, desde de que a Interface receba a implementação da mesma, podendo assim trocar facilmente a forma de como a persistencia ocorra sem realizar alterações na própria (Service) pois a mesma estará usando s Interface DAO, segue um exemplo abaixo:

Interface

package financeiro.lancamento;

import java.util.Date;
import java.util.List;

import financeiro.conta.Conta;

public interface ILancamentoDAO {

	public void salvar(Lancamento lancamento);
	public void excluir(Lancamento lancamento);
	public Lancamento carregar(Integer lancamento);
	public List<Lancamento> listar(Conta conta, Date dataInicio, Date dataFim);
	public float saldo(Conta conta, Date data);
}

Implementação Interface

package financeiro.lancamento;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import financeiro.conta.Conta;

public class LancamentoDAOHibernate implements ILancamentoDAO{

	private Session session;
	
	public void setSession(Session session) {
		this.session = session;
	}

	@Override
	public void salvar(Lancamento lancamento) {
		this.session.saveOrUpdate(lancamento);
	}

	@Override
	public void excluir(Lancamento lancamento) {
		this.session.delete(lancamento);
	}

	@Override
	public Lancamento carregar(Integer lancamento) {
		return (Lancamento) this.session.get(Lancamento.class, lancamento);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Lancamento> listar(Conta conta, Date dataInicio, Date dataFim) {
		Criteria criteria = this.session.createCriteria(Lancamento.class);
		
		if(dataInicio != null && dataFim != null){
			criteria.add(Restrictions.between("data", dataInicio, dataFim));
		}else if(dataInicio != null){
			criteria.add(Restrictions.ge("data", dataInicio));
		}else if(dataFim != null){
			criteria.add(Restrictions.le("data", dataFim));
		}
		
		criteria.add(Restrictions.eq("conta", conta));
		criteria.addOrder(Order.asc("data"));
		return criteria.list();
	}

	@Override
	public float saldo(Conta conta, Date data) {
		StringBuffer sql = new StringBuffer();
		sql.append("select sum(l.valor * c.fator)");
		sql.append("from LANCAMENTO l,");
		sql.append(" CATEGORIA c");
		sql.append("where l.categoria = c.codigo");
		sql.append(" and l.conta = :conta");
		sql.append(" and l.data <= :data");
		SQLQuery query = this.session.createSQLQuery(sql.toString());
		query.setParameter("conta", conta.getCodigoConta());
		query.setParameter("data", data);
		BigDecimal saldo = (BigDecimal) query.uniqueResult();
		if(saldo != null){
			return saldo.floatValue();
		}
		return 0f;
	}
}

uso na camada de regra de negocio

package financeiro.lancamento;

import java.util.Date;
import java.util.List;

import financeiro.conta.Conta;
import financeiro.util.DAOFactory;

public class LancamentoRN {

         /* Aqui está a flexibilidade pois não declaro a classe LancamentoDAOHibernate e sim a interface ILancamentoDAO, usando    todos os metodos dela sem se preocupar como os mesmos são implementados*/
	private ILancamentoDAO iLancamentoDAO;
	
        // e no construtor da classe retorno uma implementação da interface ILancamentoDAO, não importando qual seja ela Hibernate, JDBC ou JPA
	public LancamentoRN(){
		this.iLancamentoDAO = DAOFactory.criarLancamentoDAO(); 
	}
	
	public void salvar(Lancamento lancamento){
		this.iLancamentoDAO.salvar(lancamento);
	}
	
	public void excluir(Lancamento lancamento){
		this.iLancamentoDAO.excluir(lancamento);
	}
	
	public Lancamento carregar(Integer lancamento){
		return this.iLancamentoDAO.carregar(lancamento);
	}
	
	public float saldo(Conta conta, Date data){
		float saldoInicial = conta.getSaldoInicial();
		float saldoNaData = this.iLancamentoDAO.saldo(conta, data);
		return saldoInicial + saldoNaData;
	}
	
	public List<Lancamento> listar(Conta conta, Date dataInicio, Date dataFim){
		return this.iLancamentoDAO.listar(conta, dataInicio, dataFim);
	}
}

espero ter ajudado t+[/quote]

Ou seja, ou seja, ou seja, ou seja…

Camarada, o uso de interfaces no java visa atender à uma característica da POO que é o polimorfismo. Você possui uma estrutura básica que poderá ser implementada de N maneiras. Como exemplo, a interface List do java.util que pode implementar ArrayList, por exemplo.
Além disso, caso você esteja utilizando um framework de IoC, como o Spring, precisará manter uma estrutura condizente com a injeção dos objetos, necessárias para o framework.

Certo acho que entendi, obrigado.

valeu amigo, caso não tenha mais duvida por favor edite o titulo do post para [RESOLVIDO], t+