【问题标题】:Objective-C class naming convention vs Uncle BobObjective-C 类命名约定 vs Uncle Bob
【发布时间】:2012-03-06 13:06:38
【问题描述】:

Chapter 2: Meaningful Names鲍勃叔叔写道:

不要添加无端上下文

在一个名为“Gas Station Deluxe”的虚构应用程序中,最好在每个类前面加上 GDS。坦率地说,你正在反对你的工具。您输入G 并按完成键,您将获得系统中每个课程的一英里长列表

实际上,一年多以前,我在使用 Objective-C 的第一天就发现了这一点。在 Java 之后它非常令人失望,但我认为我只是一个对此感到恼火的人:) 据我所知,“清洁代码”一书大部分时间都是指 Java,而 Java 具有与 Objective-C 不同的命名空间(包)。

如果您正在构建应用程序而不是库,您是否在课程中使用 2-3 个字母前缀? 您认为是糟糕的语言设计、语言“功能”还是 Bob 大叔不在?

【问题讨论】:

标签: objective-c coding-style


【解决方案1】:

也许这里的关键词是免费的。在 Objective-C 中,前缀的重要作用是减少名称冲突的机会。在 Java 和 C++ 等其他语言中,对命名空间的支持使得前缀的使用变得毫无意义(并且违反了经常引用的 DRY 原则)。然而,在 Objective-C 中,前缀是有意义的、有用的,并且不是无偿的。

【讨论】:

  • 谢谢。我了解为什么类前缀包含在语言编码约定中。但是我认为命名空间是更好的解决方案,而且很现代的语言没有它们有点奇怪。
  • @OgreSwamp 关于 Objective-C 需要记住的两件事是,它与 C++ 一样古老(两者都出现在 1983 年),并且在许多情况下,它避开了特性和复杂性,并用约定和风格代替了它们。也许命名空间非常有用,并且会对语言进行如此改进,以至于将它们作为语言特性引入是值得的。 (我不这么认为。)无论如何,我的目的不是解释前缀,而是指出该指南并不意味着前缀不好,只是如果前缀没有用处,前缀是不好的。
【解决方案2】:

我很想结束这个问题,但我认为我之前没有见过类似的问题,这是一个有效的问题。以下是我对此事的相当混乱的想法。

许多语言都有一个名为 namespaces 的功能,其中“完全限定”的类名以一系列分层名称作为前缀。例如,Java 中的String 类正确地是java.lang.String,而自定义类正确地是com.whatever.foobar.MyClass

不幸的是,命名空间从未添加到 Objective-C,这意味着即使在使用 Objective-C++(其中具有函数、常量、结构等的命名空间功能。)

因此,在共享代码中防止符号冲突的唯一解决方案是使用某种形式的名称修饰来使您的符号名称唯一。在 Objective-C 中,约定是为所有类使用两个字符的前缀(有时数字会有所不同)。

这位 Bob 大叔的家伙告诉你不要这样做,因为虽然你最终会得到一个无法编译的程序,但你会失去前缀仍然提供的命名空间的任何好处。您的应用程序使用插件吗?你需要前缀。您的应用程序是否有公共 API?你需要前缀。

理论上,从不接触外部世界的单个应用程序中的代码可以不用前缀,但要搞砸了——保持编码干净,甚至在那里添加前缀。以后会省心的。

