我有一个方法ProductService
的界面findByCriteria
。此方法有一长串可空参数,例如productName
,maxCost
,minCost
,producer
等等。
我通过引入Parameter Object重构了这个方法。我创建了类SearchCriteria
,现在方法签名如下所示:
findByCriteria (SearchCriteria criteria)
我认为SearchCriteria
的实例仅由方法调用者创建,并且仅在findByCriteria
方法中使用,即:
void processRequest() {
SearchCriteria criteria = new SearchCriteria ()
.withMaxCost (maxCost)
.......
.withProducer (producer);
List<Product> products = productService.findByCriteria (criteria);
....
}
和
List<Product> findByCriteria(SearchCriteria criteria) {
return doSmthAndReturnResult(criteria.getMaxCost(), criteria.getProducer());
}
所以我不想为SearchCriteria
创建一个单独的公共类,并将其放在ProductServiceInterface
内:
public interface ProductService {
List<Product> findByCriteria (SearchCriteria criteria);
static class SearchCriteria {
...
}
}
这个界面有什么不好的吗?你在哪里放置SearchCriteria
课程?
答案 0 :(得分:3)
我觉得它很好看。它清楚地表明SearchCriteria
专门用于ProductService
。
答案 1 :(得分:2)
它还不错,如果你想在接口和一些实用程序对象(如比较器)之间进行更紧密的分组,它会很有用。 (我对接口完全一样,内部类提供了比较接口实例的有用比较器。)
客户端使用它可能有点尴尬,因为它们必须在内部类名称前加上接口名称(或使用静态导入),但是一个好的IDE会为你处理这个问题(但是代码可以是充满Interface.SomeClass
声明,看起来不太好。)
但是,在特定情况下,SearchCriteria
看起来并没有如此紧密地耦合到接口,因此它可能更适用于常规包类。
答案 2 :(得分:2)
当你有可能需要更多或更少可空参数的方法时,我鼓励你使用类;它使您能够提供所需的任何内容,而无需调用如下方法:
someMethod("foo", null, null, null, null, null, null, ..., "bar");
使用这种机制,方法调用类似于:
someMethod(new ObjParam().setFoo("foo").setBar("bar"));
第二种方法是可消耗的和可重复使用的(没有大量的方法覆盖)。我不是在这里说方法覆盖是坏的!恰恰相反。但是有了许多可选参数,我宁愿第二次调用。
至于内部课程,它们有时很有用,但我个人遵循这些指导原则:
请记住,无论是否内部类,Java编译器将为每个类创建一个.class。您使用它们的次数越多,代码的可读性就越低。这取决于你决定他们是否合理......
答案 3 :(得分:0)
我担心我会投票给坏人。无论如何,相当糟糕,你可以做更糟糕的事情......
为简单起见,课程应仅针对一项责任。您的ProductService实现中有一个条件类定义,因此当您浏览代码时,您必须知道您所在文件的哪个部分。
更重要的是,分离使得涉及的实体的代码更简单,更明确。对我来说,这会覆盖所有其他问题(啊,除了代码当然是正确的)。我觉得简单&amp;在保留我的头发方面,或者至少是那些会保留头发的人,这种言论是最有帮助的...