Objective-C中的对象层次结构

时间:2012-10-05 22:19:31

标签: iphone objective-c ios design-patterns inheritance

我已经了解了一个具有~50,000 LoC的Objective-C代码库,我估计25%左右是重复代码。不幸的是,在代码库中,OO原则在这一点上大多被忽略,有利于复制和粘贴逻辑。耶!

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

然而,在我开始创建一堆基类并在派生类之间共享通用逻辑之前,我想我应该停下来看看是否还有其他选项供我使用。从2011年开始观看Ken Kocienda的“易于改变代码编写”WWDC会议之后,他建议我尽可能保持对象层次结构的浅薄。他没有提供任何有关他为什么有这个意见的详细统计数据,所以我想知道我是否错过了某些东西。

我不是任何想象力的Objective-C专家,所以我想知道在决定对象层次时是否有任何最佳实践。基本上,我想知道你何时决定停止创建基类并开始使用组合而不是继承作为在类之间共享代码的方式。

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

2 个答案:

答案 0 :(得分:2)

我在coming to iOS from other backgrounds上写了一些想法,包括Java。由于ARC,有些事情发生了变化。特别是,内存管理不再是前沿和中心。也就是说,你过去所做的所有事情都是为了简化内存管理(使用访问器,使用访问器,使用访问器)在ARC中同样有效。

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

查看UITableView及其对委托和数据源的使用。看看像NSAttributedString这样的东西,它们是HAS-A NSString而不是IS-A。这很常见,通常可以保持清洁。与所有大对象层次结构一样,始终牢记LSP。当有人忘记a square is not a rectangle时,我看到许多ObjC设计横着走。同样,所有语言都是如此,但在设计时值得记住。

无论何时可以使用它们,不可变(值)对象都是真正的胜利。

你将很快发现的另一件作品是“极限”或“受保护”之类的“安全装饰”很少(有@protected,但实际上并没有那么有用,而且很少使用)。来自Java和C ++背景的人们倾向于担心编译器执行各种访问规则。 ObjC没有大多数保护的编译器强制执行(您总是可以在运行时向任何对象发送任何消息)。您只需使用一致的命名约定,不要去私有方法。程序员纪律取代了编译器执行。在实践中,它在绝大多数情况下都能正常工作。

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

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

答案 1 :(得分:0)

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

但我发现Objective-C中的构图很尴尬(虽然我不能确切地说明原因),所以没有“完美”的答案。

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

PS:我不得不重做一个包含大约55K行的应用程序,我们可以计算得很近。正如您所发现的,可能有大约25%的重复,但还有25%左右的完全死代码。 (值得庆幸的是,自那以后,该应用程序几乎被抛弃了。)