我当前的IVR应用程序使用一个包装器类,其中包含几个方法来调用web服务,然后解析其结果。每个类都有一个单独的调用web服务的"invoke"方法,然后调用后续的子方法将解析分解为逻辑块。
每当在一个或多个子方法中需要一个新的输入参数时,上一个开发人员会将其作为参数添加到调用中,然后将其作为参数添加到子方法中。
这样做是正确的吗?或者在类上设置一个字段,然后在必要时引用它会更好吗?
代替:
invoke (oldField1, oldField2, newField1)
submethod1 (results, oldField1, oldField2, newField1)
submethod2 (results, oldField1, oldField2, newField1)
应该是:
invoke(oldField1, oldField2, newField1){
OldField1=oldField1
OldField2=oldField2
NewField1=newField1
}
submethod1(results)
submethod2(results)
甚至:
new (oldField1, oldField2, newField1){
OldField1=oldField1
OldField2=oldField2
NewField1=newField1
}
invoke()
submethod1(results)
submethod2(results)
谢谢!
第一种解决方案允许使对象无状态,并允许为所有调用使用唯一的实例,即使是并行的。
第三个允许使对象有状态但不可变。它可以用于使用同一组字段的多个调用,甚至是并行的(如果设置为不可变的)。
这两种解决方案都是可以接受的。对象的状态越少,就越容易使用,尤其是在多线程环境中。
对象的可变性越小,就越容易使用。
第二个使它成为一个有状态的可变对象,它不能被多个线程使用(没有同步)。
我的一般规则是尽可能避免在面向服务的类中使用有状态。虽然Java本身并不真正支持函数式编程,但最简单和最可扩展的实现是第一种方法,它不使用成员变量。
如果您的目标是避免频繁更改方法签名,您可以尝试使用更通用的字段封装:
public class Invoker {
public static void invoke(ResultContainer result, List<String> parameters) {
submethod1(result, parameters);
submethod2(result, parameters);
}
}
我还建议您看一下Decorator设计模式,以获得更多的想法。
这取决于你的参数是数据还是识别模式/开关。
我建议一个实参为数据结构类型,另一个实参包含不同操作的枚举类型。
然后根据枚举类型或操作模式选择要执行的类的策略。
要限制这种递增参数的方法,可以提供一个接口。并强制实现遵守它。