这仍然会被视为责任链模式吗?

发布于 2024-11-17 22:28:10 字数 1019 浏览 3 评论 0原文

我已经使用设计模式相当长一段时间了,并且一直将其称为“

我在开发软件时经常使用以下模式。我有一个定义 函子 的接口,类似这样。

interface FooBar{
    boolean isFooBar( Object o );
}

这些通常是搜索、过滤或处理类;通常类似于 比较器。实现方法通常是功能性的(即无副作用)。最终,我发现自己创建了一个接口的实现,如下所示:

class FooBarChain implements FooBar{
    FooBar[] foobars;

    FooBarChain( FooBar... fubars ){
         foobars = fubars;
    }

    boolean isFooBar( Object o ){
         for( FooBar f : foobars )
             if(  f.isFooBar( o )  )
                 return true;

         return false;
    }
}

它也不总是布尔值 - 我也将这种模式与可变对象一起使用 - 但总是有一个短路条件(例如返回 true,字符串是空字符串,设置标志等)。

到目前为止,我通常将其称为“责任链”模式,并将从基类继承的问题视为实现细节。然而,今天我意识到一个重要的区别:链上的对象不能中断链的其余部分。实现没有办法说“这是假的,我可以保证在任何条件下它都是假的”(注意:仅在 true 上短路)。

那么,这是否应该称为责任链模式以外的其他模式?与传统的让实例传递消息的方法相比,使用此方法时是否有任何我应该考虑的问题?

I have been using a design pattern for quite some time and have been calling/referring to it as a "Chain-of-Responsibility pattern" but now I realise there are differences, and it may not be appropriate to do so. So my question is 1, "is the following an instance of this pattern, or should it be called something else?", and 2, "is there any reason I should prefer the traditional way?".

I often use the following pattern when developing software. I have an interface that defines a functor, something like this.

interface FooBar{
    boolean isFooBar( Object o );
}

These are usually search, filtering, or processing classes; usually something like Comparator. The implementation method is usually functional (i.e. side-effect free). Eventually, I find myself creating an implementation of the interface that looks like:

class FooBarChain implements FooBar{
    FooBar[] foobars;

    FooBarChain( FooBar... fubars ){
         foobars = fubars;
    }

    boolean isFooBar( Object o ){
         for( FooBar f : foobars )
             if(  f.isFooBar( o )  )
                 return true;

         return false;
    }
}

Its not always booleans either -I've used this pattern with mutable objects as well- but there is always a short-circuiting condition (e.g. returns true, the String is empty String, a flag gets set etc).

Until now I have generally calling this a "Chain of Responsibility" pattern, considering the issue of inheriting from a base class to be an implementation detail. However, today I have realised an important difference: the objects along the chain cannot interrupt the rest of chain. There is no way for an implementation to say "this is false, and I can guarantee it will be false for any condition" (nb: short-circuits only on true ).

So, should this be called something other than a chain-of-responsibility pattern? Are there any concerns or issues I should consider when using this approach over the traditional having the instances pass the message along.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌酱 2024-11-24 22:28:10

我不会称这条链为责任链。

在责任链中,“短路”大致是“我可以处理这个问题,所以链中的下一个人不必这样做”,而不是任何类型的返回值。链中的每个对象都知道链中的下一个对象是谁,并根据需要将控制权传递给下一个对象,这是正常的。他们通常做一些事情而不是返回一个值。

您提供的示例是完全合理的,尽管我不确定它是命名模式。我现在不太清楚你描述的其他变体。

I wouldn't call this chain of Chain of Responsibility.

In Chain of Responsibility, the "short-circuit" is roughly "I can handle this, so the next guy in the chain doesn't have to" rather than being a return value of any kind. It's normal for each object in the chain to know who is next in the chain and to pass control to that next object as necessary. They normally do something rather than returning a value.

The example you've presented it is perfectly reasonable, though I'm not sure it's a named pattern. I'm not too clear right now on the other variants you describe.

杀お生予夺 2024-11-24 22:28:10

您拥有的是责任链,但您可以通过添加一些小的更改来创建“纯粹”的责任链。

您可以创建一个枚举来表示您期望从此函数得到的 3 个不同结果。

 public enum Validity{
     Invalid,
     Indeterminate,
     Valid
 }

您可以将接口更改为可链接的,如下所示:

 public interface ChainFooBar{
     public boolean isFooBar(Object o);
     public Validity checkFooBar(Object o);
 }

您的大多数 FooBar 都必须实现如下方法:

public abstract class AbstractFooBar implements FooBar{
    public Validity checkFooBar(Object o){
        return this.isFooBar(o) ? Validity.Valid : Validity.Indeterminate;
    }
}

然后您可以更改您的链以检查任一明确的答案。

public class FooBarChain implements FooBar{
    private FooBar[] fooBars;

    public FooBarChain(FooBar... fooBars){
        this.fooBars = fooBars;
    }

    public Validity isFooBar(Object o){
        for(FooBar fooBar : this.fooBars){
            Validity validity = fooBar.checkFooBar(o);
            if(validity != Validity.Indeterminate){
                return validity == Validity.Valid;
            }
        }
        return false;
    }
}

What you have is a chain-of-responsibility, but you can make a 'pure' chain of responsibility by adding a few small changes.

You can create an enum that will represent the 3 different results that you are expecting from this function.

 public enum Validity{
     Invalid,
     Indeterminate,
     Valid
 }

You can change the interface to be chain-able like so:

 public interface ChainFooBar{
     public boolean isFooBar(Object o);
     public Validity checkFooBar(Object o);
 }

Most of your FooBars would then have to implement a method like this:

public abstract class AbstractFooBar implements FooBar{
    public Validity checkFooBar(Object o){
        return this.isFooBar(o) ? Validity.Valid : Validity.Indeterminate;
    }
}

Then you can change your chain to check for either of the definite answers.

public class FooBarChain implements FooBar{
    private FooBar[] fooBars;

    public FooBarChain(FooBar... fooBars){
        this.fooBars = fooBars;
    }

    public Validity isFooBar(Object o){
        for(FooBar fooBar : this.fooBars){
            Validity validity = fooBar.checkFooBar(o);
            if(validity != Validity.Indeterminate){
                return validity == Validity.Valid;
            }
        }
        return false;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文