如何命名作为参数副本的变量?

Rol*_*and 12 java parameters naming-conventions

我有一个方法将处理Collection<Nodes>作为参数传入的方法.这Collection将被修改,因此我认为首先制作它的副本是好的.如何命名参数和局部变量,例如nodes在下面的示例中?

List<Nodes> process(Collection<Nodes> nodes) {
  List<Nodes> nodes2 = new ArrayList<>(nodes);
  ...
}
Run Code Online (Sandbox Code Playgroud)

作为另一个示例,请考虑以下内容,其中变量是intString参数解析的:

public void processUser(final String userId) {
  final int userId2 = Integer.parseInt(userId);
  ...
Run Code Online (Sandbox Code Playgroud)

acm*_*acm 5

名称变量问题的一个好方法是使用表示变量实际含义的名称.在您的示例中,您使用的名称没有说明方法功能或变量含义,这就是为什么很难选择名称的原因.

在JDK中有很多像你的案例,例如Arrays#copyOf:

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它们调用参数original和局部变量copy,该变量完美地表示返回的值是参数的副本.准确地说,复制就是这种方法的作用,并相应地命名.

使用相同的推理你的情况(考虑重构提供更多有意义的名称,以你的方法和变量),我会说出你的本地副本nodes类似processedNodes,表示该变量是什么,是你的方法的名称一致.

编辑:

您在编辑中添加的新方法的名称不提供有关它的功能的提示.我假设它修改了id通过参数传递的用户的某些属性(可能在数据库中).

如果是这种情况(或类似情况),我认为您可以采用的适当方法是每种方法都应该承担一项责任.根据您的方法名称,它应该处理用户,因为您需要一个int userId.解析an的责任String userId应该超出此方法的范围.

使用所提出的方法具有以下优点:

  • 如果您必须在输入中添加其他验证,则您的课程不会更改.

  • 您的班级将不负责处理NumberFormatException哪些必须是申请责任.

  • 你的processUser,如果你要处理不同类型的输入(例如方法不会改变float userId).


Mar*_*nna 5

它最终归结为您希望与未来程序员沟通的内容.电脑显然不在乎; 这是你正在与之交谈的其他人.因此,最大的因素将是那些人需要知道的:

  • 这个变量的逻辑(抽象,概念)含义是什么?
  • 如何使用这个变量可能让程序员感到困惑?
  • 这个变量最重要的是什么?

看看你的第一个例子,你真的很难理解你的程序真正选择一个好名字.该方法被调用process; 但是方法一般来说都是实现计算过程,所以这个名字实际上并没有告诉我什么.你在忙什么?这个过程是什么?你在为谁处理它,为什么?知道该方法的作用以及它所在的类将有助于通知您的变量名称.

让我们添加一些假设.假设您正在构建一个定位建筑物中Wi-Fi接入点的应用程序.该Node问题是一个无线节点,子类Repeater,AccessPointClient.我们还说它是一个在线处理的数据集,因此给定的节点集合可以随时更改,以响应后台线程接收当前可见的节点中的更新.您在方法的头部复制集合的原因是在本地处理期间将自己与这些更改隔离开来.最后,让我们假设您的方法是通过ping时间对节点进行排序(解释为什么该方法采用泛型Collection但返回更具体的List类型).

现在我们更好地了解您的系统,让我们使用这种理解来选择一些名称,将您系统的逻辑意图传达给未来的开发人员:

class NetworkScanner {
    List<Node> sortByPingTime(Collection<Node> networkNodes) {
        final ArrayList<Node> unsortedSnapshot;

        synchronized(networkNodes) {
            unsortedSnapshot = new ArrayList<>(networkNodes);
        }

        return Utils.sort(unsortedSnapshot, (x,y) -> x.ping < y.ping);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以方法是sortByPingTime定义它的作用; 该论点是networkNodes描述我们正在研究的节点类型.并且调用变量unsortedSnapshot来表达关于它的两件事,仅通过阅读代码就不可见:

  • 它是某种东西的快照(暗示原始的东西有些不稳定); 和
  • 它对我们没有任何重要的命令(建议它可能在我们完成之前).

我们可以放在nodes那里,但是从输入参数中可以立即看到它.我们也可以这样称呼,snapshotToSort但这一点在我们将其交给sort下面的例行程序中可见.

这个例子仍然有点人为.该方法实际上太短,变量名称无关紧要.在现实生活中,我可能只是称之为out,因为选择一个好名字所花费的时间比任何人都要花费更长时间来弄清楚这种方法是如何工作的.

其他相关说明:

  • 命名本质上有点主观.我的名字永远不会适用于每个人,特别是考虑到多种人类语言时.
  • 我发现最好的名字通常都没有名字.如果我能做出匿名的东西,我会 - 这样可以最大限度地减少变量被重用的风险,并减少IDE"查找"框中的符号.一般来说,这也促使我编写更紧凑,功能更强大的代码,我认为这是一件好事.
  • 有些人喜欢在名称中包含变量的类型; 我总是发现有点奇怪,因为类型通常很明显,如果我错了,编译器通常会抓住我.
  • "保持简单"在这里充满力量,无处不在.大多数情况下,您的变量名称不会帮助某人避免将来的工作.我的经验法则是,将它命名为愚蠢的东西,如果我最终想知道什么意思,请选择那个场合来命名它.