Java 静态方法中的重复代码

Java 静态方法中的重复代码,java,code-duplication,Java,Code Duplication,我有两个用JAVA实现的阅读器。见下文: public final class ReaderA { public ReaderA() {} public static int read(final File file) { final byte[] data = Files.readAllbytes(file.toPath()); return read(data); } public static int read(final byte[] data) {

我有两个用JAVA实现的阅读器。见下文:

public final class ReaderA {
  public ReaderA() {}

  public static int read(final File file) {
    final byte[] data = Files.readAllbytes(file.toPath());
    return read(data);
  }

  public static int read(final byte[] data) {
    // do somethingA
  }

  ...// and some other methods
}


public final class ReaderB {
  public ReaderB() {}

  // this method is exactly the same as in ReaderA
  public static int read(final File file) {
    final byte[] data = Files.readAllbytes(file.toPath());
    return read(data);
  }

  // this is implemented different from the one in ReaderA
  public static int read(final byte[] data) {
    // do somethingB
  }

  ...// and the same other methods as in ReaderA
}
问题。避免重复代码的最佳方法是什么


我试图在一个新的抽象类
Reader
中提取一个重复的代码,并试图使
读取(最终字节[]数据)
抽象并在子类
ReaderA
ReaderB
中实现它。因为这些方法是静态的,所以它不起作用。

我认为有几个问题你需要先问自己:

  • 我真的需要两个静态方法吗
  • “方法”或类的共同代码是什么
  • 制作一个抽象类来编写这样的实现,并让ReaderA和ReaderB对其进行扩展,是否会减少重复代码
  • 您是否应该拥有一个父类,然后创建从上面继承的类

  • 我认为你应该阅读坚实的原则,特别是开放/封闭原则和依赖倒置

    我认为你首先需要问自己几个问题:

  • 我真的需要两个静态方法吗
  • “方法”或类的共同代码是什么
  • 制作一个抽象类来编写这样的实现,并让ReaderA和ReaderB对其进行扩展,是否会减少重复代码
  • 您是否应该拥有一个父类,然后创建从上面继承的类

  • 我认为您应该阅读SOLID原则,特别是开/闭原则和依赖项反转

    如果您使用的是JavaSE8,您可以将静态方法放在接口中。Java接口静态方法与默认方法类似,只是我们不能在实现类中重写它们。此功能有助于我们避免在实现类中实现不佳时出现不希望出现的结果。

    如果您使用的是Java SE 8,则可以将静态方法放在接口中。Java接口静态方法与默认方法类似,只是我们不能在实现类中重写它们。此功能有助于我们避免在实现类中实现差时出现不希望出现的结果。

    有一些可能性:

  • 从其中一个类中删除该方法并使用继承(不能为静态方法调用super.myMethod(),但除非重写它,否则它会工作)
  • 我建议您不要这样做:您可能会在子类中获得其他可用的方法,但您可能不想这样做

  • 将它提取到两个类的公共超类

  • 从一个类调用另一个类的方法。如果它们都保持相同的功能,这将起作用


  • 有一些可能性:

  • 从其中一个类中删除该方法并使用继承(不能为静态方法调用super.myMethod(),但除非重写它,否则它会工作)
  • 我建议您不要这样做:您可能会在子类中获得其他可用的方法,但您可能不想这样做

  • 将它提取到两个类的公共超类

  • 从一个类调用另一个类的方法。如果它们都保持相同的功能,这将起作用


  • 我不确定用静态方法保持这个实现是您能做的最好的,但是如果是这样,您可以添加一个
    函数
    参数

    public class Reader {
    
        public static int read(final File file, Function<byte[], Integer> reader) {
            final byte[] data = Files.readAllbytes(file.toPath());
            return reader.apply(data);
        }
    
    }
    

    自从Java 8中引入和以来,几乎没有任何无法避免的重复代码部分。

    我不确定使用静态方法保持此实现是否是最好的方法,但如果是这样,可以添加一个
    函数
    参数

    public class Reader {
    
        public static int read(final File file, Function<byte[], Integer> reader) {
            final byte[] data = Files.readAllbytes(file.toPath());
            return reader.apply(data);
        }
    
    }
    

    自从Java 8中引入和以来,几乎没有任何无法避免的重复代码部分。

    除非从
    读取(字节[])中删除
    静态
    修饰符并创建实例,否则将无法使用继承来帮助您

    静态
    方法的行为与实例方法不同,不能被覆盖。相反,超类和子类都将有单独的方法,这些方法需要用类名限定。拉起
    read(File)
    意味着它总是调用超类的
    read(byte[])
    。您仍然需要将
    read(File)
    复制到每个子类,使其使用该类自己的
    read(byte[])
    。中的代码也显示了这一点

    请阅读此问题及其答案以供参考:

    举例说明:您使用的两种
    读取(文件)
    方法与您在代码片段中所说的不同。它们并不都调用
    this.read(data)
    ,而是分别调用
    ReaderA.read(data)
    ReaderB.read(data)
    。查看
    read(byte[])
    调用如何调用两个完全不同的、不可重写的方法


    如果你能做到这一点,我建议你以一种不那么静态的方式重新编写读者:

    interface Reader
    {
        default int read(File file)
        {
            final byte[] data = Files.readAllbytes(file.toPath());
            return read(data);
        }
    
        int read(byte[] data);
    }
    
    class ReaderA
        implements Reader
    {
        int read(byte[] data)
        {
            // do somethingA
        }
    }
    
    class ReaderB
        implements Reader
    {
        int read(byte[] data)
        {
            // do somethingB
        }
    }
    

    请注意,
    read(File)
    现在对于所有实现类都是一样的。当然,您必须将方法的调用方式从
    ReaderX.read()
    更改为
    new ReaderX().read()

    ,除非您从
    read(byte[])
    中删除
    静态
    修饰符并创建实例,否则您将无法使用继承来帮助您

    静态
    方法的行为与实例方法不同,不能被覆盖。相反,超类和子类都将有单独的方法,这些方法需要用类名限定。拉起
    read(File)
    意味着它总是调用超类的
    read(byte[])
    。您仍然需要将
    read(File)
    复制到每个子类,使其使用该类自己的
    read(byte[])
    。中的代码也显示了这一点

    请阅读此问题及其答案以供参考:

    举例说明:您使用的两种
    读取(文件)
    方法与您在代码片段中所说的不同。他们