使Objective-C类看起来很美

我想问你们所有的意见在目标C的代码气味,特别是cocoa触摸。 我正在制作一个相当复杂的游戏,并且即将开始伟大的12月重构。

我的很多课程,特别是模型,充满了处理内部商业逻辑的方法; 我将把这些隐藏在一个私人的类别中,在对抗大量头文件的战争中。 这些私有类别包含了大量的声明,这让我感到不安…就像Objective-C出来让我对所有这些方法感到内疚。

我重构得越多(一件好事!),就越需要保持所有这些重复(不太好)。 这只是感觉不对。

像Ruby这样的语言,社区非常注重非常简短,清晰,美丽的方法。 我的问题是,Objective C(特别是Cocoa Touch),你的方法有多长,你的控制器有多大,以及你们所有项目中你发现每种types的方法有多less? 在目标C中,有什么特别好的,美丽的由短方法构成的类的例子,还是不是语言文化的重要组成部分?

披露:我正在阅读“小小的Schemer”,这应该解释我的悲伤,重新:客观C.

是主观的。 对于我来说,如果一个Objective-C类是可读的(我知道它应该做什么)并且可维护(我可以看到哪些部分负责做什么),那么这个类很漂亮。 我也不喜欢被一个陌生的成语从阅读代码中抛出。 有点像当你正在读书,你读了一些东西,让你离开沉浸,并提醒你,你正在阅读。

你可能会得到很多不同的,相互排斥的build议,但这是我的想法。

  • 私人方法在私人类别中没有任何问题。 这就是它的目的。 如果您不喜欢堵塞文件的声明,请在IDE中使用代码折叠,或将扩展名作为不同文件中的类别。
  • 将相关的方法组合在一起,并用#pragma mark语句标记它们
  • 无论您使用哪种代码布局,一致性都很重要。 花几分钟时间写下你自己的指导方针(这里是我的 ),所以如果你忘记了你应该做的事情,你可以参考一下。
  • 控制器不一定是委托和数据源,你可以总是有其他的类。
  • 使用方法和属性的描述性名称。 是的,你可以logging它们,但是当Xcode应用代码完成时,你不能看到文档。 此外,代码注释如果在代码本身更改时没有更新,则会过时。
  • 不要尝试写出聪明的代码。 你可能会认为在一行上链接一系列的方法调用会更好,但编译器比你想象的更适合优化。 如果使用临时variables来提高可读性,那么使用临时variables来保存值(大多数情况下这些指针只是指针,所以相对较小)是可以的。 编写供人阅读的代码
  • DRY与其他语言一样适用于Objective-C。 不要担心重构代码到更多的方法。 只要有用,就有很多方法是没有问题的。

我甚至在实施课程或方法之前所做的第一件事就是问: “我怎样才能从外面使用这个?

我永远不会从头开始写我的课程和方法的内部。 通过一个优雅的公共API开始,内部的人往往会变得优雅,如果他们不这样做,那么这个丑陋至less被包含在一个单一的方法或类中,而不允许污秽其他的代码。

那里有很多devise模式,二十年的编码教会了我,唯一经得起时间考验的模式是: KISS 。 保持简单愚蠢。

一些一般的经验法则,适用于任何语言或环境:

  • 按照您的直觉感受您阅读或听到的任何build议!
  • 提前退出!
    • 如果需要的话,尽早validationinput并快速救助! 较less的清理工作。
  • 千万不要在你的代码中添加一些你不用的东西。
    • “反向”选项可能会让人觉得好像在路上。
    • 在这种情况下,把它添加到道路上! 不要浪费时间增加你不需要的复杂性。
  • 方法名称应该描述做了什么,而不是如何做。
    • 只要结果相同,应允许方法更改其实现而不更改其名称。
    • 如果你不明白一个方法从它的名字是什么,那么改名字!
    • 如果这个部分足够复杂,那么使用注释来描述你的实现。
  • 不要害怕单身!
    • 如果你的应用只有一个数据模型,那么它是一个单身!
    • 绕过一个单一的variables只是假装它是别的东西,而不是一个单身人士,并增加复杂性作为奖金。
  • 从一开始就计划失败。
    • 始终使用doFoo:error代替doFoo:从一开始。
    • 从一开始就用最终用户可读的本地化描述创build漂亮的NSError实例。
    • 将error handling/消息改装成现有的大型应用程序是一个主要的难题。
    • 如果你有用户和IO参与,总会有错误!
  • cocoa/ Objective-C是面向对象的,而不是**面向大多数stream行的孩子,在那里声称是面向对象。
    • 不要只用属性来引入哑值类,没有方法执行实际工作的类也可以是结构体。
    • 让你的物体变得聪明! 为什么添加一个全新的FooParser类,如果Foo上的fooFromString:方法是你所需要的?
  • 在cocoa中,你所能做的总是比更重要。
    • 如果目标/行动可以做,不要引入协议。
    • 不要validation实例是否符合协议,是一种类,取决于编译器。

我的2美分:

  1. 属性通常比旧式的getter + setter更好。 即使你使用@dynamic属性 – 用@property声明他们,这是更多的信息和更短。
  2. 我个人不会模拟类的“私人”方法 。 是的,我可以在.m(m)文件的某个地方写一个类别,但是由于Obj-C没有纯粹的方法来声明一个私有方法 – 为什么我应该发明一个呢? 无论如何,即使你真的需要这样的东西 – 用一个类别声明一个单独的“MyClassPrivate.h”,并将其包含在.m(m)文件中,以避免重复声明。
  3. 绑定 。 对于大多数Controller <> UI关系的绑定,使用变换器,格式化器,只是不要写方法手动读取/写入控制值。 它使代码看起来像MFC时代的东西。
  4. C ++中 ,用C ++编写的代码看起来好多了,也好看很多。 由于编译器能够理解C ++类,所以重构是一个好的方面,特别是在处理低级代码时。
  5. 我通常分裂大控制器。 超过500行的代码对于我来说是一个很好的重构候选。 例如,我有一个文件窗口控制器,因为它的一些版本的应用程序扩展与图像导入/导出选项。 控制器增长到1000行,其中1/2是“图像的东西”。 这是我制作ImageStuffController的一个“触发器”,在NIB中实例化它,并将所有与图像相关的代码放在那里。

以上所有使我更容易维护我的代码。 对于一个庞大的项目,在分割控制器和类以保持较小的文件数量的情况下,我通常会尝试将一些代码提取到一个框架中。 例如,如果应用程序的很大一部分正在与外部Web服务进行通信,通常可以直接从主应用程序中提取MyWebServices.framework。

Interesting Posts