基于角色限制用户可以执行的操作
本文关键字:用户 执行 操作 于角色 角色 | 更新日期: 2023-09-27 18:01:12
场景
我正在建立一个系统,每个项目都由两个不同的人进行审查。每当第一个审阅者保存项目审阅时,就轮到第二个审阅者完成他们的个人审阅。如果我提交了第一次审阅,然后再次打开该项目,则该项目将处于只读状态,因为您无法审阅自己的作品。此外,如果需要更多信息,第一个审阅者可以将项目置于挂起状态,而第二个审阅者则不能。每当每个用户从列表中选择一个项目时,他们都会得到一个特定的审阅者名单。
到目前为止我所拥有的
每次将一个项目加载到编辑器中时,该人员都会获得两个角色中的一个,即InitialReviewer
或SecondReviewer
。
public class Reviewer
{
public void AddReview(string review) { }
}
public class InitialReviewer : Reviewer, ICanPutIntoPendingState
{
public void PutIntoPendingState(string pendingState) { }
}
public class SecondReviewer : Reviewer
{
// Just use base class to add review
}
public class ReviewerService
{
private readonly Reviewer _reviewer;
public void AddReview(string review)
{
_reviewer.AddReview(review);
}
public void PutIntoPendingState(string pendingState)
{
_reviewer.PutIntoPendingState(pendingState);
}
}
我编辑的精简版。
public class Editor
{
private readonly ReviewerService _reviewerService;
public Editor(ReviewerService reviewerService)
{
_reviewerService = reviewerService;
}
public void SaveCommand()
{
if(user chose a pending state && _reviewerService.Reviewer is ICanPutIntoPendingState) // Pending state is a dropdown.
_reviewerService.PutIntoPendingState("pending state");
else // the user made a complete review
_reviewerService.AddReview("user review");
}
}
问题
我遇到的问题是,我似乎无法摆脱Save()
中不属于Editor
类的逻辑。
问题
如何从Editor
类中去除Save()
函数内部的逻辑?这似乎违反了SRP原则。我认为,检查当前审阅者对象是否属于ICanPutIntoPendingState
类型是个大问题。
请注意,我已经放弃了所有的逻辑,因为有相当多的逻辑
给ReviewerService一个Save((方法是不够的,该方法内部调用抽象类Reviewer的一个Save((方法,该抽象类的具体实现是在InitialReviewer和SecondReviewer中实现的。因此,您可以将决策逻辑推送到具有具体实现的类中。希望这能有所帮助。
也许您应该考虑将业务逻辑从Reviewer类转移到ReviewerService。简单的实现是这样的:
public abstract class Reviewer
{
public abstract bool CanPutIntoPendingState { get; }
}
public class InitialReviewer : Reviewer
{
public override bool CanPutIntoPendingState
{
get
{
return true;
}
}
}
public class SecondReviewer : Reviewer
{
public override bool CanPutIntoPendingState
{
get
{
return false;
}
}
}
public class ReviewerService
{
private readonly Reviewer _reviewer;
public void AddReview(string review)
{
// do add review logic here
}
public void PutIntoPendingState(string pendingState)
{
if (_reviewer.CanPutIntoPendingState )
{
// do PutIntoPendingState logic here
}
}
}
public class Editor
{
private readonly ReviewerService _reviewerService;
public Editor(ReviewerService reviewerService)
{
_reviewerService = reviewerService;
}
public void SaveCommand()
{
if(user chose a pending state) // Pending state is a dropdown.
_reviewerService.PutIntoPendingState("pending state");
else // the user made a complete review
_reviewerService.AddReview("user review");
}
}
您还可以考虑在review服务上只公开一个函数,该函数接受输入模型。然后,服务负责验证输入并采取适当的操作。类似这样的东西:
public class ReviewerService
{
private readonly Reviewer _reviewer;
public void StoreReview(ReviewModel model)
{
// validate input here
// do business logic here
if (model.IsPendingState && _reviewer.CanPutIntoPendingState)
{
this.PutIntoPendingState("pending state");
}
else
{
this.AddReview(model.Review);
}
}
private void AddReview(string review)
{
// do add review logic here
}
private void PutIntoPendingState(string pendingState)
{
// do PutIntoPendingState logic here
}
}
public class ReviewModel
{
public string Review { get; set; }
public bool IsPendingState { get; set; }
}
public class Editor
{
private readonly ReviewerService _reviewerService;
public Editor(ReviewerService reviewerService)
{
_reviewerService = reviewerService;
}
public void SaveCommand()
{
ReviewModel model = new ReviewModel() {Review="user review",IsPendingState=user chose a pending state };
_reviewerService.StoreReview(model);
}
}