سلسلة تنفيذ تنوع المسؤولية

لقد حصلت على مجموعة من المهام التي هي في الأساس تنوع في نمط سلسلة المسؤولية.

مهمة في خط أنابيب بلدي تبدو على النحو التالي

internal interface IPTask
{
    bool CanExecute(T instance);
    T Process(T instance);
}

.. و معالج بلدي يشبه

internal interface IProcessor
{
    T Execute(T instance);
}

ويبدو تنفيذي ملموسة مثل هذا:

public class Processor : IProcessor
{
    private readonly ITasks tasks;

    public Processor(ITasks tasks)
    {
        this.tasks= tasks;
    }

    public T Execute(T instance)
    {
         var taskstoExecute = tasks.GetTasks()
                                   .Where(task => task.CanExecute(instance));

         taskstoExecute.ToList().ForEach(task=>task.Process(instance));

         return T;
    }
}

.. و مهامي تبدو كالتالي:

internal interface ITasks
{
    IEnumerable> GetTasks();
}

يمكن أن تكون حالات T مختلفة ، ولكن مرتبطة بعقد عام. تتمثل إحدى المهام في تعيين الكائن الوارد في كائن مختلف تمامًا وإعادة توجيه ذلك المثيل من هناك.

الآن كما ترون ، أنا أعمل جميع المهام في خط الأنابيب ، أود تعديل هذا على ما يلي:

  • يجب أن تكون المدخلات لطريقة تنفيذ للمهمة التالية من المهمة التي تم تنفيذها سابقًا. </لى>
  • إذا فشلت CanExecute في مهمة ، يجب أن يتوقف خط الأنابيب عن معالجة المهام.

هل يمكنك مساعدتي في الحصول على هذا. كما تتوقع أن يتم تنظيم التعليمات البرمجية بشكل مختلف لهذا الغرض؟

0

2 إجابة

وماذا عن هذا:

public T Execute(T instance)
{
     T result = instance;
     foreach(var individual in tasks.GetTasks())
     {
         if(!individual.CanExecute()) break;

         result = individual.Process(result);
     }

     return result;
}

كما لديك حاليا ، هو أشبه إلى حد كبير نمط مركب من سلسلة من المسؤولية. هذا التغيير يجعله أكثر قليلا CoR-ish. ولكن من الأهم ملاحظة ما إذا كانت تلبي احتياجاتك بدلاً من استخدام المصطلحات الصحيحة لنمط التصميم. :)

0
وأضاف

باستخدام هذا التطبيق ، يتم استخدام CanProcess فعليًا لتشغيل استثناء سيوقف العملية.

لقد قمت بإضافة تطبيق ثانٍ ، يسمى ExecuteWithPartial ، والذي يتعامل مع الاستثناء ، في حالة هذا السلوك الذي تتوقعه. إنه يعمل ولكن إذا كان هناك خطأ ، فإنه يعيد النتيجة الجزئية إلى هذه النقطة.

public class Processor : IProcessor
{
    //... rest of your code

    public T Execute(T instance)
    {
        return this._tasks.GetTasks().Aggregate(instance, (current, task) => InternalExecute(task, current));
    }

    public T ExecuteWithPartial(T instance)
    {
        var target = instance;
        try
        {
            foreach (var task in this._tasks.GetTasks())
            {
                target = InternalExecute(task, target);
            }
            return target;
        }
        catch (CantExecuteException)
        {
            return target;
        }
    }


    private static T InternalExecute(IPTask task, T instance)
    {
        if (!task.CanExecute(instance))
            throw new CantExecuteException();
        return task.Process(instance);
    }
}

وفئة الاستثناء الجديدة هي:

public class CantExecuteException : Exception
{
}
0
وأضاف