我当前的IVR应用程序使用包装类和几种方法来调用Web服务,然后解析其结果。每个类都有一个调用Web服务的“调用”方法,然后调用后续的子方法将解析分解为逻辑块。
每当在一个或多个子方法中需要新的输入参数时,前一个开发人员会将其作为参数添加到调用上,然后将其作为参数添加到子方法中。
这是执行此操作的正确方法,还是更好在类上设置字段,然后在必要时引用它?
而不是:
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)
谢谢!
答案 0 :(得分:4)
第一个解决方案允许使对象无状态,并允许对所有调用使用唯一实例,即使是并行。
第三个允许使对象有状态但不可变。它可以用于使用相同字段集的多个调用,即使是并行(如果是不可变的)。
这两种解决方案都是可以接受的。对象具有的状态越少,最容易使用它,特别是在多线程环境中。
对象的可变性越小,最容易使用它。
第二个使它成为一个有状态的可变对象,它不能被多个线程使用(没有同步)。它对我来说看起来不如其他两个。
答案 1 :(得分:1)
我的一般规则是尽可能避免面向服务的类中的有状态。虽然Java本身并不真正支持函数式编程,但最简单,最可扩展的实现是您的第一种方法,它不使用任何成员变量。
如果您的目标是避免频繁更改方法签名,则可以尝试使用更通用的字段封装:
public class Invoker {
public static void invoke(ResultContainer result, List<String> parameters) {
submethod1(result, parameters);
submethod2(result, parameters);
}
}
我还建议您查看Decorator design pattern以获取更多想法。
答案 2 :(得分:0)
这取决于您的参数是数据还是识别模式/开关。
我建议数据结构类型的一个参数和包含不同操作的枚举类型的另一个参数。
然后根据您的枚举类型或操作模式,您可以选择要在哪个类上执行的策略。
要限制这种增加的参数方法,您可以提供一个接口。并强制实施坚持这一点。