No mundo ideal, Usuário/Perfil/Grupo/Aplicação seriam as classes do domínio de uma aplicação de gerenciamento de usuários, possivelmente que operasse como o back-end para prover serviços de SSO através das aplicações existentes.
Se vc. se vê com classes deste tipo no modelo de domínio de uma aplicação em particular, é um sinal de alerta: será que isto deveria estar aí ?
Por outro lado, é provavelmente correto ter uma entidade que possua informações e/ou métodos de um “participante” de um processo de negócio.
IMO, a chave aí é ter a provisão para determinar quem é o participante de um processo de negócio vinculado a um usuário do sistema. Este mapeamento é um bom candidato a ficar isolado em um serviço definido por uma interface. A interface deve permitir associar um usuário ao identificador de participante e ao sistema. Quando houver necessidade de se implementar uma função de negócio que dependa de quem está fazendo a solicitação, utiliza-se outro método que, dado o usuário e o sistema, retorne o identificador de participante - e aí pode ser utilizado para determinar se a operação será executada ou não.
Por exemplo: Imagine um sistema de aprovação de despesas, com um caso de uso “aprovar despesa” onde especifica-se que a despesa só pode ser aprovada por um supervisor se o valor for menor do que a alçada definida para o mesmo. Caso contrário deve ser aprovada por um gerente.
“supervisor” e “gerente” podem ser mapeados por roles e determinados em tempo de execução via segurança declarativa e, portanto, não são problema. A questão no caso é determinar a alçada do usuário corrente. Esta é uma informação de negócio que pertence à aplicação de reembolso e, portanto, deve estar lá em algum lugar. É aí que entra o conceito de “participante”. Se vc. for pensar, ele é uma espécie de “proxy” do usuário da plataforma de execução dentro do seu sistema.
Voltando ao exemplo, o pseudo-código para o caso de uso de aprovação seria algo assim:
- Obtem o usuário de plataforma atual
- chama o serviço de mapeamento e obtem o identificador de participante
- obtem o participante utilizando o identificador
- obtem o valor da alçada
- se valor < alçada, prossegue. Caso contrário impede o acesso.