Estrutura de uma aplicação MVC

Seguinte galera, depois de revirar vários tópicos (e presenciar muitas discussões que dão um né na cabeça), decidi fazer um exemplo de uma aplicação MVC, MAS me surgiram algumas dúvidas e incertezas. Estou mesmo fazendo certo?

Segue as classes:

Entidade:

package br.com.projeto.model.entity;

@Entity
@Table(name = "usuario")
public class Usuario implements java.io.Serializable {

	private static final long	serialVersionUID	= 1L;

	@Id
	@Column(name = "codigo", nullable = false)
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	private Long				codigo;

	@Column(name = "login", nullable = false)
	private String				login;

	@Column(name = "nome", nullable = false)
	private String				nome;

	@Column(name = "senha", nullable = false)
	private String				senha;

	@Column(name = "email", nullable = false)
	private String				email;

	@Column(name = "data_cadastro")
	@Temporal(TemporalType.TIMESTAMP)
	private Date				dataCadastro;

	@Column(name = "classificacao")
	@OneToOne
	@JoinColumn(name = "codigo")
	private Classificacao		classificacao;

	public Usuario() {}

	public Usuario(String login, String nome, String email, Classificacao classificacao) {
		setLogin(login);
		setNome(nome);
		setEmail(email);
		setDataCadastro(new Date());
		setClassificacao(classificacao);
	}

        //gets sets

Dao:

Classe abstrata:

package br.com.projeto.model.dao;

public abstract class AbstractDao<TEntity, PK> {

	protected static EntityManager			entityManager;
	
	public AbstractDao(EntityManager entityManager) {
		AbstractDao.entityManager = entityManager;
	}
	
	public void save(final TEntity entity) throws PersistenceException {
		try {
			entityManager.persist(entity);
		}
		catch(javax.persistence.PersistenceException pe) {
			throw new PersistenceException(pe.getMessage(), pe.getCause());
		}
	}

	public List<TEntity> list() throws PersistenceException {
		String jpql = TothenUtils.concat("select x from ", getEntityClass().getSimpleName(), " x");
		
		try {
			Query query = entityManager.createQuery(jpql);
			return query.getResultList();
		}
		catch(javax.persistence.PersistenceException pe) {
			throw new PersistenceException(pe.getMessage(), pe.getCause());
		}
	}

	public void delete(final TEntity entity) throws PersistenceException {
		try {
			entityManager.remove(entity);
		}
		catch(javax.persistence.PersistenceException pe) {
			throw new PersistenceException(pe.getMessage(), pe.getCause());
		}
	}

	public void update(final TEntity entity) throws PersistenceException {
		try {
			entityManager.merge(entity);
		}
		catch(javax.persistence.PersistenceException pe) {
			throw new PersistenceException(pe.getMessage(), pe.getCause());
		}
	}

	public TEntity read(final PK pk) throws PersistenceException {
		try {
			return (TEntity) entityManager.find(getEntityClass(), pk);
		}
		catch(javax.persistence.PersistenceException pe) {
			throw new PersistenceException(pe.getMessage(), pe.getCause());
		}
	}

	protected abstract Class<TEntity> getEntityClass();
}

UsuarioDao:

package br.com.projeto.model.dao;

public final class UsuarioDao extends AbstractDao<Usuario, Long> {

	public UsuarioDao(EntityManager entityManager) {
		super(entityManager);
	}

	@Override
	protected Class<Usuario> getEntityClass() {
		return Usuario.class;
	}
	
	public boolean exists(Usuario user) throws PersistenceException {
		final String jpql = Utils.concat("select count(*) from ", getEntityClass().getSimpleName());
		try {
			Query query = entityManager.createQuery(jpql);
			Integer qtde = (Integer) query.getSingleResult();
			return qtde > 0;
		}
		catch(javax.persistence.PersistenceException pe) {
			throw new PersistenceException(pe.getMessage(), pe.getCause());
		}
	}
}

Service (regras de negócio):

package br.com.projeto.model.service;

public class UsuarioService {

