如果您有一个输入参数可能是输出的方法。
假设我们有一个save方法,它生成一个自动生成的id,客户端可能有兴趣在调用save()之后使用它。
你应该像这样设计方法签名:
1
public void save(Person person);
客户电话:
personService.save(person);
System.out.println(person.getId());
2
public Person save(Person person);
客户电话:
person = personService.save(person);
System.out.println(person.getId());
我们知道,在接收对象的方法调用中,会传递对该对象的引用,因此只要具有相同的引用,对其他人所做的任何更改都将被其他人感知。但是在远程调用的情况下发生序列化/反序列化,因此我的对象引用是与远程服务对象不同的引用。因此,即使进行了更改,客户也不会注意到差异。
此时我知道该方法不会是远程调用,所以我可以使用第一个签名来设计它。但是,如果将来这种情况发生变化并需要被称为远程呼叫,那该怎么办呢。
所以我的问题是: 我应该设计我的API,认为将来可能会调用API作为远程调用,并且不使用object参数作为将值返回给客户端的方法(2)或者我应该根据我的实际设计我的API服务不是远程的情况(1)?
谢谢
答案 0 :(得分:1)
为什么不两个都做?使用第二个签名,在本地修改人员,暂时只返回对同一个人的引用。这样,在将来针对任何需求进行更改将不会更改API,并且当前用户仍然可以使用您的第一种方法。
话虽如此,总的来说,我对改变其参数的方法感到不舒服,除非这是他们唯一的目的,并且他们被命名并记录以表明这一点。从“做什么方法,从中得到什么新信息”的角度来看,我可能会选择以下签名:
public ID save(Person);
答案 1 :(得分:1)
两者都可以;让save()
返回新ID 和使用getId()
方法。从“setter”(一种更改状态的方法)返回一个值有很多先例 - java Collections API会一直这样做,例如Map.remove(Object)
返回boolean
。
流畅的界面
您可能需要考虑另一种模式,即Fluent Interface模式。使用流畅的API,您可以从您返回的每个方法this
返回对象(即void
)。这允许调用者“链接”方法调用。使用流畅的界面,您的代码将如下所示:
public Person save() {
// do your save stuff
return this;
}
如果您想在保存后使用该ID,则需要对此进行编码:
save().getId();
简单!这种模式也被用于许多现有的Java代码中,特别是在this java fluent code example
中的休眠我建议使用流利的,如果没有别的东西可以使用它来练习
答案 2 :(得分:0)
我建议使用第一种方法,因为对象很少单独使用。 Person对象通常由引用其他实体(如Employee)引用。如果你创建一个新实例,那么你就会使整个对象图无效,相信我,你不想搞乱深度复制。
至于未来RPC的可能性,无论你将用什么来实现这一点,它很可能能够在提交操作后更新ID字段。
@CPerkins - 对象以“参考值”传递,绝对正确;)