1

シナリオ

各アイテムが 2 人の異なる人によってレビューされるシステムを構築しています。最初のレビュアーがアイテムのレビューを保存すると、次は 2 番目のチェッカーが個別のレビューを完了します。最初のレビューを送信してアイテムを再度開くと、自分の作品をレビューできないため、アイテムは読み取り専用状態になります。また、最初のレビュー担当者は、さらに情報が必要な場合にアイテムを保留状態にすることができますが、2 番目のレビューではできません。各ユーザーには、リストから項目を選択するたびに、特定のレビュー担当者ロールが与えられます。

私がこれまでに持っているもの

アイテムがエディターに読み込まれるたびに、ユーザーには 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()から関数内のロジックを取り除くにはどうすればよいですか? EditorSRP の原則に違反しているようです。現在のレビュアー オブジェクトが型ICanPutIntoPendingStateであるかどうかを確認することが大きな問題だと思います。

かなりの数があるため、すべてのロジックを省略したことに注意してください。

4

2 に答える 2

3

この時点で、抽象クラス Reviewer の 1 つの Save() メソッドを内部的に呼び出す 1 つの Save() メソッドを ReviewerService に与えるだけでは十分ではありません。したがって、決定ロジックを具体的な実装を持つクラスにプッシュします。お役に立てれば。

于 2011-07-04T19:21:12.710 に答える
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");
    }
}

また、入力モデルを使用するレビューアサービスの関数を1つだけ公開することも検討できます。その後、サービスは入力を検証し、適切なアクションを実行する責任があります。このようなもの:

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-07-04T21:30:43.407 に答える