对于这种情况,我会尝试对链进行建模,并通过给节点更多的“智能”来将执行的责任转移到链本身。在某种程度上,我会将节点视为命令,因为它们可以自己执行,并且通过具有通用接口,能够创建组合。(顺便说一句,我不是 Java 程序员,所以请原谅我可能的语法错误)。所以,我的主要设计决策是:
- 链知道如何执行自己。
- 链节点可以是复合的。
我将首先定义如下内容:
public abstract class ChainNode {
public abstract Content apply(Content content);
}
/**
The NullObject of the chain
http://www.oodesign.com/null-object-pattern.html
*/
public class FinalNode extends ChainNode {
public Content apply(Content content) {
return content;
}
}
/** A sample filter */
public class FilterA extends ChainNode {
private ChainNode nextNode;
FilterA(ChainNode nextNode) {
this.nextNode = nextNode;
}
public Content apply(Content content) {
filteredValue = //Apply the filter
return nextNode.apply(filteredValue);
}
}
/** An if-then-else filter */
public abstract class ConditionalFilter extends ChainNode {
private ChainNode trueFilter;
private ChainNode falseFilter;
ConditionalFilter(ChainNode trueFilter, ChainNode falseFilter) {
this.trueFilter = trueFilter;
this.falseFilter = falseFilter;
}
public Content apply(Content content) {
if (this.evalCondition(content)) {
return this.trueFilter.apply(content);
}
else {
return this.falseFilter.apply(content);
}
}
private abstract boolean evalCondition(Content content);
}
使用这种方法,您正在做的是将控制结构转换为对象并要求它们执行,这甚至允许您创建与标准 if-then 或 switch 语句不同的逻辑。有了这个基础,您可以创建一个具有不同分支运算符的链,触发不同的过滤路径。
需要注意的一些事项是:
- 我假设一个过滤器返回 type 的东西
Content
,这实际上允许您将一个过滤器链接到另一个过滤器。我想这在你的要求中是正确的,但我不确定。
- 对于每个新过滤器,您只需创建一个新类并定义
apply
方法。
- 空对象始终是链的最后一个节点,停止链调用。
- 要定义新的“分支节点”,您必须从子类化
ConditionalFilter
并重新定义该evalCondition
方法。我不知道 Java 是否有闭包(我认为没有),但如果有,您可以添加一个condition
实例变量并用闭包对其进行参数化,从而避免为每个新条件进行子类化。或者,在 Java 世界中可能有更可接受的解决方法,我只是不知道 :(。
- 我假设条件分支是根据
content
参数决定的。如果您需要更多信息来做出决定,您还可以在apply
方法中传递一个上下文对象。根据您的需要,这可以是结构化对象,如果您需要更大的灵活性,也可以只是字典。
最后,关于链条的构建,如果链条很长且构建复杂,我认为这里的构建器应该适合您的需求。
高温高压