Java私有方法签名的清晰性和更好的实践
我收到了以下代码片段的代码审阅注释-Java私有方法签名的清晰性和更好的实践,java,code-readability,Java,Code Readability,我收到了以下代码片段的代码审阅注释- public void doWork(String a, Integer b) { .. .. SomeService service = getService(); for (Integer i : numbers) { doMoreWork(a, b, service); } } private void doMoreWork(String a, Integer b, SomeService servi
public void doWork(String a, Integer b) {
..
..
SomeService service = getService();
for (Integer i : numbers) {
doMoreWork(a, b, service);
}
}
private void doMoreWork(String a, Integer b, SomeService service) {
...
...
...
service.doingMoreWork(a, b);
}
审查建议-
SomeService=getService()应在doMoreWork
中调用code>,以确保签名清晰。所以签名变成了doMoreWork(a,b)
,这更容易理解李>
我的问题-
由于doMoreWork()
是在循环中发生的,因此我将向它传递一个服务对象。doMoreWork()只是代码中的一个私有逻辑单元,可以将“service”作为方法参数。这种方法永远不会公开。在这种情况下,指导原则是什么?这里的清晰度或可读性如何受到影响
(注:
调用getService()
没有太多的性能开销,所以性能不是我的标准
服务注入在这里不是一个选项。它需要按照示例中所示的方式获取
doMoreWork()不仅仅是调用service.doingMoreWork()。它还需要遵循一些预先的步骤
)由于建议是正确的,您只需要在doMoreWork
方法中使用Service
对象。因此,最好只在执行操作的doMoreWork
方法中获取Service
对象
如果在循环
之后添加了更多语句,那么服务
对象将持续很长时间,直到其作用域存在为止(直到没有遇到关闭}
),它将不会被垃圾收集,因此您应该在域工作
中调用getService()
,并在域工作(a,b)中传递2个参数
。这样会更容易理解 从代码清晰性的角度来看,doMoreWork
是类中知道其服务的实例方法(即,它有一个getService()
方法)。将服务
放在签名中会让读者想知道这个方法指的是什么服务
,因此有些混乱。但是,在一个拥有多个服务并且必须对其中几个服务执行相同类型的工作的类中,这样的签名是完全有意义的。老实说,除了在doMoreWork
方法中声明该变量之外,声明该变量对任何人都没有好处。原因如下:
- 在
doWork
getService()
似乎总是返回同一个SomeService
如果getService
只是一个字段的getter,那么最好直接使用该字段,而不是使用该方法。但是,确实不需要将此值传递给方法。如果将doMoreWork()
重构为以下内容:
private void doMoreWork(String a, Integer b) {
SomeService service = getService();
service.doingMoreWork(a, b);
}
然后,您使doMoreWork()
的功能依赖于getService()
。如果您想要使用不同的方法来获取SomeService
对象,您必须重构此代码。因此,出于这个原因,您可能希望继续使用原始实现
如果您使用的是Spring之类的框架,则可以将SomeService
注入到您的类中,如下所示:
@Autowired
private SomeService service;
// use the injected service here
private void doMoreWork(String a, Integer b) {
service.doingMoreWork(a, b);
}
public void doWork(String a, Integer b) {
..
..
for (Integer i : numbers) {
getService().doingMoreWork(a, b);
}
}
如果每次getService()
都返回一个新实例,但其名称应该是createNewService()
,那么将服务作为参数传递是有意义的
在当前场景中,getService()
似乎总是返回相同的实例,因此将服务作为参数传递并没有任何区别,反而会让读者感到困惑
进一步添加,getService()
是在同一个类中定义的,doMoreWork()
是一个私有方法,因此它总是引用同一个服务,而不是每次都添加一个额外的步骤来通过service
另一件事,如果所有的doMoreWork()
都是调用service.doingMoreWork(a,b)代码>除此之外,最好删除此方法并在循环中直接调用它,如下所示:
@Autowired
private SomeService service;
// use the injected service here
private void doMoreWork(String a, Integer b) {
service.doingMoreWork(a, b);
}
public void doWork(String a, Integer b) {
..
..
for (Integer i : numbers) {
getService().doingMoreWork(a, b);
}
}
我同意代码审查,getService()
应该在doMoreWork()
中
此外,我建议将服务作为类的依赖项,也就是说,服务可以是类的一个字段。一些DI框架可以为您注入服务,例如Spring框架
如果是这样,此.service
可以在类的每个方法中引用。这并不重要,因为:
doMoreWork()
标记为private
它是类的隐藏细节。
由于它不是public
它不是public
API或合同的一部分,因此它是一个可以更改的实现细节
所以签名是什么并不重要,你问题中给出的理由只是个人偏好
您永远不会在一个循环中创建一个新的JDBC连接,这将是非常低效的,即使有一个好的连接池,这样做也是错误的
所有这些都表明我会这样做。
private
方法是不需要的,只会增加混乱和意见
public void doWork(@Nonnull final String s, @Nonnull final Integer i)
{
final SomeService service = getService();
for (final Integer n : numbers)
{
service.doingMoreWork(s, i);
}
}
如果这是真正的代码,我会内联“doMoreWork”,我不明白为什么这里需要一个方法(它是1loc),我现在已经编辑了示例代码。doMoreWork()正在做更多的工作!我问这个问题是想知道这个建议背后的最佳实践,甚至是事实。这是我从书中找不到的东西,所以我把它贴在这里。我不确定它是否真的是“保持”的候选人。即使是回答也是合理的,而不仅仅是基于观点的。+1对我来说,这是最干净的解决方案——名义上的代码和最大的灵活性。doMoreWork方法不应该关心用于执行更多工作的服务。你可以用模块化的方式与DI.yeah交换服务,我们确实考虑了服务注入。但就我而言,我们不能这样做。一定是这样