	private UsuarioDao dao;
	
	public UsuarioService(UsuarioDao dao) {
		setDao(dao);
	}
	
	public void add(Usuario user) throws ValidationException {
		try {
			if(!dao.exists(user)) {
				dao.save(user);
			}
			else
				throw new ValidationException("Usuário já existe!");
		}
		catch(PersistenceException pe) {
			pe.printStackTrace();
			//pagina de erro
		}
	}
	
	public void remove(Usuario user) throws ValidationException {
		try {
			if(!dao.exists(user))
				throw new ValidationException("Usuário não existe!");
			else
				dao.delete(user);
		}
		catch(PersistenceException pe) {
			pe.printStackTrace();
			//pagina de erro
		}
	}
	
	public void update(Usuario user) throws ValidationException {
		try {
			dao.update(user);
		}
		catch(PersistenceException pe) {
			pe.printStackTrace();
			//pagina de erro
		}
	}
	
	public void setDao(UsuarioDao dao) {
		this.dao = dao;
	}	
}

UsuarioController:

package br.com.projeto.controller;

public class UsuarioController {
	
	private UsuarioService service;
	
	public UsuarioController(UsuarioService service) {
		setService(service);
	}
	
	public void add(Usuario user) throws ValidationException {
		service.add(user);
	}
	
	public void remove(Usuario user) throws ValidationException {
		service.remove(user);
	}
	
	public void update(Usuario user) throws ValidationException {
		service.update(user);
	}
	
	public void setService(UsuarioService service) {
		this.service = service;
	}
}

Bom, o fluxo que eu imagino seria o seguinte:
Requisição do usuário na View -> Controller -> Service -> Dao

Bom, aceito sugestões e me digam, por favor, se estou no caminho certo, ou que posso mudar.

PS: Até dicas sobre excessões são bem-vindas.

Grato, j0nny

Opinião pessoal: Não!

Use a própria classe de entidade como repositório para a lógica associada a ela, essa é a responsabilidade dela afinal.
Não use DAOs. São velhos e trabalhosos, só vão te atrasar. Para isolar a lógica de persistência use NamedQueries são
mais simples e econômicas em linhas de código.
Por fim, dispense a classe Service. Esse é mais um velho padrão J2EE. O seu controle faz quase nada, na verdade ele
se parece mais com um arquivo de configuração conectando elementos da view com ações do Service. Evite classes com
tão pouca responsabilidade, muito código (e tempo) e pouco (ou nenhum) ganho. Ao invés disso, coloque o código do Service
diretamente nos métodos do seu Controller.

Só mais uma coisa. Use Scala, vai te poupar um montão de linhas de código.

Mas eu posso estar errado!

[quote=dev.rafael]Opinião pessoal: Não!

Use a própria classe de entidade como repositório para a lógica associada a ela, essa é a responsabilidade dela afinal.
Não use DAOs. São velhos e trabalhosos, só vão te atrasar. Para isolar a lógica de persistência use NamedQueries são
mais simples e econômicas em linhas de código.
Por fim, dispense a classe Service. Esse é mais um velho padrão J2EE. O seu controle faz quase nada, na verdade ele
se parece mais com um arquivo de configuração conectando elementos da view com ações do Service. Evite classes com
tão pouca responsabilidade, muito código (e tempo) e pouco (ou nenhum) ganho. Ao invés disso, coloque o código do Service
diretamente nos métodos do seu Controller.

Mas eu posso estar errado![/quote]

Não entendi a parte dos Dao’s… :oops:

Lógica nos controller’s, pensei tbm, mas pelo tópicos que acompanhei, isso não é uma boa prática.

Os DAOs servem apenas para separar a lógica de acesso ao banco da lógica da aplicação. Ou seja, ao invés de fazer assim:

// Controller
public class UserController {

  private final EntityManager em;

  public List<User> getUsers(String name) {
    return em.createQuery("select u from User u where lower(u.name) like lower(:name)", User.class)
              .setParameter("name", "%" + name + "%").getResultList();
  }

}

vc faz assim:

// DAO
public class UserDAO {

