设计一组使用依赖关系的规则

本文关键字:依赖 关系 规则 一组 | 更新日期: 2023-09-27 18:01:39

我有一项服务,可以读取特定邮箱收到的所有电子邮件。问题是,基于电子邮件所包含的内容,我们必须执行一个或多个操作。我目前有下面的混乱。我把它缩短了一些。实际的应用程序目前有更多的极端情况。

var email = new Email { Body = "Some random email body text..." };
if(email.Body.StartsWith("A"))
{
    // Requires a dependency on INotifier
    Console.WriteLine("Notifying administrator");
}
if (email.Body.StartsWith("B"))
{
    // Requires a dependency on IParser and IRepository
    Console.WriteLine("Parsing email and adding to database");
}
if (email.Body.EndsWith("C"))
{
    // Requires a dependency on ISender and INotifier
    Console.WriteLine("Forwarding email and notifying administrator");
}
if (email.Body.EndsWith("C"))
{
    // Requires a dependency on INotifier
    Console.WriteLine("Ignoring email");
}

本质上,如果满足标准,则必须使用一个或多个依赖项执行关联操作。我想把这些依赖项注入构造函数中。

我想创建这样的东西:

public class AdministratorNotififerCriteria : ICriteria
{
    private readonly INotifier _notifier;
    public AdministratorNotififerCriteria(INotifier notifier)
    {
        _notifier = notifier;
    }
    private void Execute()
    {
        _notifier.Notify();
    }
    public void CheckSatisfaction(Email email)
    {
        if(email.Body.StartsWith("A"))
            Execute();
    }
}

底线是我希望生成可组合的命令。因此,当我添加另一个标准时,我所要做的就是继承ICriteria(或其他)并让应用程序找出它。

这一切都有一个名字吗?

我目前有一个类似的消费者。

public class EmailConsumer
{
    private readonly IEnumerable<ICriteria> _criterias;
    // Criterias are found and injected with Windsor from all classes inheriting the ICriteria interface
    public EmailConsumer(IList<ICriteria> criterias)
    {
        _criterias = criterias;
    }
    public void Consume(IList<Email> emails)
    {
        foreach(var criteria in _criterias)
        {
            foreach(var email in emails)
            {
                criteria.CheckSatisfaction(email);
            }
        }
    }
}

编辑

谢谢你的回复,IAbstract和djna。我现在明白了策略和CoR模式的作用,考虑哪一个更合适,证明了我对当前的问题理解得不够。

我理解它的方式是,CoR是贪婪的,谁能承担责任将执行并继续下一个对象被消耗。另一方面,似乎没有什么能阻止策略之间的循环,说"嘿!我可以正确地处理这个请求,所以不用担心"。

设计一组使用依赖关系的规则

这似乎是责任链的一种变体,可能有一些额外的逻辑来处理非排他情况——如果Body以"a"开始,以"C"结束,您打算发生什么?

责任链中的一个想法是不需要一个庞大的调度if/else链。相反,你只需将电子邮件提供给一些执行iccriteria的人,他们有责任处理或将其传递给下一位候选人。

@djna暗示了CoR模式的一种变体。我并不完全不同意。它看起来更像这个策略模式的例子。