Primeiro, observe que fazer algo como entity.underlyingEntity.underlyingEntity.method()é considerado um cheiro de código de acordo com a Lei de Demeter . Dessa forma, você está expondo muitos detalhes de implementação ao consumidor. E cada necessidade de extensão ou modificação de um sistema desse tipo prejudicará muito.
Portanto, eu recomendo que você tenha um método HasRoleou IsAdminno Usercomentário de CodesInChaos. Dessa maneira, a maneira como as funções são implementadas no usuário permanece sendo o detalhe da implementação para o consumidor. E também parece mais natural perguntar ao usuário qual é o seu papel, em vez de perguntar sobre detalhes de seu papel e decidir com base nisso.
Evite também usar strings, a menos que seja necessário. nameé um bom exemplo de stringvariável porque o conteúdo é desconhecido de antemão. Por outro lado, algo como roleonde você tem dois valores distintos que são bem conhecidos no momento da compilação, é melhor usar uma digitação forte. É aí que o tipo de enumeração entra em jogo ...
Comparar
public bool HasRole(string role)
com
public enum Role { Admin, User }
public bool HasRole(Role role)
O segundo caso me dá muito mais idéia do que eu deveria estar passando. Também me impede de passar erroneamente um inválido string, caso eu não tenha idéia das constantes de sua função.
Em seguida, está a decisão sobre como será o papel. Você pode usar enum diretamente armazenado no usuário:
public enum Role
{
Admin,
User
}
public class User
{
private Role _role;
public bool HasRole(Role role)
{
return _role == role;
}
// or
public bool IsAdmin()
{
return _role == Role.Admin;
}
}
Por outro lado, se você deseja que seu papel tenha um comportamento próprio, ele definitivamente deve ocultar novamente os detalhes de como seu tipo está sendo decidido:
public enum RoleType
{
User,
Admin
}
public class Role
{
private RoleType _roleType;
public bool IsAdmin()
{
return _roleType == RoleType.Admin;
}
public bool IsUser()
{
return _roleType == RoleType.User;
}
// more role-specific logic...
}
public class User
{
private Role _role;
public bool IsAdmin()
{
return _role.IsAdmin();
}
public bool IsUser()
{
return _role.IsUser();
}
}
No entanto, isso é bastante detalhado e a complexidade aumentaria a cada adição de função - geralmente é assim que o código termina quando você tenta aderir totalmente à Lei de Demeter. Você deve melhorar o design, com base nos requisitos concretos do sistema que está sendo modelado.
De acordo com sua pergunta, acho melhor você ir com a primeira opção com enum diretamente User. Se você precisar de mais lógica Role, a segunda opção deve ser considerada como ponto de partida.
User.HasRole(Role.Admin).