Innanzitutto, tieni presente che fare qualcosa come entity.underlyingEntity.underlyingEntity.method()
è considerato un odore di codice in base alla Legge di Demetra . In questo modo, stai esponendo molti dettagli di implementazione al consumatore. E ogni esigenza di estensione o modifica di un tale sistema farà molto male.
Pertanto, ti consigliamo di utilizzare un metodo HasRole
o IsAdmin
sul User
come nel commento di CodesInChaos. In questo modo, il modo in cui i ruoli vengono implementati sull'utente rimane il dettaglio dell'implementazione per il consumatore. Ed è anche più naturale chiedere all'utente quale sia il suo ruolo, invece di chiedergli dettagli sul suo ruolo e poi decidere in base a questo.
Evita anche di usare string
s a meno che non sia necessario. name
è un buon esempio di string
variabile perché i contenuti sono sconosciuti in anticipo. D'altra parte, qualcosa come role
in cui si hanno due valori distinti che sono ben noti al momento della compilazione, è meglio usare una digitazione strong. È qui che entra in gioco il tipo di enumerazione ...
Confronto
public bool HasRole(string role)
con
public enum Role { Admin, User }
public bool HasRole(Role role)
Il secondo caso mi dà un'idea molto più ampia di quello che dovrei passare. Inoltre, mi impedisce di passare erroneamente un string
non valido nel caso in cui non avessi idea delle costanti di ruolo.
La prossima è la decisione su come apparirà il ruolo. Puoi utilizzare enum direttamente memorizzato sull'utente:
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;
}
}
D'altra parte, se vuoi che il tuo ruolo abbia un comportamento in sé, dovrebbe sicuramente nascondere di nuovo i dettagli di come viene deciso il suo tipo:
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();
}
}
Questo è comunque piuttosto prolisso e la complessità aumenterebbe con ogni aggiunta di ruolo - di solito è come finisce il codice quando si tenta di aderire completamente alla Legge di Demetra. Dovresti migliorare la progettazione, in base ai requisiti concreti del sistema da modellare.
Secondo la tua domanda, suppongo che faresti meglio ad andare con la prima opzione con enum direttamente su User
. Se hai bisogno di più logica su Role
, la seconda opzione dovrebbe essere considerata come un punto di partenza.