【问题标题】:Limiting what a user can do based on roles根据角色限制用户可以执行的操作
【发布时间】:2011-09-28 07:50:35
【问题描述】:

场景

我正在构建一个系统,每个项目都由 2 个不同的人进行审核。每当第一个审阅者保存项目审阅时,就轮到第二个检查者完成他们的个人审阅。如果我提交了第一个评论并再次打开该项目,那么该项目将进入只读状态,因为您无法查看自己的工作。此外,如果需要更多信息,第一个审阅者可以将项目置于待处理状态,而第二个审阅者则不能。每当用户从列表中选择一个项目时,他们都会获得一个特定的审阅者名单。

到目前为止我所拥有的

每次将项目加载到编辑器时,都会为该人分配两个角色之一,InitialReviewerSecondReviewer

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");
    }
}

问题

我遇到的问题是,我似乎无法摆脱不属于 Editor 类的 Save() 内部的逻辑。

问题

如何从Editor 类中摆脱Save() 函数内部的逻辑?它似乎违反了 SRP 原则。我认为检查当前审阅者对象是否为ICanPutIntoPendingState 类型是个大问题。

请注意,我省略了所有逻辑,因为有很多。

【问题讨论】:

  • 别忘了标记你喜欢的答案。
  • @Tigran:感谢您的提醒。完全打消了我的念头。

标签: c# oop architecture mvvm single-responsibility-principle


【解决方案1】:

给 ReviewerService 一个 Save() 方法是不够的,它内部调用了抽象类 Reviewer 的一个 Save() 方法,抽象类 Reviewer 的抽象 Save() 方法的具体实现在 InitialReviewer 和 SecondReviewer 中进行.因此,您将决策逻辑推送到具有具体实现的类。 希望这会有所帮助。

【讨论】:

    【解决方案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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-26
      • 2020-01-21
      • 1970-01-01
      • 2012-07-07
      • 2017-10-18
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多