我一直在使用设计模式很长一段时间,并且一直在调用/称之为“Chain-of-Responsibility pattern”,但现在我意识到存在差异,这可能不合适。所以我的问题是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;
}
}
它也不总是布尔 - 我已经将这种模式与可变对象一起使用 - 但总是存在短路条件(例如返回true,String为空String,标志设置等)。
到目前为止,我一般将此称为“责任链”模式,考虑从基类继承为实现细节的问题。但是,今天我已经意识到一个重要的区别:链条上的物体不能打断链条的其余部分。实现没有办法说“这是错误的,我可以保证它对于任何条件都是假的”(nb:仅在true
上短路)。
那么,这应该被称为责任链模式以外的东西吗?使用这种方法时,我应该考虑任何问题或问题,而不是传统的实例传递信息。
答案 0 :(得分:2)
我不会将此链称为责任链。
在责任链中,“短路”大致是“我可以处理这个,所以链中的下一个人不必”而不是任何类型的返回值。链中的每个对象通常知道链中的下一个是谁,并在必要时将控制传递给下一个对象。他们通常做某事而不是返回一个值。
你提出它的例子是完全合理的,虽然我不确定它是一个命名模式。我现在对你描述的其他变种我不太清楚。
答案 1 :(得分:1)
你所拥有的是一个责任链,但你可以通过添加一些小的变化来建立一个“纯粹的”责任链。
您可以创建一个枚举,它将代表您希望从此功能获得的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;
}
}