我正在做一个新项目,我正在努力坚持正确的设计方法。我遇到了一个 switch 语句的问题,我知道这是一个问题,但我无法以面向对象的方式重新分解它。
在系统中,一个用户有 0..n 个角色。根据用户当前的角色,系统将向该用户返回一组特定的数据。用户将能够执行某些操作,但不能执行其他操作等。
public class User
{
public bool HasRole(string roleName)
{
return this.UserRoles.Any(r => r.Name == roleName);
}
public string Username { get; set; }
public long? CurrentRoleId { get; set; }
public Role CurrentRole { get; set; }
public virtual IList<Role> UserRoles { get; set; }
}
public class Role
{
public Role() { }
public string Name { get; set; }
}
public class GetEventsQuery : IQuery<List<Event>>
{
public List<Event> Query()
{
switch (this.user.CurrentRole.Name)
{
case "Administrator":
UserIsNotInAdministratorRole();
return repository.All.ToList();
case "Supervisor":
UserIsNotInSupervisorRole();
return repository.All.Where(evnt => evnt.SupervisorId == this.user.RecordId).ToList();
case "User":
UserIsNotInUserRole();
return repository.All.Where(evnt => evnt.UserId == this.user.RecordId).ToList();
default:
throw new Exception("GetEventsQuery Unknow exception.");
}
}
private void UserIsNotInUserRole()
{
if (!this.user.HasRole("User"))
{
throw new NoUserRoleException("User does not have user role!");
}
}
private void UserIsNotInSupervisorRole()
{
if (!this.user.HasRole("Supervisor"))
{
throw new NoSupervisorRoleException("User does not have supervisor role!");
}
}
private void UserIsNotInAdministratorRole()
{
if (!this.user.HasRole("Administrator"))
{
throw new NoAdministratorRoleException("User does not have administrator role!");
}
}
public GetEventsQuery(string username, IUserRepository userRepository, IEventRepository repository)
{
this.repository = repository;
var userQuery = new GetUserQuery(username, userRepository);
this.user = userQuery.Query();
}
private readonly User user;
private readonly IEventRepository repository;
}
这个 switch 语句将出现在系统的所有部分。如果有办法将它重新分解到一个类中并将它放在一个位置,我不介意保留它,但一遍又一遍地重复它绝对是一种代码味道。我刚刚开始这个项目,所以如果有更好的方法来设计对象层次结构或进行重大更改以消除这个问题,我愿意接受。