首先,请注意,entity.underlyingEntity.underlyingEntity.method()
根据Demeter定律,执行类似操作会被视为代码异味。这样,您就可以向使用者公开许多实现细节。而对这种系统的扩展或修改的每一个需求都会伤害很多。
因此,鉴于此,我建议您根据CodesInChaos的注释在上使用HasRole
or IsAdmin
方法User
。这样,如何在用户上实现角色的方式仍然是消费者的实现细节。而且,向用户询问他的角色而不是向他询问他的角色的详细信息,然后根据该角色来决定,这更加自然。
string
除非必要,也请避免使用s。name
是string
变量的一个很好的例子,因为内容是事先未知的。另一方面,类似role
在编译时众所周知的两个不同值的情况,最好使用强类型。那就是枚举类型起作用的地方...
比较
public bool HasRole(string role)
与
public enum Role { Admin, User }
public bool HasRole(Role role)
第二种情况使我对应该传递的内容有了更多的了解。string
如果我对您的角色常量一无所知,它还可以防止我错误地传入一个无效值。
接下来是角色外观的决定。您可以使用直接存储在用户上的枚举:
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();
}
}
但是,这非常冗长,添加每个角色都会增加复杂性-通常,这就是您尝试完全遵守Demeter法则时代码的结局。您应该根据要建模的系统的具体要求来改进设计。
根据您的问题,我想您最好直接将enum放在第一个选项上User
。如果您需要更多的逻辑Role
,则应将第二个选项视为起点。
User.HasRole(Role.Admin)
。