Bom dia, Bruno! Tudo bem?
Na Clean Architecture, é uma prática comum criar um use case para cada ação significativa do sistema. Isso ajuda a manter o sistema modularizado e facilita a manutenção e testabilidade. Por exemplo, se você tem um sistema de gerenciamento de usuários, você poderia ter use cases separados para "Adicionar Usuário", "Remover Usuário", "Atualizar Usuário", etc.
Quanto à criação de interfaces para cada use case, essa é uma prática recomendada. As interfaces definem um contrato que deve ser seguido pelas implementações, o que ajuda a desacoplar o código. Isso significa que as mudanças em uma parte do sistema não afetam outras partes que dependem apenas da interface. Além disso, usar interfaces facilita a substituição das implementações, se necessário, e é essencial para a injeção de dependências.
Sobre a injeção de dependências, você está correto ao dizer que injetar diretamente a implementação não é uma boa prática segundo os princípios SOLID, especialmente o princípio da inversão de dependência.
Esse princípio sugere que módulos de alto nível não devem depender de módulos de baixo nível, mas ambos devem depender de abstrações (interfaces, neste caso). Portanto, ao invés de injetar a implementação, você deveria injetar a interface no controller. Isso torna seu código mais flexível e testável.
Aqui está um exemplo simplificado de como você poderia organizar isso em Java:
// Interface do use case
public interface AdicionarUsuarioUseCase {
void adicionarUsuario(Usuario usuario);
}
// Implementação do use case
public class AdicionarUsuarioUseCaseImpl implements AdicionarUsuarioUseCase {
private final UsuarioRepository usuarioRepository;
public AdicionarUsuarioUseCaseImpl(UsuarioRepository usuarioRepository) {
this.usuarioRepository = usuarioRepository;
}
@Override
public void adicionarUsuario(Usuario usuario) {
usuarioRepository.save(usuario);
}
}
// Controller
public class UsuarioController {
private final AdicionarUsuarioUseCase adicionarUsuarioUseCase;
public UsuarioController(AdicionarUsuarioUseCase adicionarUsuarioUseCase) {
this.adicionarUsuarioUseCase = adicionarUsuarioUseCase;
}
public void adicionarUsuario(Usuario usuario) {
adicionarUsuarioUseCase.adicionarUsuario(usuario);
}
}
Neste exemplo, o UsuarioController
depende apenas da interface AdicionarUsuarioUseCase
, não da implementação. Isso permite que você mude a implementação do use case sem alterar o controller.
Espero que essa explicação tenha esclarecido suas dúvidas e boa sorte nos estudos!
Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.