当前位置: 首页 > 科技观察

Objective-C的优雅命名

时间:2023-03-12 06:53:27 科技观察

ComputerScience中只有两件难事:cacheinvalidation和namingthings。计算机科学中只有两件难事:缓存失效和命名。—PhilKarlton计算机语言是人与计算机之间交流的媒介。好的代码应该像人与计算机对话一样自然优雅。命名看似是一件很简单的事情,但往往越简单的事情越难做好,否则高手们也不会把命名当成计算机世界的难题。如何优雅地“说”出Objective-C这门计算机语言,非常考验一个工程师对它的理解深度。Apple的SDK中有大量的API,我们可以从这些API中体会到一些命名艺术。减少缩写命名缩写仅用于常见的技术术语,如URL,不允许自创命名缩写,如Ctr和Msg。命名要长于难以理解。是不是看别人的代码各种缩写不知道为什么?名称越短越好,但不要过度使用缩写以致失去可读性。在程序动作发生之前使用Will,在它发生之后使用Did,在询问它是否发生时使用Should。每个处理都有一定的流程,这个处理往往会产生一些通知和回调。一个好的命名必须明确当前流程中的步骤。在命名这些通知和回调时,最好提供发生前后两个版本。如果要在事件发生前回调确认,请将回调命名为Should并返回一个BOOL值。命名空间的各个全局范围内的函数、常量、类、枚举、结构等都必须加上前缀。Objective-C没有像C++那样的命名空间的概念,也没有Java包名的概念。随着项目代码的增多,难免会出现名称冲突,所以全局作用域的名称必须是唯一的。比较经典的做法是加一个命名前缀。大多数人认为命名前缀只是类前面的几个大写字母,但它不止于此。?类型(类、枚举、结构)应以相关模块前缀UIViewNSStringCGRect作为前缀?常量应以相关类型名称为前缀。UIApplicationDidFinishLaunchingNotificationCGRectZero?函数名称应以相关类型名称为前缀。CGRectMakeCGPointMake?枚举类型的名称应以相关类名为前缀,枚举值的名称应以枚举类型为前缀。typedefNS_ENUM(NSInteger,UIViewAnimationTransition){UIViewAnimationTransitionNone,UIViewAnimationTransitionFlipFromLeft,UIViewAnimationTransitionFlipFromRight,UIViewAnimationTransitionCurlUp,UIViewAnimationTransitionCurlDown,};做到以上几点,几乎可以让名字不冲突。参数提示方法命名时,每个参数前都要加上参数的名称提示。-(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil-(void)performSegueWithIdentifier:(NSString*)identifiersender:(id)senderobjectnaming修改对象命名时,使用修改+类型的方式,不用首先指定它的类型。很多人喜欢把对象的类型放在对象名称的前面,以标识一个对象是什么类型。这不符合Objective-C语言的特点,容易造成歧义。比如一个UILabel对象:titleLabel//表示title的label,是UIlabel对象labelTitle//label的标题吗?似乎是一个NSString?confirmButton//确认按钮buttonConfirm//不自然的命名,看起来像是一个按钮的点击动作。方法命名符合语法大多数方法可以分为以下两类,而这两类经常被乱用。它们是:?Whattodo?Whattodo“Whattodo”表示获取对象,方法必须以名词开头;“Whattodo”是指进行某种操作,方法必须以动词开头。看下面的命名方式:-(XXItem*)itemNamed:(NSString*)name//好。意思很明确-(XXItem*)findItemWithName:(NSString*)name//与其说是返回一个对象,不如说是一个操作。名称findItemWithName表示不返回对象的操作。比如可以用来设置一个类的内部成员,如:-(void)findItemWithName:(NSString*)name{...self.foundItem=xxx;...}get"Whatdoyouwant"常被胡乱命名为以get开头的方法。首先,get是一个动词,所以还是“whattodo”或者“whattodo”。那么get方法不是用来返回对象的,而是可以用来返回参数的。-(XXItem*)getItemAtIndex:(NSUInteger)index//不好!!命名不规则-(XXItem*)itemAtIndex:(NSUInteger)index//好,命名清晰-(void)getItem:(XXItem**)outItematIndex:(NSUInteger)index//与规范相比,但第二个更好。知道回调的时候,被调用者需要知道调用者可以在回调方法的第一个参数中添加调用者:-(BOOL)application:(UIApplication*)applicationwillFinishLaunchingWithOptions:(NSDictionary*)launchOptions-(void)buttonTapped:(UIButton*)senderconstants或macroglobalconstants不能使用宏来定义。我们经常看到通过宏定义的通知、关键字等。其实这样做是很危险的,因为宏很有可能被重新定义,引用不同的文件可能会导致不同的宏,所以尽量使用const来定义常量。一些思维命名的好坏,在开发的时候往往不太注意,毕竟不好的命名不会影响程序逻辑。但是,在大型项目中命名不当带来的隐性维护成本是相当高的。这些在项目初期可能难以察觉,后期就会陷入后续维护的困境。我们往往很重视项目逻辑的复杂性,却做不到“简单”的命名。其实简单的事情你都做不好,再复杂的事情也做不好。