私は新しいプロジェクトに取り組んでおり、適切な設計方法を遵守しようとしています。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 ステートメントは、システムのすべての部分に表示されます。それをクラスにリファクタリングして単一の場所に配置する方法があった場合、それを保持してもかまいませんが、それを何度も繰り返すことは間違いなくコードの匂いです。私はこのプロジェクトを始めたばかりなので、オブジェクト階層を設計したり、この問題を解消するために大きな変更を加えたりするためのより良い方法があれば、私はそれを受け入れます。