我正在构建一个系统,每个项目都由2个不同的人进行审核。每当第一个评论者保存项目评论时,它就会转向第二个检查者完成他们的个人评论。如果我提交了第一次审核并再次打开该项目,则该项目将进入只读状态,因为您无法查看自己的工作。此外,如果需要更多信息,第一个评论者可以将项目置于待定状态,而第二个评论则不能。每当用户从列表中选择一个项目时,每个用户都会获得一个特定的审阅者滚动。
每次将一个项目加载到编辑器中时,该人员将被赋予两个角色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
中不属于那里的逻辑。
如何摆脱Save()
类中Editor
函数内部的逻辑?它似乎违反了SRP原则。我认为检查当前审阅者对象是否为ICanPutIntoPendingState
类型是个大问题。
请注意,我已经省略了所有逻辑,因为它有很多。
答案 0 :(得分:3)
Woudn足以向ReviewerService提供一个Save()方法,该方法在此时内部调用一个Save()方法,抽象类Reviewer,用于抽象Save()方法的具体实现在InitialReviewer和SecondReviewer中创建。因此,您可以通过具体实现将决策逻辑推送到类。 希望这会有所帮助。
答案 1 :(得分:2)
也许你应该考虑将业务逻辑从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");
}
}
您还可以考虑在审阅者服务上仅公开一个带有输入模型的函数。然后,服务负责验证输入并采取适当的措施。像这样:
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);
}
}