Po pierwsze, należy pamiętać, że robienie czegoś takiego entity.underlyingEntity.underlyingEntity.method()
jest uważane za zapach kodu zgodnie z prawem Demetera . W ten sposób ujawniasz wiele szczegółów implementacji konsumentowi. I każda potrzeba rozszerzenia lub modyfikacji takiego systemu będzie bardzo boleć.
Biorąc to pod uwagę, zaleciłbym, abyś miał metodę HasRole
lub zgodnie z komentarzem CodesInChaos. W ten sposób sposób, w jaki role są wdrażane na użytkowniku, pozostaje szczegółem implementacji dla konsumenta. Bardziej naturalne wydaje się także pytanie użytkownika o jego rolę zamiast pytania o szczegóły jego roli, a następnie podjęcie decyzji w oparciu o to.IsAdmin
User
Unikaj także używania string
s, chyba że jest to konieczne. name
jest dobrym przykładem string
zmiennej, ponieważ zawartość nie jest wcześniej znana. Z drugiej strony, role
jeśli masz dwie wyraźne wartości, które są dobrze znane w czasie kompilacji, lepiej użyj silnego pisania. Właśnie wtedy wchodzi w grę typ wyliczenia ...
Porównać
public bool HasRole(string role)
z
public enum Role { Admin, User }
public bool HasRole(Role role)
Drugi przypadek daje mi o wiele więcej informacji na temat tego, co powinienem przekazywać. Zapobiega mi również błędnym przekazaniem nieważnego string
na wypadek, gdybym nie miał pojęcia o twoich stałych ról.
Następnie jest decyzja, jak będzie wyglądać rola. Możesz użyć enum bezpośrednio zapisanego na użytkowniku:
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;
}
}
Z drugiej strony, jeśli chcesz, aby twoja rola zachowywała się sama, zdecydowanie powinna ukryć szczegóły dotyczące sposobu decydowania o jej typie:
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();
}
}
Jest to jednak dość gadatliwe i złożoność wzrasta z każdym dodaniem roli - zwykle tak kończy się kod, gdy próbujesz w pełni przestrzegać prawa Demetera. Powinieneś ulepszyć projekt, w oparciu o konkretne wymagania modelowanego systemu.
Zgodnie z twoim pytaniem, myślę, że lepiej wybrać pierwszą opcję z enum bezpośrednio User
. Jeśli potrzebujesz więcej logiki Role
, drugą opcję należy uznać za punkt wyjścia.
User.HasRole(Role.Admin)
.