Eu trabalho desta maneira (Struts2 + Hibernate):
O My Struts Actions é responsável apenas por mostrar informações no navegador da web. Não estou pensando.
Usuário -> Ação -> Serviço -> Repositório -> Acesso a Dados
Ou:
Quero ver -> Como ver -> O que fazer -> Como obter -> Onde obter
Então, na primeira camada (a visualização), tenho algo como:
public String execute () {
try {
CourseService cs = new CourseService();
Course course = cs.getCourse(idCourse);
} catch (NotFoundException e) {
setMessageText("Course not found.");
} catch (Exception e) {
}
return "ok";
}
Como você vê, minha "visão" não pensa. Ele está solicitando um serviço (para gerenciar cursos), um curso específico. Esse serviço pode fazer muito mais, como relatórios, seraches e assim por diante. Os resultados são sempre uma lista ou um objeto específico (como o exemplo). Os serviços são a máquina real, aplicam regras e acessam o Repositório (para gerenciar os dados).
Portanto, se eu colocar meus Serviços, Repositórios e DAOS em diferentes bibliotecas, posso usá-lo mesmo em um programa baseado em texto ou em um sistema de desktop baseado em Windows sem alterar nada.
O serviço sabe o que fazer, mas não sabe como mostrar. A exibição sabe como mostrar, mas não sabe o que fazer. O mesmo acontece com Serviço / Repositório: O serviço envia e solicita os dados, mas não sabe onde os dados estão e como levá-los. O repositório "compõe" os dados brutos para objetos de negócios, para que o Serviço possa trabalhar.
Mas o Repositório não sabe nada sobre o banco de dados. O tipo de banco de dados (MySQL, PostgreSQL, ...) refere-se ao DAO.
Você pode alterar o DAO se desejar alterar o banco de dados e ele não deve afetar as camadas superiores. Você pode alterar o repositório se desejar atualizar seu gerenciamento de dados, mas isso não deve afetar o DAO e as camadas superiores. Você pode alterar os Serviços se quiser alterar sua lógica, mas isso não deve prejudicar as camadas acima nem abaixo.
E você pode alterar qualquer coisa à vista, mesmo a tecnologia (web, desktop, texto), mas isso não implica em contato com nada abaixo.
A lógica de negócios é serviço. Mas como interagir com isso é ver. Qual botão para mostrar agora? O usuário pode ver este link? Pense que seu sistema é um programa baseado em console: você deve negar se o usuário errado escolher #> myprogram -CourseService -option=getCourse -idCourse=234
ou parar com ele para pressionar as teclas para escrever este comando?
Conversando em sistemas baseados na Web (Struts + JavaEE) Eu tenho um pacote de controlador de GUI separado. Na exibição Ação, dou ao usuário logado e a classe me fornece os botões (ou qualquer elemento de interface que eu queira).
<div id="userDetailSubBox">
<c:forEach var="actionButton" items="${actionButtons}" varStatus="id">
${actionButton.buttonCode}
</c:forEach>
</div>
E
private List<ActionButton> actionButtons;
Lembre-se de manter isso fora dos serviços. Isso é coisa do VIEW. Mantenha-o nas ações do Struts. Todas as interações da interface devem ser totalmente separadas do código comercial real; portanto, se você portar o sistema, será fácil cortar o que não será mais necessário.