  private final EntityManager em;

  public List<User> findUsers(String login) {
    return em.createQuery("select u from User u where lower(u.name) like lower(:name)", User.class)
              .setParameter("name", "%" + name + "%").getResultList();    
  }

}

// Controller
public class UserController {

  private final UserDAO userDAO;

  public List<User> getUsers(String name) {
    return userDAO.findUsers(name);
  }
}

Isso é legal. Mas compare com isso:

// Controller
public class UserController {

  private final EntityManager em;

  public List<User> getUsers(String name) {
    return em.createNamedQuery(User.ALL).setParameter("%" + name + "%").getResultList();
  }
}

// e na sua entidade
@Entity
@NamedQueries({
  @NamedQuery(User.ALL, query = "select u from User u where lower(u.name) like (:name)", resultClass=User.class)
})
public class User implements Serializable {

  public static final String ALL = "User.all";

O custo de se escrever uma NamedQuery é bem menor que o de um DAO. E com elas o seu EntityManager faz o papel de
um DAO genérico. Poupe o seu esforço para a lógica da aplicação não p/ infraestrutura. Quem devia pensar nisso é o framework.

“Boa Prática” é um termo que um monte de programador/arquiteto antiquado usa p/ te fazer programar mais p/ chegar no
mesmo lugar. Case vc consiga encontrar uma justificativa real p/ não colocar a lógica dos casos de uso no controle, então faça isso.
Caso contrário, vc só vai estar programando mais p/ a felicidade de quem inventou essas “boas práticas”. Seja pragmático.
Poupe o seu esforço para a lógica da aplicação não p/ infraestrutura. Quem devia pensar nisso é o framework.

[quote=dev.rafael]Os DAOs servem apenas para separar a lógica de acesso ao banco da lógica da aplicação. Ou seja, ao invés de fazer assim:

// Controller
public class UserController {

  private final EntityManager em;

  public List<User> getUsers(String name) {
    return em.createQuery("select u from User u where lower(u.name) like lower(:name)", User.class)
              .setParameter("name", "%" + name + "%").getResultList();
  }

}

vc faz assim:

// DAO
public class UserDAO {

  private final EntityManager em;

  public List<User> findUsers(String login) {
    return em.createQuery("select u from User u where lower(u.name) like lower(:name)", User.class)
              .setParameter("name", "%" + name + "%").getResultList();    
  }

}

// Controller
public class UserController {

  private final UserDAO userDAO;

  public List<User> getUsers(String name) {
    return userDAO.findUsers(name);
  }
}

Isso é legal. Mas compare com isso:

// Controller
public class UserController {

  private final EntityManager em;

  public List<User> getUsers(String name) {
    return em.createNamedQuery(User.ALL).setParameter("%" + name + "%").getResultList();
  }
}

// e na sua entidade
@Entity
@NamedQueries({
  @NamedQuery(User.ALL, query = "select u from User u where lower(u.name) like (:name)", resultClass=User.class)
})
public class User implements Serializable {

