【问题标题】:Grouping together "main" methods and their "helper" methods in Java在 Java 中将“主要”方法及其“辅助”方法组合在一起
【发布时间】:2013-10-17 13:52:05
【问题描述】:

避免大型、单一的方法被认为是一种很好的做法。我个人喜欢识别所有具有独特、明确目的的代码,并将它们重构为一种方法。这样,代码读起来更像一本书。

这种方法的明显问题是,我的课程最终会在其预期范围之外提供大量可用的方法,我认为这是非常不可取的。

有一些方法可以在 Java 中创建嵌套函数,但由于该语言不直接支持该功能,因此生成的代码通常丑陋得深不可测——至少对我来说是这样。

也可以使用嵌套类。我不喜欢这个解决方案的地方在于它有点笨拙——是吗?——当“组合在一起”中涉及的一些方法被覆盖时。

相当模糊的问题,但无论如何我想知道人们是如何做到这一点的。

编辑:我的意思的例子:

public class ClassWithTwoMainMethods {

    private int var1;
    private int var2;

    public void doSomething(int a) {
        if (conditionToCheck(a)) {
            doSomethingSpecific();
        }
    }

    private void doSomethingSpecific() {
        ...
    }

    private boolean conditionToCheck(int a) {
        ...
    }

    public void doSomethingElse(int a, int b) {
        doSomethingElseHelper1(a+b);
        doSomethingElseHelper2();
        doSomethingElseHelper3();
    }

    private void doSomethingElseHelper1(int arg) {
        ...
    }

    private void doSomethingElseHelper2() {
        ...
    }

    private void doSomethingElseHelper3() {
        ...
    }

}

乍一看,上面的类有一个“main”方法和两个不应该在其他地方使用的“helper”,以及另一个“main”方法和三个helper,这一点并不明显。

【问题讨论】:

  • 你应该更具体一点,我现在可以给你写大约 10 页好的 OOP 方法:)。
  • 为什么公共/私有范围不够?
  • 因为无法知道 conditionToCheck() 是 doSomething() 的助手还是 doSomethingElse() 的助手,因为两者都可以调用它。可以使用命名约定,但那是非常“C-ish”......最好只能从它们的“main”调用辅助方法。
  • 我的建议是使用任何药物治疗强迫症。确实,只要您的类足够短(最多 1000 行),并且您将相关方法放在一起,那么您无法在方法级别轻松设置细粒度访问这一事实并不是实际的可维护性/可读性问题。
  • 好吧,这让我笑了:D

标签: java coding-style refactoring


【解决方案1】:

我为此使用“工作对象”。工作对象仅存在于方法内部,有助于实现目标。一个典型的例子是String,除了这个worker非常有用以至于方法经常返回它。

所以我所做的是将方法分组到一个工作对象中,在一个公共 API 方法中创建它(即,应该在公共 API 中使用和记录某些东西)并让它完成它的事情:

public void doSomethingElse(int a, int b) {
    new Worker( a, b ).run();
}

这种方法有一些好处:

  1. 您可以单独测试这些工人。
  2. 它将属于一起的代码放在一起
  3. 它有助于避免混淆类的命名空间。不过,它确实在一定程度上污染了全局命名空间。
  4. 它允许您在不同的类中重用工人。
  5. 我可以减少对工人领域的限制。对于主类,我更喜欢不变的字段。在工人中,字段通常更像局部变量。这样,我可以减少方法参数的数量,但我需要编写更多的单元测试。

【讨论】:

  • 此外,您可以将这些“工作人员”创建为私有静态类或封装私有,然后避免全局命名空间污染(虽然失去了重用的可能性)。
  • @siledh:您可以将它们设为私有包,至少允许测试访问它们。或者您可以将它们标记为protected 以允许通过继承访问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 2018-02-26
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多