可测试Java代码:使用带构造函数的模型bean

可测试Java代码:使用带构造函数的模型bean,java,constructor,testability,constructor-injection,Java,Constructor,Testability,Constructor Injection,据Misko Hevery说,他有一个可测试性博客。开发人员应该避免使用“holder”、“context”和“kitchen-sink”对象(这些对象包含各种各样的其他对象,是协作者的抓包)。作为参数传入所需的特定对象,而不是该对象的持有者 在示例中,这是代码气味吗?我应该只传递所需的参数还是传递带有所需数据的模型/bean 例如,你会这样做吗:注意。我可能已经将数据作为构造函数参数传递了。这是代码气味吗 public Parser { private final SourceCodeBe

据Misko Hevery说,他有一个可测试性博客。开发人员应该避免使用“holder”、“context”和“kitchen-sink”对象(这些对象包含各种各样的其他对象,是协作者的抓包)。作为参数传入所需的特定对象,而不是该对象的持有者

在示例中,这是代码气味吗?我应该只传递所需的参数还是传递带有所需数据的模型/bean

例如,你会这样做吗:注意。我可能已经将数据作为构造函数参数传递了。这是代码气味吗

public Parser {
  private final SourceCodeBean source;

  public Parser(final SourceCodeBean s) {
    this.source = s;
  }

  public void parse() {
     // Only access the source field
     this.source.getFilename();
     ...
     ... assume that the classes uses fields from this.source
     ...
  }

}

public SourceCodeBean {
   private String filename;
   private String developer;
   private String lines;
   private String format;

   ...
   ...
   <ONLY SETTERS AND GETTERS>
   ...
}

...

Or 

public Parser {


  public Parser(String filename, String developer, String lines ...) {
    ...
  }

}

And building a test case

public void test() {
  SourceCodeBean bean = new SourceCodeBean():
  bean.setFilename();

  new Parser().parse();
}
公共解析器{
私有最终SourceCodeBean源;
公共解析器(最终SourceCodeBean s){
this.source=s;
}
公共空解析(){
//仅访问源字段
this.source.getFilename();
...
…假定类使用此.source中的字段
...
}
}
公共源代码bean{
私有字符串文件名;
私人字符串开发人员;
专用字符串线;
私有字符串格式;
...
...
...
}
...
或
公共解析器{
公共解析器(字符串文件名、字符串开发人员、字符串行…){
...
}
}
以及构建一个测试用例
公开无效测试(){
SourceCodeBean=新的SourceCodeBean():
setFilename();
新建解析器().parse();
}

另一个问题:在编写可测试代码时,您是否倾向于编写太多的类。有太多的类或者一个类有太多的方法是错误的吗。这些类很有用,并且只有一个用途。但是,我可以看到在哪里可以将它们重构为一个更大的类……但该类有多种用途。

您还将注意到,Misko Hevery建议在参数计数增加时或在逻辑上可以接受的情况下,将参数分组到类中


因此,在您的情况下,您可以毫无悔意地传递
SourceCodeBean

您还会注意到,Misko Hevery建议在参数计数增加时或在逻辑上可以接受的情况下,将参数分组到类中


因此,在您的情况下,您可以毫无悔意地通过
SourceCodeBean

您提出的许多问题都是非常主观的,如果不了解您试图完成的全部内容,很难提出有用的建议,但这是我的2美分

我同意你的后一种设计。创建一个名为SourceCodeParser的类,让构造函数接受文件名、开发人员等,并让它有一个解析方法。这样,对象负责解析自身

通常,如果参数不是太多,我更喜欢将参数传递给构造函数。代码完成建议最多7个参数。如果您发现构造函数参数的数量很麻烦,您可以始终使用前面提到的SourceCodeParser类创建setter


如果您想要一种方法来建立不同的解析行为,我建议在SourceCodeParser内部使用解析器委托,并将其作为构造函数参数或setter传入。

您提出的许多问题都是非常主观的,如果你不知道你想要完成什么,很难提出有用的建议,但这是我的2美分

我同意你的后一种设计。创建一个名为SourceCodeParser的类,让构造函数接受文件名、开发人员等,并让它有一个解析方法。这样,对象负责解析自身

通常,如果参数不是太多,我更喜欢将参数传递给构造函数。代码完成建议最多7个参数。如果您发现构造函数参数的数量很麻烦,您可以始终使用前面提到的SourceCodeParser类创建setter


如果您想要一种建立不同解析行为的方法,我建议在SourceCodeParser内部使用解析器委托,并将其作为构造函数参数或setter传入。

如果您有一个类的唯一目的是将各种信息关联在一起,那么,我看不出有什么理由不应该将该类直接用作参数。原因是类的编码就是为了实现这一点,那么为什么不让它完成它的工作呢?所以我肯定更喜欢前者

现在,这是假设
解析器
实际上需要在
SourceCodeBean
中语义表示的信息。如果
解析器实际需要的只是一个文件名,那么它应该只接受文件名,我更喜欢第二种方法


我想唯一让我担心的是
SourceCodeBean
成为一种信息的“厨房水槽”。例如,filename和format字段在这里非常有意义。但是你真的需要开发者和产品线吗?是否可以将它们放在某种关联的元数据信息类中?

如果有一个类的唯一目的是将各种信息关联在一起,那么我认为没有理由不将该类直接用作参数。原因是类的编码就是为了实现这一点,那么为什么不让它完成它的工作呢?所以我肯定更喜欢前者

现在,这是假设
解析器
实际上需要在
SourceCodeBean
中语义表示的信息。如果
解析器实际需要的只是一个文件名,那么它应该只接受文件名,我更喜欢第二种方法


我想唯一让我担心的是
SourceCodeBean
成为一种信息的“厨房水槽”。例如,filename和format字段在这里非常有意义。但是你真的需要开发者和产品线吗?是否可以将它们放在某种关联的元数据信息类中?

为什么第二个解析器需要
devel