【讨论】:

    【解决方案3】:

    就我个人而言,我几乎从不使用前缀。唯一的例外是类以某种方式相互连接,或者它们都应该存在。

    一个例子:

    一些用于聊天的客户端应用程序。让我们将该聊天称为ExampleChat

    然后我会使用ECMessageECUserECRoom 等来轻松查看应该有哪些类。

    或者,如果我为UITableView 制作一些自定义单元格,我会使用前缀使它们彼此靠近,而不是在“一英里长的列表”中搜索它们。示例:

    ECTextMessageCellECSoundMessageCellECUploadMessageCellECJoinOrLeaveMessageCell

    这是我个人的看法,不可能是最好的。但这对我来说仍然是最简单的。

    希望对你有帮助

    【讨论】:

    • 我会将所有这些类放在语言允许的ExampleChat 命名空间或子命名空间中。前缀只有在命名空间不是一个选项时才有用(这就是我们正在讨论的内容。)
    • 如果像 Objective-c 这样的语言没有包/命名空间或一些类似的概念可用于构建源代码,我会支持你。
    • 那是 Clean Code 中描述的确切情况,它被认为是不好的做法。我非常同意鲍勃叔叔的观点,但我认为这是语言语法的错误(类没有命名空间)
    • 这是语言的问题,但 Bob 叔叔告诉读者不要使用标准的解决方法(前缀)是错误的。
    • 我不会说他错了。他没有告诉不要使用它们。他说这是不好的命名约定。在这里我会同意他的看法。但在 Objective-C 中,我们将其作为标准命名约定,我们不得不使用它。
    【解决方案4】:

    如果您没有命名空间,则可能会发生名称冲突。您可以在许多 C 库中看到它们使用某种前缀。所以我想有很好的理由有这些前缀和其他不使用它的理由。但是,将完成修改为忽略输入三个字母而不是一个字母的前缀应该是什么大问题。

    所以最后在我看来,这是一个品味问题。我想拥有带有前缀的良好结构类而不是一堆没有前缀的类会更重要......

    恕我直言,这与糟糕的语言设计无关。曾经有一段时间,软件并非无处不在,为什么要在命名空间上浪费额外的精力?正如我们所看到的那样,即使在当今使用没有命名空间的语言......

    【讨论】:

    • Objecive-C 3.0 大约 1 岁左右。他们有机会解决命名空间的问题,所以关于旧时代的争论在这里不起作用,恕我直言
    • 不熟悉“Objective-C 3.0”。你能提供一个链接吗?
    • 对不起,打错字了,2.0。而我犯了一个年龄的错误。大约是 5 年前。无论如何,它不会太旧,对吧? :)
    【解决方案5】:

    我想说,世界不是非黑即白的。我在 java 中使用包进行编程,是的,在每个类中都有一个前缀很烦人,而且用 I 启动接口也很烦人且有争议(就像 .Net 过去那样)。

    有时它在 Objective-c 中确实让我很烦,但是如果你的语言没有包,它有一些合法性,因为你可以“构建”人工类组,如“NS”、“UI”、“MK”和在 objc 和 cocoa 中以此类推。

    【讨论】:

    • 但这是语言错误。此外,我在 com.example.Message 中与 EXMessage 发生名称冲突的可能性要高出百万倍。
    • 我不确定我们是否可以将其标记为故障,而是将其标记为功能或限制。缺少对象和命名空间是 C 语言中的错误吗?我宁愿说这是语言特征的一部分。如果我们认为语言是一种工具,那么它们中的每一个都有自己的使用方式。有些做法在其中一种方法中是有效的,甚至是可取的,但在另一种方法中绝对不行。
    【解决方案6】:

    除了避免冲突之外,名称前缀的好处之一是您可以立即知道您真正处理的是什么类型。假设您有以下代码:

    Color c = ...;
    MultiValueMap m = ...;
    

    粗略浏览一下代码,根据您使用的库,这些类型可能来自许多不同的来源。您可能必须查找哪个包含/导入语句才能了解该类型可以做什么(例如,您想修改它,但它缺少您确定存在的方法)。

    在 iOS 世界中,您会立即知道它是 UIColor 还是 CGColor 并立即获得上下文。

    过去,在 WWDC 上,Apple 会举办一次会议,解释 Cocoa/Objective-C 编码约定。我相信他们提到了名称前缀的这一方面,因此您可能想找到其中一个可用的录音。由于各种原因,其他 C 开发人员(例如 Linux 内核开发人员)似乎也不重视 C++ 命名空间(以及其他 C++ 特性)。

    【讨论】:

    • 谢谢布莱恩特。但我认为在标准框架中使用 UIColor 和 CGColor 是“糟糕”设计的另一个例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多