  public static final String ALL = "User.all";

O custo de se escrever uma NamedQuery é bem menor que o de um DAO. E com elas o seu EntityManager faz o papel de
um DAO genérico. Poupe o seu esforço para a lógica da aplicação não p/ infraestrutura. Quem devia pensar nisso é o framework.

“Boa Prática” é um termo que um monte de programador/arquiteto antiquado usa p/ te fazer programar mais p/ chegar no
mesmo lugar. Case vc consiga encontrar uma justificativa real p/ não colocar a lógica dos casos de uso no controle, então faça isso.
Caso contrário, vc só vai estar programando mais p/ a felicidade de quem inventou essas “boas práticas”. Seja pragmático.
Poupe o seu esforço para a lógica da aplicação não p/ infraestrutura. Quem devia pensar nisso é o framework.[/quote]

Não concordo com sua abordagem dos DAO’s. Minha aplicação ficaria muito acoplada, e repare no meu Dao abstrato e no UsuarioDao, vc acha mesmo que tenho trabalho?
Quanto ao controller, pensei em deixar a lógica neles, mas quero ver como o pessoal faz e suas vantagens/desvantagens.

Eu discordo do nosso colega dev.rafael.

Use sim Dao e Service e não coloque nenhuma lógica nas Entidades.

Dao serve para criar as consultas a banco e criar os métodos save, update e delete.

Service serve para as regras de negócio. Se vc precisar criar alguma coisa diferente antes de salvar por exemplo, deve ser feito no service, é pra isso que ele serve.

Controller serve para se comunicar com a interface visual, tudo que vai e vem dela, deve passar pelo controller, e qualquer regra que não tenha a ver com a parte visual, deverá então ser feita no service. No controller vc deve apenas fazer o acesso aos métodos do service e não criar um service dentro do controller.

Veja bem, se vc criar regras de negócio na entidade, não poderá aproveitar essa classe em outras aplicações, pq podem ter regras lá que não se apliquem.
Vc criou um Dao genérico, perfeito, poderia ir até além, criar um service genérico e extender esse service nos seus Services, assim, não precisaria fazer coisas do tipo: private UsuarioDao dao. Teria um método para isso herdado.

Acho que a estrutura que vc montou está muito boa.

Veja isso:

// Save no DAO
public class UserDAO {

  private final EntityManager em;

  public void save(User) {
    em.persist(user);
  }

}

public class UserService {

  private final UserDAO dao;

  public void save(User user) {
    userDAO.save(user);
  }

}

public class UserController {

  private final UserService userService;

  public void save(User user) {
    userService.save(user);
  }

}

Agora vejam isso:

public class UserController {

  private final EntityManager em;

