Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中静态Util类和方法的替代方案_Java_Oop - Fatal编程技术网

Java中静态Util类和方法的替代方案

Java中静态Util类和方法的替代方案,java,oop,Java,Oop,比如说,我想有一个方法,它接受一个集合,并根据某种逻辑将集合格式化为字符串。例如 public String formatCustomerSet(final Set<Customer> customers) { String result = ""; for (Customer customer : customers) { result += customer.getFirstName() + " : " + customer.getLastName

比如说,我想有一个方法,它接受一个集合,并根据某种逻辑将集合格式化为字符串。例如

public String formatCustomerSet(final Set<Customer> customers) {
    String result = "";
    for (Customer customer : customers) {
        result += customer.getFirstName() + " : " + customer.getLastName() + "\n";
    }

    return result;
}
公共字符串格式CustomerSet(最终设置客户){
字符串结果=”;
用于(客户:客户){
结果+=customer.getFirstName()+“:“+customer.getLastName()+”\n”;
}
返回结果;
}

我在几个类中使用这段代码。现在,我应该把这个放在哪里?我发现应该避免使用实用程序类,而不应该使用它?

那么,应该是使用特定名称的Util类,比如CustomerMatter,还是我们应该从中创建一个OOP类?推荐哪一种?为什么


我在几个类中使用这段代码。现在,我应该把这个放在哪里?我发现应该避免使用实用程序类,而不应该使用它?


那么,应该是使用特定名称的Util类,比如CustomerMatter,还是我们应该从中创建一个OOP类?推荐哪一种以及原因?

使用Java streams,您实际上可以通过以下一行代码获得所需内容(假设
客户
类中有一个好的
toString()
):

放置它的一个好地方可能是
Customer
类本身。但我会开始使用它,只有在收集了一些关于用例的信息之后,我才会考虑将它重构成一个独立的类。 Edit(回答评论):是的,我会首先在
Customer
类中创建一个静态方法,因为它实际上不使用该类中的任何字段


< >编辑2(注释):顺便说一下,如果您想使用您的问题中的方法,考虑使用<代码> StringBuilder <代码>,而不是<代码> String < /C> >

< P>,在大多数情况下,最好将行为直接添加到已经存在的类中作为非静态方法。如果您真的想重用它,最好创建一个具有所需行为的新类,但作为一个常规类,它需要实例化并可以子类化

实用/静态类的缺点: 主要问题是依赖于实用程序类的静态方法的类具有紧密耦合

  • 测试有点困难:因为您对Util类有一个硬依赖,所以无法轻松提供模拟实现
  • 控制反转:当使用实用程序类时,依赖项注入是不可能的
  • 代理:许多框架依赖于动态代理向类实例(例如日志记录级别)添加附加功能,这在实用程序类中是不可能的
  • 单一责任:随着时间的推移,如果您不是很严格,这些类往往会积累越来越多的代码,这可能与原始方法没有太大关系。该类将失去其原有的单一责任

  • 参考:

    我不同意应该避免使用util类这一事实。拥有一个包含纯实用程序的静态方法的类是非常好的。有时函数或操作应该只是函数或操作。并不总是需要将它们与某种抽象对象类型或任何东西关联起来

    但是,我同意的是,在创建util类时,应该严格定义该类将提供哪些类型的实用程序。如果您有一组与数学运算相关的静态方法,那么可以创建一个util类
    ExtendedMath
    。如果你在做大量的数学作业,而课堂变得过于肥胖,那么试着进一步完善它。按数学类型对它们进行分组,如
    代数
    向量

    最后,它主要只是试图运用常识。函数作为对象的一部分有意义吗,或者它只是一个任意操作

    在您的情况下,您必须问自己这样一个问题:“是否要创建代码对
    formatCustomerSet
    实现的硬依赖关系?”。如果您100%确信您将始终以完全相同的方式格式化客户集,并且您永远不会需要不同的格式化程序,那么使用静态方法可能是可以的。如果不是,那么最好将其作为非静态函数放到
    CustomerSetFormatter
    类中

    我不能给你一个肯定或否定的答案,因为你必须自己权衡赞成者和反对者。只需考虑以下几点:

    • 引用静态方法时,您正在创建对该静态方法的硬依赖关系。有时这是好的,有时不是。软件开发的核心原则是重用。您能否在其他上下文中重用调用静态函数的代码?还是静态函数过于特定于上下文
    • 编程中的另一个核心原则是依赖注入。假设您有
      A类
      ,它需要客户格式化程序。您可以做的是创建一个
      界面CustomerMatter
      。然后在
      类A
      中定义构造函数:
      A(CustomerFormatter格式化程序)
      。这允许您在使用不同的
      CustomerMatter
      实现时重用
      Class A
      。这大大提高了类A的可重用性。当使用静态函数时,这不再可能
    • 常见的泛型操作(例如
      Math
      中定义的函数,例如
      min()
      max()
      ceil()
      floor()
      )完全保证为静态函数。他们只做一件常用的事情。通常,您可以将这样的函数作为一个例子,来说明静态方法是完全正确的
    • 你的函数是纯函数吗?这是一个函数,它总是为任何唯一的对象提供完全相同的输出
      String result = 
          customers.stream().map(Customer::toString).collect(Collectors.joining("\n"));