简体   繁体   English

Objective-C中的对象层次结构

[英]Object hierarchies in Objective-C

I've been introduced to an Objective-C codebase which has ~50,000 LoC and I'd estimate that 25% or so is duplicate code. 我已经被介绍到具有〜50,000 LoC的Objective-C代码库,并且我估计25%左右是重复代码。 Unfortunately, OO principles have been mostly ignored up to this point in the codebase in favor of copy and pasting logic. 不幸的是,到目前为止,在代码库中,面向对象的原理一直被忽略,而采用了复制和粘贴逻辑。 Yay! 好极了!

I'm coming from a Java background and a lot of this duplication is fixable with good old-fashioned objective oriented programming. 我来自Java背景,许多此类重复可以通过良好的老式面向对象编程来解决。 Extracting shared logic into a base class feels like the correct solution in a lot of cases. 在很多情况下,将共享逻辑提取到基类中似乎是正确的解决方案。

However, before I embark on creating a bunch of base classes and sharing common logic between derived classes, I thought I should stop and see if there are any other options available to me. 但是,在我开始创建一堆基类并在派生类之间共享通用逻辑之前,我认为我应该停下来看看是否有其他可用的选择。 After watching Ken Kocienda's 'Writing Easy-To-Change Code' WWDC session from 2011, he's advising me to keep object hierarchies as shallow as possible. 在观看了Ken Kocienda从2011年开始的WWDC的“编写易于更改的代码”会议之后,他建议我将对象层次结构保持尽可能浅。 He doesn't offer up any hard statistics as to why he has this opinion, so I'm wondering whether I'm missing out on something. 他没有就他为什么有这种观点提供任何确切的统计数据,所以我想知道我是否错过了某些东西。

I'm not an Objective-C expert by any stretch of the imagination, so I'm wondering if there's any best practices when deciding on an object hierarchy. 凭空想象,我不是Objective-C专家,所以我想知道在确定对象层次结构时是否有最佳实践。 Basically, I'd like to get opinions on when you decide to stop creating base classes and start using composition instead of inheritance as a way of sharing code between classes. 基本上,当您决定停止创建基类并开始使用合成而不是继承作为在类之间共享代码的方式时,我想征询您的意见。

Also, from a runtime performance standpoint, is there anything to sway me away from creating object hierarchies? 而且,从运行时性能的角度来看,有什么可以让我远离创建对象层次结构的吗?

I wrote up some thoughts awhile back on coming to iOS from other backgrounds , including Java. 我有段时间想起从其他背景 (包括Java) 进入iOS的想法。 Some things have changed due to ARC. 由于ARC,某些情况已更改。 In particular, memory management is no longer so front-and-center. 特别是,内存管理不再是中心问题。 That said, all the things you used to do to make memory management easy (use accessors, use accessors, use accessors) is still equally valid in ARC. 也就是说,您过去为简化内存管理所做的所有事情(使用访问器,使用访问器,使用访问器)在ARC中同样有效。

@Radu is completely correct that you should often keep your class hierarchies fairly simple and shallow (as you read). @Radu是完全正确的,您应该经常使类层次结构相当简单和浅(如您所读)。 Composition is often a much better approach in Cocoa than extensive subclassing (this is likely true in Java, too, but it's common practice in ObjC). 在Cocoa中,组合通常是比扩展子类更好的方法(在Java中也可能如此,但在ObjC中是常见的做法)。 ObjC also has no concept of an abstract method or class, which makes certain kinds of subclassing a little awkward. ObjC也没有抽象方法或类的概念,这使得某些类型的子类有点尴尬。 Rather than extracting shared logic into base classes (particularly abstract base classes), it is often better to extract them into a separate strategy object. 与其将共享逻辑提取到基类(尤其是抽象基类)中,不如将它们提取到单独的策略对象中通常更好。

Look at UITableView and its use of delegates and datasources. 查看UITableView及其对委托和数据源的使用。 Look at things like NSAttributedString which HAS-A NSString rather than IS-A. 看一下像NSAttributedString这样的东西,它是HAS-A NSString而不是IS-A。 That's common and often keeps things cleaner. 这很常见,通常会使事情更清洁。 As with all large object hierarchies, keep LSP in mind at all times. 与所有大对象层次结构一样,始终要记住LSP I see a lot of ObjC design go sideways when someone forgets that a square is not a rectangle . 当有人忘记正方形不是矩形时,我会看到很多ObjC设计都是横行的。 Again, this is true of all languages, but it's worth remembering as you design. 同样,所有语言都是如此,但是在设计时值得记住。

Immutable (value) objects are a real win whenever you can use them. 只要使用不可变(值)对象,它们都是真正的胜利。

The other piece you will quickly discover is that there are very few "safety decorations" like "final" or "protected" (there is a @protected , but it isn't actually that useful in practice and is seldom used). 您很快就会发现的另一件作品是,很少有诸如“最终”或“受保护”之类的“安全装饰”(有@protected ,但实际上在实践中并没有那么有用,并且很少使用)。 People from a Java and C++ background tend to fret about compiler enforcement of various access rules. 来自Java和C ++背景的人们倾向于对各种访问规则的编译器强制执行感到烦恼。 ObjC doesn't have compiler enforcement of most protections (you can always send any message you want to any object at runtime). ObjC没有大多数保护措施的编译器实施(您始终可以在运行时将所需的任何消息发送给任何对象)。 You just use consistent naming conventions and don't go poking around at private methods. 您只需要使用一致的命名约定,就可以随意使用私有方法。 Programmer discipline takes the place of compiler enforcement. 程序员纪律代替了编译器强制。 In practice, it works just fine that way in the vast majority of cases. 实际上,它在大多数情况下都可以正常工作。

That said, ObjC has a lot of warnings, and you absolutely must eliminate all warnings. 就是说,ObjC有很多警告,您绝对必须消除所有警告。 Most ObjC warnings are actually errors. 大多数ObjC警告实际上是错误。

I've strayed a little from the specific question of object hierarchies, but hopefully it's useful. 我从对象层次结构的特定问题中走了一些步,但希望它会有用。

One major problem with deep hierarchies in Objective-C is that Xcode doesn't help you at all understanding/managing them. Objective-C中的深层次结构的一个主要问题是Xcode根本无法帮助您理解/管理它们。 Another is simply that just about anything in Objective-C gets about twice as complex than the equivalent in Java, so you need to work harder to keep stuff simple. 另一个简单的原因是,Objective-C中的几乎所有东西都比Java中的东西复杂了两倍,因此您需要更加努力地使事情变得简单。

But I find composition in Objective-C to be awkward (though I can't say exactly why), so there is no "perfect" answer. 但是我发现Objective-C中的合成很尴尬(尽管我不能确切地说出原因),因此没有“完美”的答案。

I have observed that small subroutines are much rarer in Objective-C vs Java, and one is much more likely to see code duplicated between mostly-identical view controllers and the like. 我已经观察到,在Objective-C和Java中,小的子例程要少得多,而且人们更可能看到在大多数相同的视图控制器等之间重复的代码。 I think a big part of this is simply the development tools and the relative awkwardness with creating new classes. 我认为其中很大一部分只是开发工具和创建新类的相对尴尬。

PS: I had to rework an app that contained roughly 55K lines, close as we could count. PS:我不得不重做一个包含大约55K行的应用程序,这与我们可以估计的接近。 As you found, there was likely about 25% duplication, but there was also another 25% or so of totally dead code. 如您所见,可能有大约25%的重复,但是还有25%左右的完全无效代码。 (Thankfully, that app has been pretty much abandoned since.) (值得庆幸的是,此应用自此以来已被废弃。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM