0

我使用设计模式已经有一段时间了,并且一直将其称为“责任链模式”,但现在我意识到存在差异,这样做可能不合适。所以我的问题是 1,“下面是这种模式的一个实例,还是应该将其称为其他东西?”,以及 2,“我有什么理由更喜欢传统方式吗?”。

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

interface FooBar{
    boolean isFooBar( Object o );
}

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

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

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

到目前为止,我通常将其称为“责任链”模式,考虑到从基类继承的问题是一个实现细节。但是,今天我意识到了一个重要的区别:链条上的物体不能打断链条的其余部分。实现没有办法说“这是错误的,我可以保证它在任何情况下都是错误的”(nb:短路仅在 上true)。

那么,这应该被称为责任链模式以外的东西吗?在使用这种方法而不是让实例传递消息的传统方法时,我是否应该考虑任何顾虑或问题。

4

2 回答 2

2

我不会称之为责任链链。

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

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

于 2011-06-28T22:23:28.627 回答
1

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

您可以创建一个枚举,该枚举将代表您期望从此函数获得的 3 个不同结果。

 public enum Validity{
     Invalid,
     Indeterminate,
     Valid
 }

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

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

然后,您的大多数FooBars 将不得不实现这样的方法:

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;
    }
}
于 2011-06-28T16:05:24.167 回答