  public void save(User user) {
    em.persist(user);
  }

}

Agora me digam e o uso de DAOs e Services não viola o principio DRY (Don’t Repeat Yourself). DAOs e services eram uma
necessidade no J2EE mas com o JEE5 e JEE6 eles agora não passam de redundância (salvo certos casos bem específicos).
Vide o livro Real World Java EE Patterns - Rethinking Best Practices do Adam Bien.

Além disso, basta ver como os frameworks modernos como o Rails evitam esses padrões de projeto ultrapassados.

No seu livro Begining Scala, Dave Pollack (criador do Lift) diz que quem
deve ser preocupar com a infraestrutura da aplicação é o programador de frameworks. O consumidor de frameworks deve
apenas se preocupar com a lógica da aplicação. Se vc está preocupado com DAO e Services, é pq o seu framework faz pouco
por vc.

[quote=romarcio]Eu discordo do nosso colega dev.rafael.

Use sim Dao e Service e não coloque nenhuma lógica nas Entidades.

Dao serve para criar as consultas a banco e criar os métodos save, update e delete.

Service serve para as regras de negócio. Se vc precisar criar alguma coisa diferente antes de salvar por exemplo, deve ser feito no service, é pra isso que ele serve.

Controller serve para se comunicar com a interface visual, tudo que vai e vem dela, deve passar pelo controller, e qualquer regra que não tenha a ver com a parte visual, deverá então ser feita no service. No controller vc deve apenas fazer o acesso aos métodos do service e não criar um service dentro do controller.

Veja bem, se vc criar regras de negócio na entidade, não poderá aproveitar essa classe em outras aplicações, pq podem ter regras lá que não se apliquem.
Vc criou um Dao genérico, perfeito, poderia ir até além, criar um service genérico e extender esse service nos seus Services, assim, não precisaria fazer coisas do tipo: private UsuarioDao dao. Teria um método para isso herdado.

Acho que a estrutura que vc montou está muito boa.
[/quote]

Vlw pelas dicas, mas vc citou algo que fiquei confuso…

Mas como faria isso?

[quote]

Vlw pelas dicas, mas vc citou algo que fiquei confuso…

No controller vc deve apenas fazer o acesso aos métodos do service e não criar um service dentro do controller.

Mas como faria isso?[/quote]

Faz apenas o acesso, como vc fez, cira o atributo private UsuarioService usuarioService e acessa os métodos do service a partir dele.

A idéia de criar service ou dao não tem nada haver com MVC. Design Patterns devem ser explorados dentro de um contexto e aplicados conforme. Ess negócio de ficar falando use isso ou use aquilo, é meramente ilusório.

Um service caíria muito bem numa aplicação trhee-tier. Enquanto que o DAO é um pattern que existe há decádas pq a linguagem não dá suporte fácil a operaçoes com o banco de dados. Se você escrever um ÚNICO dao usando genercis, não vai precisar ficar criando DAOs e nem acomplando o Entity Manager ao seu controller, o que eu desaconselho fortemente.

Em linguagens como o Scala e o Ruby on Rails, vocẽ não escreve mais DAOs, visto que a comunicação com o banco de dados é feita via meta dados, dinâmicamente.

Pois trata-se exatamente dos casos mais simples, aqueles que dominam as maior parte das aplicações. É certo que existem
situações em que DAOs e Services são necessários. Mas essa não é uma delas. Termos como “acoplamento” são abstratos.
Eu conheço um monte de gente que sabe usar esse termo desde os primeiros anos de faculdade mas quantos sabem realmente
mensurar o “acoplamento” em valores concretos de tempo, esforço e custo?

Vejam q não estou dizendo “Nunca usem DAOs e Services”, estou dizendo p/ não usarem p/ uma aplicação simples. Nem DAOs,
nem Services fazem parte do padrão MVC, eles foram adicionados no J2EE pq a tecnologia não oferecia boas ferramentas para
solucionar certos problemas. Esses padrões certamente podem ser usados hoje com o JEE6. Mas os problemas p/ os quais
eles são orientados já possuem soluções melhores presentes do próprio JEE. Não está codificando errado, está codificando mais.
Codificando mais vc perde mais tempo, aumenta o custo do seu sistema e se torna menos competitivo. E não ganha absolutamente
nada por isso já adicionar uma camada a mais de abstração apenas aumenta a quantidade de código boilerplate.

Eu simplesmente não consigo ver uma razão p/ criar um DAO genérico em uma aplicação orientada a banco de dados posto que
o EntityManager é um DAO genérico. Com JPA, DAO genérico é reescrever o que já está feito, é redundância.

Em Ruby on Rails não se usa DAO mas se usa uma camada de abstração para a lógica de acesso ao banco. A unica diferença é
que em Rails essa camada fica dentro das classes de Entidade e não em uma classe DAO a parte.

E na minha classe Service, caso ocorra uma exceção, como vou tratar isso? (na parte onde coloquei o comentário).
Pq no service, eu não tenho ‘acesso’ à view, certo?

No seu caso? Vc vai precisar propagar a exeção e escrever um outro bloco try/catch no seu controller para q
esse possa tratar a exeção da maneira correta.

[quote=dev.rafael]No seu caso? Vc vai precisar propagar a exeção e escrever um outro bloco try/catch no seu controller para q
esse possa tratar a exeção da maneira correta.[/quote]

Hmm, ok.

[quote=dev.rafael]eles foram adicionados no J2EE pq a tecnologia não oferecia boas ferramentas para
solucionar certos problemas.[/quote]

Olha só, os design patterns da Sun que compõe o Blue Print, são patterns catalogados pela Sun para uma aplicação JEE. Talvez ALGUNS destes patterns seja remendos a alguns problemas que surgiram como é o caso do DTO.

Agora service e dao não são remendos, por favor.

[quote=dev.rafael]Esses padrões certamente podem ser usados hoje com o JEE6. Mas os problemas p/ os quais
eles são orientados já possuem soluções melhores presentes do próprio JEE[/quote]

Então qual é a solução que o JEE deu para o J2EE que substitui o service ?

Será que com isso não ganhamos em flexibilidade, manutenção, escalabilidade, segurança ??? Afinal de um service eu posso derivar a chamada de N lugares. Agora se ficar tudo no controller ??? Lembrando que cada controller atende somente a um tipo de entrada, não se usa o mesmo controller para entrdas diferentes. Esta tua idéia de deixar as regras no controller é absurda.

Isto chama-se Decorator

“In object-oriented programming, the decorator pattern is a design pattern that allows new/additional behaviour to be added to an existing object dynamically.”

Wow!! Vai com calma cara! Eu nem chinguei a sua mãe e vc já me vem descer o nível.

Agora, voltando a discução séria…
É o seguinte, o padrão Service pode ser bem mais flexível q colocar a sua lógica no controller, mas isso só se a sua aplicação tem
múltiplos fontends, mas esse aspecto não foi comentado pelo J0nny de modo que estou tratando essa como uma aplicação
web simples. Na arquitetura vc deve procurar os padrões q melhor se encaixam às suas necessidades e não busca justificativas
genéricas para usar qualquer coisa no teu projeto.

Vc usa um Service se vc tiver múltiplos frontends e esses diferentes frontends acessam as mesmas funcionalidades do sistema.
Então vc tem uma boa justificativa p/ isolar essa lógica dos seus controllers já q assim vc evita a duplicação desse código e melhora
a mantenibilidade do sistema. Outra razão boa p/ usar Services é quando vc tem um cliente remoto como uma aplicação Swing
acessando EJBs em um servidor JEE. Pq nesse caso chamadas de granularidade muito fina podem impactar negativamente a
performance do seu sistema.

Agora como a maioria dos sistemas possuem um único frontend, e geralmente um frontend WEB, não tem pq vc criar controllers tão
magros. Eles acabam virando um tipo de arquivo de configuração q diz ao sistema qual método de qual service deve ser chamado
quando uma determinada requisição chega. Isso é algo q poderia facilmente ser descrito através de um arquivo XML com muito menos
esforço. Vc ainda pode me dizer q usando o padrão Service de qualquer modo tornaria a sua aplicação mais flexível caso no futuro
vc precisasse criar um novo frontend p/ essa aplicação e vc estaria certo. Porém quantas vezes vc já viu isso acontecer na prática.
Quantas vezes vc desenvolveu uma aplicação WEB e tempos depois o seu cliente requeriu a adição de um outro frontend p/ as mesmas
funcionalidades. Vc pode escrever Services se quizer mas, como eu já disse, vc vai escrever mais código, perder mais tempo e gastar
mais dinheiro e se tornar menos competitivo p/ o mercado.

Com relação ao decorator, na boa, ou vc não sabe inglês eu vc simplesmente não entendeu o q o cara escreveu.

In object-oriented programming, the decorator pattern is a design pattern that allows new/additional behaviour to be added to an
existing object dynamically.

A chave está em “new/adicional behavior”. Como encapsular um DAO genérico (EntityManager) em um outro DAO genérico pode ser um
Decorator se vc não está adicionando nenhum comportamento a este? Como vc está criando um decorator se vc está mudando a interface
da classe decorada?

Eu discordo da sua abordagem Rafael.

Acredito que os controladores devem trabalhar com o fluxo da aplicação, não devem implementar lógica alguma de negócio a lógica nos controladores deveria estar relacionada a navegação mesmo nas aplicações web mais simples.

Segundo o exemplo do Jonny percebe-se que ele pretende utilizar diversos controladores definidos de acordo com as funcionalidades e cada funcionalidade da visão poderia levar a ele uma ou mais telas diferentes, não vejo o porque de acoplar isso com as regras de negócio já que ele mesmo criou uma camada de modelo com os Services.

Outro ponto: se estamos falando de uma aplicação onde os Controllers são Servlets adicionar dependências na camada de modelo torna o código muito mais fácil de testar e evoluir.

Jonny,
Se você pretende ter um grau de acoplamento menor eu sugeriria seguir um fluxo parecido com esse:

View --> Controller --> InterfaceService —> ServiceImplementation --> Dao.

Hoje em dia, no Brasil, eu vejo muitos aplicativos overengeneered. Camadas e mais camadas de abstração são adicionadas p/ solucionar problemas de acoplamento q
os frameworks modernos já solucionaram. Os argumentos q tenho dado são todos tirados do livro de boas práticas no desenvolvimento JEE do Adam Bien. Agora eu
gostaria vcs me darem justificativas reais e não teóricas do uso de tantas camadas de código. Eu gostaria de saber quanto tempo, custo ou quantas pessoas vc polpa
usando Services e DAOs. Quantas linhas de código são polpadas e quanto tempo em manutenção. Pq dizer q o código fica mais organizado e tudo qualquer um faz!

O problema é que o exemplo dado é muito “magro” pra se fazer uma analise do que deve e do que nao deve ser usado. Nao ha regra nenhuma pra ser avaliada.

Eu concordo em partes com o Rafael e discordo em outras.

Concordo plenamente quando ele diz que algo so deve ser usado quando nós sabemos porque estamos usando e nao só porque lemos em algum blog que assim é mais bonitinho.

Discordo quando ele fala dos DAOs e que o acesso aos dados devem ficar no controller. Acho isso ruim. Até faria sentido em operacoes simples em que voce simplesmente faz um entityManager.persist(objeto), mas qualquer coisa adicional que precise ser feita, como a criacao de um criteria por exemplo, ja pede pra que saia do controller. Um DAO ou Repositorio é o melhor lugar pra isso, em Java. Sem duvida e sem trauma.
Ainda que seja uma simples delegacao, ja vale so pela legibilidade do codigo. O que é mais agradavel de se ver num controller (ou em qualquer lugar)? em.persist(usuario), ou repositorio.guardar(usuario)?

Concordo tambem quando ele diz que o Service é dispensavel NESSE CASO. Esse é um exemplo muito simples para que haja um service envolvido. Aproveitando pra fazer uma colocação sobre um comentario na primeira pagina, do romarcio

Este nao eh um bom conselho definitivamente, na minha opiniao. Os services nao servem para implementar regras de negocio, essa eh uma visao da arquitetura BO/VO renomeada. Os services servem para “orquestrar” o que vai ser feito pelas entidades, quando houver alteracao de estado em mais de uma delas. Um exemplo classico é o estoque, um service jamais vai verificar se ha ou nao quantidade suficiente, ele vai apenas consultar o estoque, que vai dizer a ele se ha ou nao, ele vai fazer isso porque nao é responsabilidade da Venda fazer, assim como nao é responsabilidade do produto calcular o imposto desta venda. Sao todos passos necessarios dentro de um processo, mas cada um deles feito por uma entidade com sua logica especifica, a qual o service nao conhece. Ele apenas coordena, chamando os metodos da entidades que executam a logica, na ordem que for necessario, pra garantir que tudo saia de acordo.

A ideia de que as entidades nao devem conter logica eh ruim e a possibel reusabilidade em outro sistema nao diminui isso. Digamos que um usuario queira alterar sua senha. De acordo com a visao neo BO/VO, o service implementaria essa regra, verificaria se a senha atual foi digitada corretamente, usario um usuario.setSenha(12345) para passar a senha nova para a entidade e salvaria. Otimo, sem problema algum.

Mas num outro dia, eu dando manutencao no sistema, com uma regra qualquer, vejo lá, belo e formoso o tal do setSenha(String senha). Nao penso duas vezes, senha nova e salvar. E dai? Tenho entao uma inconsistencia no meu sistema.

Ja se eu tivesse o metodo modificarSenha(senhaAtual, senhaNova) na minha classe usuario,eu nao correria esse risco porque só haveria uma maneira de informar uma nova senha, e antes seria validada a senha atual. O metodo setSenha nao existiria.

Rafael,

No caso não usei o nome service para me relacionar ao padrão Service do JEE.

Considerei aqui serviço como uma classe do Modelo que deveria possuir comportamentos referentes ao domínio da aplicação.
Se o Jonny quer seguir o MVC acredito que ele deve separar as lógicas de Controle do Modelo da aplicação.

Para mim só o fato de poder-se testar o modelo sem se preocupar com o controle de fluxo da aplicação já compensa o esforço.