Прежде всего, обратите внимание, что выполнение чего-то подобного entity.underlyingEntity.underlyingEntity.method()
считается запахом кода согласно Закону Деметры . Таким образом, вы раскрываете много деталей реализации потребителю. И каждая необходимость расширения или модификации такой системы будет очень больно.
Поэтому, учитывая это, я бы порекомендовал вам использовать метод HasRole
или IsAdmin
в User
соответствии с комментарием CodesInChaos. Таким образом, способ реализации ролей для пользователя остается деталью реализации для потребителя. Кроме того, более естественно спрашивать пользователя о его роли, а не спрашивать его о деталях его роли, а затем принимать решение на основе этого.
Пожалуйста, также избегайте использования string
s, если это необходимо. name
хороший пример string
переменной, потому что ее содержимое неизвестно заранее. С другой стороны, что-то вроде того, role
где у вас есть два разных значения, которые хорошо известны во время компиляции, вам лучше использовать строгую типизацию. Вот где в игру вступает тип перечисления ...
сравнить
public bool HasRole(string role)
с
public enum Role { Admin, User }
public bool HasRole(Role role)
Второй случай дает мне гораздо больше представления о том, что я должен обойти. Это также препятствует тому, чтобы я ошибочно передал инвалид string
в случае, если я понятия не имел о ваших константах роли.
Далее следует решение о том, как будет выглядеть роль. Вы можете использовать enum, который хранится непосредственно у пользователя:
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;
}
}
С другой стороны, если вы хотите, чтобы ваша роль имела собственное поведение, она обязательно должна снова скрыть детали того, как определяется ее тип:
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();
}
}
Это, однако, довольно многословно, и сложность возрастает с каждым добавлением роли - обычно так заканчивается код, когда вы пытаетесь полностью придерживаться закона Деметры. Вы должны улучшить дизайн, основываясь на конкретных требованиях моделируемой системы.
В соответствии с вашим вопросом, я думаю, вам лучше выбрать первый вариант с включенным enum User
. Если вам нужно больше логики Role
, второй вариант следует рассматривать как отправную точку.
User.HasRole(Role.Admin)
.