4

我被介绍到一个 Objective-C 代码库,它有大约 50,000 个 LoC,我估计 25% 左右是重复代码。不幸的是,到目前为止,代码库中的 OO 原则大多被忽略,而倾向于复制和粘贴逻辑。耶!

我来自 Java 背景,很多这种重复可以通过老式的面向目标的编程来修复。在很多情况下,将共享逻辑提取到基类中感觉像是正确的解决方案。

然而,在我着手创建一堆基类并在派生类之间共享公共逻辑之前,我想我应该停下来看看是否还有其他可用的选项。从 2011 年开始观看 Ken Kocienda 的“Writing Easy-To-Change Code”WWDC 会议后,他建议我尽可能保持对象层次结构的浅层。他没有提供任何关于他为什么有这种观点的确切统计数据,所以我想知道我是否错过了一些东西。

无论如何,我都不是Objective-C专家,所以我想知道在决定对象层次结构时是否有任何最佳实践。基本上,当您决定停止创建基类并开始使用组合而不是继承作为在类之间共享代码的一种方式时,我想获得意见。

此外,从运行时性能的角度来看,有什么可以让我远离创建对象层次结构吗?

4

2 回答 2

2

不久前,我写了一些关于从其他背景(包括 Java)进入 iOS 的想法。由于ARC,有些事情发生了变化。特别是,内存管理不再那么重要。也就是说,您过去为简化内存管理所做的所有事情(使用访问器、使用访问器、使用访问器)在 ARC 中仍然同样有效。

@Radu 是完全正确的,你应该经常保持你的类层次结构相当简单和浅薄(如你所读)。在 Cocoa 中,组合通常是比扩展子类化更好的方法(这在 Java 中可能也是如此,但在 ObjC 中是常见的做法)。ObjC 也没有抽象方法或类的概念,这使得某些类型的子类化有点尴尬。与其将共享逻辑提取到基类(尤其是抽象基类)中,不如将它们提取到单独的策略对象中。

查看UITableView委托和数据源及其使用。看看像NSAttributedStringwhich HAS-ANSString而不是 IS-A 之类的东西。这很常见,并且经常使事情变得更清洁。与所有大型对象层次结构一样,始终牢记LSP。当有人忘记正方形不是矩形时,我看到很多 ObjC 设计偏向一边。同样,这适用于所有语言,但在设计时值得记住。

只要您可以使用不可变(值)对象,它们就是真正的胜利。

您会很快发现的另一部分是很少有像“final”或“protected”这样的“安全装饰”(有一个@protected,但实际上在实践中并没有那么有用并且很少使用)。具有 Java 和 C++ 背景的人往往会担心编译器对各种访问规则的强制执行。ObjC 没有编译器强制执行大多数保护(您始终可以在运行时向任何对象发送您想要的任何消息)。您只需使用一致的命名约定,不要到处寻找私有方法。程序员纪律取代了编译器的强制执行。在实践中,它在绝大多数情况下都能正常工作。

也就是说,ObjC 有很多警告,您绝对必须消除所有警告。大多数 ObjC 警告实际上是错误。

我偏离了对象层次结构的具体问题,但希望它是有用的。

于 2012-10-13T03:50:30.053 回答
0

Objective-C 中深层层次结构的一个主要问题是 Xcode 根本无法帮助您理解/管理它们。另一个原因很简单,Objective-C 中的任何东西都比 Java 中的东西复杂两倍,所以你需要更加努力地保持简单。

但是我发现 Objective-C 中的组合很尴尬(虽然我不能确切地说出为什么),所以没有“完美”的答案。

我观察到,在 Objective-C 与 Java 中,小的子例程要少得多,而且更有可能看到代码在大部分相同的视图控制器等之间重复。我认为其中很大一部分只是开发工具和创建新类的相对尴尬。

PS:我不得不重新设计一个包含大约 55K 行的应用程序,我们可以数得差不多了。正如您所发现的,可能有大约 25% 的重复,但还有另外 25% 左右的完全死代码。(谢天谢地,从那以后,该应用程序几乎被遗弃了。)

于 2012-10-13T04:33:03.177 回答