在java中声明嵌套类在接口内部有什么不好吗?

时间:2010-05-24 10:28:50

标签: java oop

我有一个方法ProductService的界面findByCriteria。此方法有一长串可空参数,例如productNamemaxCostminCostproducer等等。

我通过引入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课程?

4 个答案:

答案 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"));

第二种方法是可消耗的和可重复使用的(没有大量的方法覆盖)。我不是在这里说方法覆盖是坏的!恰恰相反。但是有了许多可选参数,我宁愿第二次调用。

至于内部课程,它们有时很有用,但我个人遵循这些指导原则:

  1. 只有在内部类应该是私有的时才尝试使用内部类(例如:在自定义LinkedList实现的情况下,Node类是私有类,因此是内部类。)
  2. 通常只有当类不可重用并且主要在一个(非常)小的类组中使用时才会使它成为内部类
  3. “父母”和内心阶级变得足够大;然后这两个类都有自己的Java源文件以便于阅读,除非内部类应该是第一个点的私有。
  4. 请记住,无论是否内部类,Java编译器为每个类创建一个.class。您使用它们的次数越多,代码的可读性就越低。这取决于你决定他们是否合理......

答案 3 :(得分:0)

我担心我会投票给坏人。无论如何,相当糟糕,你可以做更糟糕的事情......

为简单起见,课程应仅针对一项责任。您的ProductService实现中有一个条件类定义,因此当您浏览代码时,您必须知道您所在文件的哪个部分。

更重要的是,分离使得涉及的实体的代码更简单,更明确。对我来说,这会覆盖所有其他问题(啊,除了代码当然是正确的)。我觉得简单&amp;在保留我的头发方面,或者至少是那些会保留头发的人,这种言论是最有帮助的...